Skriva din första Django-app, del 7¶
Denna handledning börjar där Tutorial 6 slutade. Vi fortsätter med web-poll applikationen och kommer att fokusera på att anpassa Djangos automatiskt genererade admin-webbplats som vi först utforskade i Tutorial 2.
Var du kan få hjälp:
Om du har problem med att gå igenom den här handledningen kan du gå till avsnittet Att få hjälp i FAQ.
Anpassa administratörsformuläret¶
Genom att registrera modellen Question
med admin.site.register(Question)
kunde Django konstruera en standardformulärrepresentation. Ofta vill du anpassa hur adminformuläret ser ut och fungerar. Du gör detta genom att berätta för Django de alternativ du vill ha när du registrerar objektet.
Låt oss se hur detta fungerar genom att omorganisera fälten i redigeringsformuläret. Ersätt raden admin.site.register(Question)
med:
polls/admin.py
¶from django.contrib import admin
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
fields = ["pub_date", "question_text"]
admin.site.register(Question, QuestionAdmin)
Du följer det här mönstret - skapa en modelladministratörsklass och skicka den sedan som det andra argumentet till admin.site.register()
- varje gång du behöver ändra administratörsalternativen för en modell.
Den här ändringen gör att ”Publiceringsdatum” kommer före fältet ”Fråga”:

Detta är inte imponerande med bara två fält, men för adminformulär med dussintals fält är det en viktig användbarhetsdetalj att välja en intuitiv ordning.
Och på tal om formulär med dussintals fält kanske du vill dela upp formuläret i fältuppsättningar:
polls/admin.py
¶from django.contrib import admin
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {"fields": ["question_text"]}),
("Date information", {"fields": ["pub_date"]}),
]
admin.site.register(Question, QuestionAdmin)
Det första elementet i varje tupel i fieldsets
är titeln på fältuppsättningen. Så här ser vårt formulär ut nu:

Anpassa ändringslistan för administratörer¶
Nu när administratörssidan för frågor ser bra ut ska vi göra några justeringar på sidan ”ändringslista” - den sida som visar alla frågor i systemet.
Så här ser det ut i nuläget:

Som standard visar Django str()
för varje objekt. Men ibland skulle det vara till större hjälp om vi kunde visa enskilda fält. För att göra det använder du adminalternativet list_display
, som är en lista med fältnamn som ska visas, som kolumner, på sidan med ändringslistan för objektet:
polls/admin.py
¶class QuestionAdmin(admin.ModelAdmin):
# ...
list_display = ["question_text", "pub_date"]
För säkerhets skull inkluderar vi även metoden was_published_recently()
från Tutorial 2:
polls/admin.py
¶class QuestionAdmin(admin.ModelAdmin):
# ...
list_display = ["question_text", "pub_date", "was_published_recently"]
Nu ser sidan med frågeändringslistan ut så här:

Du kan klicka på kolumnrubrikerna för att sortera efter dessa värden - utom när det gäller rubriken was_published_recently
, eftersom det inte finns stöd för sortering efter resultatet av en godtycklig metod. Observera också att kolumnrubriken för was_published_recently
som standard är namnet på metoden (med understreck ersatta med mellanslag), och att varje rad innehåller strängrepresentationen av utdata.
Du kan förbättra det genom att använda display()
-dekoratorn på den metoden (utöka polls/models.py
-filen som skapades i Tutorial 2), enligt följande:
polls/modeller.py
¶from django.contrib import admin
class Question(models.Model):
# ...
@admin.display(
boolean=True,
ordering="pub_date",
description="Published recently?",
)
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
För mer information om de egenskaper som kan konfigureras via dekoratorn, se list_display
.
Redigera filen polls/admin.py
igen och lägg till en förbättring av sidan med ändringslistan Question
: filter med hjälp av list_filter
. Lägg till följande rad i QuestionAdmin
:
list_filter = ["pub_date"]
Det lägger till en ”Filter”-sidofält som låter människor filtrera ändringslistan efter fältet pub_date
:

