티스토리 수익 글 보기
Pisanie pierwszej aplikacji Django, część 7.¶
This tutorial begins where Tutorial 6 left off. We’re continuing the web-poll application and will focus on customizing Django’s automatically-generated admin site that we first explored in Tutorial 2.
Gdzie szukać pomocy:
Jeśli masz trudności w przejściu tego tutorialu, przejdź do sekcji Uzyskiwanie pomocy często zadawanych pytań.
Dostosuj formularz panelu administracyjnego¶
Rejestrując model Question przez admin.site.register(Question), umożliwiłeś Django skonstruowanie domyślnej reprezentacji formularza. Często będziesz chciał zmienić to jak formularz panelu administracyjnego wygląda i działa. Będziesz to robił mówiąc Django, jakie wybierasz opcje, rejestrując obiekt.
Zobaczmy jak to działa zmieniając kolejność pól w formularzu edycji. Zamień linię admin.site.register(Question) na:
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)
Będziesz realizował ten wzorzec stworzenie klasy model admin, następnie przekazanie jej jako drugiego argumentu do admin.site.register() – w dowolnym momencie, kiedy potrzebujesz zmienić opcje admina dla modelu.
Konkretnie ta zmiana powyżej powoduje, że „Publication date” jest przed polem „Question”:
Nie robi to wrażenia z tylko dwoma polami, ale dla formularzy admina z tuzinami pól, wybranie intuicyjnego porządku jest ważnym szczegółem użyteczności.
A mówiąc o formularzach z tuzinami pól, możesz chcieć podzielić formularz na fieldsety:
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)
Pierwszym elementem każdej krotki w fieldsets jest tytuł fieldsetu. Tak wygląda teraz nasz formularz:
Dodawanie powiązanych obiektów¶
Ok, mamy stronę admina dla pytań, ale Question ma wiele wyborów i strona admina tych wyborów nie wyświetla.
Jeszcze nie wyświetla.
Są dwa sposoby rozwiązania tego problemu. Pierwszy to zarejestrować Choice z adminem tak jak zrobiliśmy przed chwilą z Question:
polls/admin.py¶from django.contrib import admin
from .models import Choice, Question
# ...
admin.site.register(Choice)
Teraz „Choices” są dostępną opcją w adminie Django. Formularz „Add choice” wygląda tak:
W tym formularzu pole „Question” jest polem wyboru zawierającym wszystkie pytania z bazy danych. Django wie, że ForeignKey powinno być reprezentowane w adminie jako <select>. W naszym przypadku istnieje tylko jedno pytanie w tym momencie.
Also note the „Add another question” link next to „Question.” Every object with
a ForeignKey relationship to another gets this for free. When you click
„Add another question”, you’ll get a popup window with the „Add question” form.
If you add a question in that window and click „Save”, Django will save the
question to the database and dynamically add it as the selected choice on the
„Add choice” form you’re looking at.
Ale tak naprawdę to niewydajny sposób na dodawanie obiektów Choice do systemu. Byłoby lepiej, jeśli mógłbyś dodać zestaw wyborów bezpośrednio, gdy tworzysz obiekt Question. Zróbmy tak.
Usuń wywołanie register() dla modelu Choice. Następnie zmodyfikuj kod rejestracji Question, by wyglądał tak:
polls/admin.py¶from django.contrib import admin
from .models import Choice, Question
class ChoiceInline(admin.StackedInline):
model = Choice
extra = 3
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
inlines = [ChoiceInline]
admin.site.register(Question, QuestionAdmin)
Mówi to Django: „Obiekty Choice są edytowane na stronie admina Question. Domyślnie wyświetl pól wystarczająco na 3 wybory”.
Załaduj stronę „Add question”, by zobaczyć jak to wygląda:
Działa to tak: Są trzy miejsca na powiązane wybory – tak jak jest wskazane przez extra – i za każdym razem, kiedy powrócisz na stronę „Change dla już stworzonego obiektu, dostaniesz kolejne trzy dodatkowe miejsca.
Na końcu trzech bieżących miejsc znajdziesz link „Add another Choice”. Jeśli w niego klikniesz, zostanie dodane nowe miejsce. Jeśli chcesz usunąć dodane miejsce, możesz kliknąć X w prawym górnym rogu dodanego miejsca. Ta grafika pokazuje dodane miejsce:
Jest jednak jeden mały problem. Wyświetlenie wszystkich pól do wypełnienia powiązanych obiektów Choice zajmuje ogromną ilość miejsca na ekranie. Z tego powodu Django oferuje sposób tabelaryczny na wyświetlenie „inline” powiązanych obiektów. Aby go użyć, zmień deklarację ChoiceInline, aby brzmiała:
polls/admin.py¶class ChoiceInline(admin.TabularInline):
#...
Z TabularInline (zamiast StackedInline), powiązane obiekty są wyświetlane w bardziej zwartym, opartym na tabelce formacie:
Note that there is an extra „Delete?” column that allows removing rows added using the „Add another Choice” button and rows that have already been saved.
Dostosuj widok listy panelu administracyjnego¶
Teraz, kiedy strona admina dla pytania wygląda dobrze, poprawmy nieco stronę „change list” – tę, która wyświetla wszystkie pytania w systemie.
Tak ona wygląda w tym momencie:
Domyślnie Django wyświetla str() każdego obiektu. Ale czasem bardziej pomocne byłoby wyświetlanie poszczególnych pól. Aby to zrobić, użyj list_display
polls/admin.py¶class QuestionAdmin(admin.ModelAdmin):
# ...
list_display = ('question_text', 'pub_date')
Na wszelki wypadek dodajmy też metodę was_published_recently() z Tutoriala 2:
polls/admin.py¶class QuestionAdmin(admin.ModelAdmin):
# ...
list_display = ('question_text', 'pub_date', 'was_published_recently')
Teraz strona „change list” pytań wygląda w ten sposób:
Możesz klikać w nagłówki kolumn, aby sortować po tych wartościach – z wyjątkiem przypadku nagłówka was_published_recently, ponieważ sortowanie po wyniku arbitralnej metody nie jest wspierane. Zwróć też uwagę, że nagłówek kolumny dla was_published_recently jest domyślnie nazwą metody (z podkreślnikami zamienionymi na spacje) i każda linia zawiera reprezentację w ciągu znaków wyniku.
Możesz to poprawić używając dekoratora display() na tej metodzie (w polls/models.py), w następujący sposób:
polls/models.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
Po więcej informacji na temat właściwości konfigurowalnych przez ten dekorator, zobacz list_display.
Zmień znów swój plik polls/admin.py i dodaj ulepszenie do strony „change list” Questions: filtry, z użyciem list_filter. Dodaj następującą linię do QuestionAdmin:
list_filter = ['pub_date']
Doda to sidebar „Filter”, który pozwala ludziom filtrować listę obiektów używając pola pub_date:
Typ wyświetlanego filtru zależy od typu pola, po którym filtrujesz. Ponieważ pub_date to DateTimeField, Django wie, aby dać odpowiednie opcje w filtrze: „Any date”, „Today”, „Past 7 days”, „This month”, „This year”.
Dobrze się to zarysowuje. Dodajmy trochę możliwości wyszukiwania:
search_fields = ['question_text']
To dodaje pole wyszukiwania na górze „change listy”. Kiedy ktoś wprowadzi wyrażenie wyszukiwania, Django przeszuka pole question_text. Możesz użyć tyle pól, na ile masz ochotę – choć z powodu, że pod maską użyje to zapytania LIKE, ograniczenie liczby pól wyszukiwania do rozsądnej liczby ułatwi twojej bazie danych wykonać wyszukiwanie.
Teraz jest dobry moment, by zwrócić uwagę, że „change lista” daje ci wolną paginację. Domyślnie wyświetla ona 100 elementów na stronę. Zmień paginację listy, pola wyszukiwania, filtry, hierarchie dat i:attr:kolejność kolumn nagłówków <django.contrib.admin.ModelAdmin.list_display> tak, aby wspólnie współgrały tak, jak uważasz, że powinny.
Dostosuj wygląd i pracę z panelem administracyjnym¶
Oczywiście, wyświetlanie napisu „Django administration” na górze każdej strony panelu administracyjnego jest bez sensu. To tylko tekst zastępczy.
Możesz go zmienić przy użyciu systemu szablonów Django. Panel administracyjny Django jest napędzany przez samo Django i jego interfejsy używają własnego systemu szablonów Django.
Dostosowywanie szablonów twojego projektu¶
Stwórz katalog templates w katalogu twojego projektu (tym, który zawiera manage.py). Szablony mogą być składowane w dowolnym miejscu twojego systemu plików, do którego może mieć dostęp Django. (Django jest uruchomione na tym samym użytkowniku co serwer.) Jednakże trzymanie szablonów wewnątrz projektu jest dobrą konwencją.
Otwórz swój plik ustawiń (mysite/settings.py, pamiętaj) i dodaj opcję DIRS w ustawieniu TEMPLATES:
mysite/settings.py¶TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
DIRS jest listą katalogów systemu plików, które należy sprawdzić ładując szablony Django; jest ścieżką wyszukiwania.
Organizacja szablonów
Tak samo jak pliki statyczne, moglibyśmy mieć wszystkie nasze szablony razem, w jednym dużym katalogu na szablony i mogłoby to całkowicie dobrze działać. Jednakże szablony, które należą do poszczególnej aplikacji powinny być umieszczane raczej w katalogu szablonów tej aplikacji (np. polls/templates) niż w katalogu szablonów projektu (templates). Omówimy bardziej szczegółowo w “samouczku aplikacji wielokrotnego użytku </intro/reusable-apps>` dlaczego to robimy.
Teraz stwórz katalog o nazwie admin wewnątrz templates i skopiuj szablon admin/base_site.html z katalogu domyślnych szablonów panelu administracyjnego z kodu źródłowego Django (django/contrib/admin/templates) do tego katalogu.
Gdzie są pliki źródłowe Django?
Jeśli masz trudność w odnalezieniu miejsca, gdzie są zlokalizowane pliki źródłowe Django w twoim systemie, uruchom następujące polecenie:
$ python -c "import django; print(django.__path__)"
...\> py -c "import django; print(django.__path__)"
Następnie zmień plik i zamień {{ site_header|default:_('Django administration') }} (wliczając nawiasy klamrowe) na nazwę swojej strony, która będzie pasować. Powinieneś skończyć z sekcją kodu typu:
{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>
{% endblock %}
Używamy tego podejścia, aby nauczyć cię jak nadpisywać szablony. W prawdziwym projekcie, prawdopodobnie użyłbyś atrybutu django.contrib.admin.AdminSite.site_header, aby w prostszy sposób zrobić tę konkretną zmianę.
Ten plik szablonu zawiera pełno tekstów typu {% block branding %} i {{ title }}. Tagi {% i {{ są częścią języka szablonów Django. Kiedy Django renderuje admin/base_site.html, ten język szablonów jest ewaluowany i produkuje ostateczną stronę HTML, tak jak widzieliśmy w Tutorialu 3.
Zwróć uwagę, że każdy domyślny szablon panelu administracyjnego Django może być nadpisany. Aby nadpisać szablon, zrób tę samą czynność, którą zrobiłeś z base_site.html – skopiuj je z domyślnego katalogu do swojego własnego katalogu i zrób zmiany.
Zmiana szablonów twojej aplikacji¶
Bystrzy czytelnicy zapytają: Ale skoro DIRS było domyślnie puste, jak Django odnajdywało domyślne szablony admina? Odpowiedzią jest, tak długo jak APP_DIRS jest ustawione na True, Django automatycznie szuka podkatalogu templates/ w każdym pakiecie aplikacji, aby użyć go jako fallback (nie zapomnij, że django.contrib.admin jest aplikacją).
Nasza aplikacja ankietowa nie jest bardzo złożona i nie potrzebuje customowych szablonów admina. Lecz gdyby urosła do bardziej skomplikowanej i wymagała modyfikacji standardowych szablonów admina do jakiś swoich funkcjonalności, byłoby bardziej rozsądne modyfikować szablony aplikacji niż te w projekcie. W ten sposób mógłbyś zawrzeć aplikację ankietową w dowolnym nowym projekcie i miałbyś pewność, że odnajdzie customowe szablony, których potrzebuje.
W dokumentacji ładowania szablonów więcej informacji o tym, jak Django odnajduje swoje szablony.
Dostosuj stronę indeksu panelu administracyjnego¶
W podobnym tonie możesz chcieć zmienić wygląd i odbiór strony indeksu panelu admina Django.
Domyślnie wyświetla ona wszystkie aplikacje w INSTALLED_APPS, które zostały zarejestrowane z aplikacją admin, w kolejności alfabetycznej. Możesz chcieć dokonać istotnych zmian w wyglądzie. W końcu, strona główna jest prawdopodobnie najważniejszą stroną admina i powinna być łatwa w użyciu.
Szablon do dostosowania to admin/index.html. (Zrób to samo co z admin/base_site.html w poprzedniej sekcji – skopiuj go z domyślnego katalogu do swojego katalogu zmienionych szablonów). Zedytuj plik. Zobaczysz, że używa on zmiennej szablonu o nazwie app_list. Ta zmienna zawiera wyszystkie zainstalowane aplikacje Django. Zamiast jej używać możesz zahardcode’ować linki do adminowych stron obiektów w dowolny sposób, który uznasz za najlepszy.
Co dalej?¶
Tutorial dla początkujących kończy się tutaj. W międzyczasie możesz chcieć sprawdzić niektóre z kierunków wskazanych w gdzie iść dalej.
Jeśli jesteś zaznajomiony z pakietowaniem w Pythonie i zainteresowany jak uczynić ankiety „aplikacją reusable”, sprawdź Zaawansowany tutorial: Jak pisać aplikacje do ponownego wykorzystania.
Dodatkowe informacje
Support Django!
Zawartość
- Pisanie pierwszej aplikacji Django, część 7.
Uzyskiwanie pomocy
- FAQ
- Wypróbuj FAQ – ma odpowiedzi na wiele powszechnych pytań.
- Indeks, Indeks modułów, or Spis treści
- Przydatne, gdy szukasz konkretnej informacji
- Django Discord Server
- Join the Django Discord Community.
- Official Django Forum
- Join the community on the Django Forum.
- Ticket tracker
- Zgłoś błędy w Django lub w dokumentacji w naszym systemie zgłoszeń.
Pobierz:
Offline (Django 4.1):
HTML |
PDF |
ePub
Dostarczone przez Read the Docs.