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”:

Fields have been reordered

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:

Form has fieldsets now

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:

Polls change list page

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:

Polls change list page, updated

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:

Polls change list page, updated

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.

Back to Top