Vilken typ av filter som visas beror på vilken typ av fält du filtrerar på. Eftersom pub_date
är en DateTimeField
, vet Django att ge lämpliga filteralternativ: ”Vilket datum som helst”, ”Idag”, ”De senaste 7 dagarna”, ”Den här månaden”, ”Det här året”.
Det här ser bra ut. Låt oss lägga till lite sökfunktionalitet:
search_fields = ["question_text"]
Det lägger till en sökruta längst upp i ändringslistan. När någon skriver in söktermer kommer Django att söka i fältet question_text
. Du kan använda så många fält som du vill - men eftersom det använder en LIKE
-fråga bakom kulisserna, kommer det att göra det lättare för din databas att göra sökningen genom att begränsa antalet sökfält till ett rimligt antal.
Nu är det också en bra tid att notera att ändringslistor ger dig gratis paginering. Standard är att visa 100 objekt per sida. Change list pagination
, search boxes
, filters
, date-hierarchies
, och column-header-ordering
fungerar alla tillsammans som du tror att de ska.
Anpassa administratörens utseende och känsla¶
Det är uppenbart att det är löjligt att ha ”Django administration” högst upp på varje adminsida. Det är bara platshållartext.
Du kan dock ändra det med hjälp av Djangos mallsystem. Django-admin drivs av Django själv och dess gränssnitt använder Djangos eget mallsystem.
Anpassa mallarna för ditt projekt¶
Skapa en templates
katalog i din djangotutorial
katalog. Mallar kan finnas var som helst på ditt filsystem som Django kan komma åt. (Django körs som vilken användare som helst som din server kör.) Att hålla dina mallar inom projektet är dock en bra konvention att följa.
Öppna din inställningsfil (mysite/settings.py
, kom ihåg) och lägg till ett DIRS
alternativ i TEMPLATES
inställningen:
mysite/settings.py
¶TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / "templates"],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
DIRS
är en lista över filsystemkataloger som ska kontrolleras när Django-mallar laddas; det är en sökväg.
Organisera mallar
Precis som med de statiska filerna skulle vi kunna ha alla våra mallar samlade i en enda stor mallkatalog, och det skulle fungera alldeles utmärkt. Mallar som tillhör en viss applikation bör dock placeras i den applikationens mallkatalog (t.ex. polls/templates
) snarare än i projektets (templates
). Vi kommer att diskutera mer i detalj i :doc:``återanvändbara apps handledning </intro/reusable-apps>` varför vi gör detta.
Skapa nu en katalog som heter admin
inuti templates
, och kopiera mallen admin/base_site.html
från standardkatalogen för Djangos adminmallar i källkoden för Django själv (django/contrib/admin/templates) till den katalogen.
Var finns Djangos källfiler?
Om du har svårt att hitta var Djangos källfiler finns på ditt system kör du följande kommando:
$ python -c "import django; print(django.__path__)"
...\> py -c "import django; print(django.__path__)"
Redigera sedan filen och ersätt {{ site_header|default:_('Django administration') }}
(inklusive hakparenteserna) med namnet på din egen webbplats som du tycker passar. Du bör sluta med ett avsnitt av kod som:
{% block branding %}
<div id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></div>
{% if user.is_anonymous %}
{% include "admin/color_theme_toggle.html" %}
{% endif %}
{% endblock %}
Vi använder detta tillvägagångssätt för att lära dig hur du kan åsidosätta mallar. I ett verkligt projekt skulle du förmodligen använda attributet django.contrib.admin.AdminSite.site_header
för att lättare göra just den här anpassningen.
Den här mallfilen innehåller mycket text som {% block branding %}
och {{ title }}
. Taggarna {%
och {{
är en del av Djangos mallspråk. När Django renderar admin/base_site.html
, kommer detta mallspråk att utvärderas för att producera den slutliga HTML-sidan, precis som vi såg i :doc:``Tutorial 3 </intro/tutorial03>`.
Observera att alla Djangos standardmallar för administratörer kan åsidosättas. För att åsidosätta en mall gör du samma sak som du gjorde med base_site.html
- kopiera den från standardkatalogen till din anpassade katalog och gör ändringar.
Anpassa mallarna för din applikation¶
Smarta läsare kommer att fråga: Men om DIRS
var tom som standard, hur hittade Django standardmallarna för admin? Svaret är att, eftersom APP_DIRS
är inställd på True
, letar Django automatiskt efter en templates/
underkatalog inom varje applikationspaket, för användning som en fallback (glöm inte att django.contrib.admin
är en applikation).
Vår poll-applikation är inte särskilt komplex och behöver inte anpassade admin-mallar. Men om det blir mer sofistikerat och kräver modifiering av Djangos standardadministratörsmallar för vissa av dess funktioner, skulle det vara mer förnuftigt att modifiera applikationens mallar, snarare än de i projektet. På så sätt kan du inkludera pollsapplikationen i alla nya projekt och vara säker på att den hittar de anpassade mallar den behöver.
Se dokumentation för laddning av mallar för mer information om hur Django hittar sina mallar.
Anpassa indexsidan för administratörer¶
På ett liknande sätt kanske du vill anpassa utseendet på Django-administratörens indexsida.
Som standard visas alla appar i INSTALLED_APPS
som har registrerats i adminprogrammet i alfabetisk ordning. Du kanske vill göra betydande ändringar i layouten. När allt kommer omkring är indexet förmodligen den viktigaste sidan i admin, och den bör vara lätt att använda.
Den mall som ska anpassas är admin/index.html
. (Gör samma sak som med admin/base_site.html
i föregående avsnitt - kopiera den från standardkatalogen till din anpassade mallkatalog). Redigera filen och du kommer att se att den använder en mallvariabel som heter app_list
. Den variabeln innehåller alla installerade Django-appar. Istället för att använda den kan du hårdkoda länkar till objektspecifika adminsidor på det sätt som du tycker är bäst.
När du känner dig bekväm med administratören kan du läsa del 8 av denna handledning för att lära dig hur du använder tredjepartspaket.