Pisanie pierwszej aplikacji Django, część 2.¶
Ten tutorial zaczyna się, gdzie skończył się Tutorial 1. Będziemy uruchamiać bazę danych, stworzymy twój pierwszy model i przejdziemy krótki wstęp do automatycznie generowanego panelu administracyjnego Django.
Konfiguracja bazy danych¶
Otwórz teraz mysite/settings.py
. To normalny moduł Pythona ze zmiennymi poziomu modułu reprezentującymi ustawienia Django.
Domyślnie konfiguracja używa SQLite’a. Jeśli jesteś nowy w bazach danych lub jesteś tylko zainteresowany wypróbowaniem Django, to najprostszy wybór. SQLite jest zawarty w Pythonie, więc nie będziesz musiał nic instalować, aby mieć bazę danych. Uruchamiając swój pierwszy prawdziwy projekt, będziesz chciał użyć bardziej skalowalnej bazy danych jak PostgreSQL, aby uniknąć bólu głowy związanego ze zmianami bazy danych po drodze.
Jeśli chcesz używać innej bazy danych, zainstaluj odpowiednie wiązania dla niej i zmień następujące klucze elemencie 'default'
ustawienia DATABASES
, aby zgadzały się z ustawieniami połączenia do twojej bazy danych:
SILNIK
–'django.db.backends.sqlite3'
,'django.db.backends.postgresql'
,'django.db.backends.mysql'
lub'django.db.backends.oracle'
. Dostępne są także inne back-endy.NAME
– nazwa twojej bazy danych. Jeśli używasz SQLite’a, baza danych będzie plikiem na twoim komputerze; w tym przypadkuNAME
powinno być pełną bezwzględną ścieżką, zawierającą nazwę, tego pliku. Domyślna wartość,os.path.join(BASE_DIR, 'db.sqlite3')
, przechowa plik w katalogu twojego projektu.
Jeśli nie używasz SQLite’a jako swojej bazy danych, musisz dodać dodatkowe ustawienia, takie jak :settings:`USER`, PASSWORD
i HOST
. Po więcej szczegółów, zobacz dokumentację DATABASES
.
Dla baz danych innych niż SQLite
Jeśli używasz bazy danych innej niż SQLite, upewnij się, że do tego miejsca stworzyłeś bazę danych. Zrób to używając „CREATE DATABASE nazwa_bazy_danych;
” w interaktywnym prompcie twojej bazy danych.
Również upewnij się, że użytkownik bazy danych podany w mysite/settings.py
ma uprawnienia „create database”. To pozwala na automatyczne tworzenie testowej bazy danych, której będziemy potrzebować w późniejszym tutorialu.
Jeśli używasz SQLite’a, nie potrzebujesz nic tworzyć – plik bazy danych zostawnie stworzony automatycznie, kiedy będzie potrzebny.
W trakcie edycji mysite/settings.py
, ustaw TIME_ZONE
na swoją strefę czasową.
Zwróć również uwagę na ustawienie INSTALLED_APPS
na początku pliku. Trzyma ono nazwy wszystkich aplikacji Django, które są aktywowane w tej instancji Django. Aplikacje mogę być używane w wielu projektach i możesz je pakować i udostępniać innym do użytku w ich projektach.
Domyślnie INSTALLED_APPS
zawiera następujące aplikacje, które są w pakiecie z Django:
django.contrib.admin
– Panel administracyjny. Niedługo go użyjesz.django.contrib.auth
– System uwierzyteniania.django.contrib.contenttypes
– Framework dla typów treści.django.contrib.sessions
– Framework dla sesji.django.contrib.messages
– Framework powiadomień.django.contrib.staticfiles
– Framework do zarządzania plikami statycznymi.
Aplikacje te są włączone domyślnie jako udogodnienie dla powszechnych spraw.
Niektóre z tych aplikacji używają przynajmniej jednej tabeli w bazie danych, więc musimy stworzyć tabele w bazie danych zanim będziemy mogli je użyć. Aby to zrobić, uruchom następującą komendę:
$ python manage.py migrate
Komenda migrate
spogląda w ustawienie INSTALLED_APPS
i tworzy potrzebne tabele bazy danych w nawiązaniu do ustawień bazy danych w twoim pliku mysite/settings.py
i do migracji bazy danych zawartych w aplikacji (powiemy o tym później). Zobaczysz wiadomość o każdej migracji, która zostanie zastosowana. Jeśli jesteś zainsteresowany, uruchom klienta linii poleceń twojej bazy danych i wpisz \dt
(PostgreSQL), SHOW TABLES;
(MySQL), .schema
(SQLite) lub SELECT TABLE_NAME FROM USER_TABLES;
(Oracle), aby wyświetlić tabele, które stworzyło Django.
Dla minimalistów
Tak jak powiedzieliśmy wyżej, domyślne aplikacje są włączone dla powszechnych przypadków użycia, ale nie każdy je potrzebuje. Jeśli nie potrzebujesz żadnej z nich, nie krępuj się zakomentować lub usunąć odpowiednią linię (odpowiednie linie) z INSTALLED_APPS
przed uruchomieniem migrate
. Komenda migrate
uruchomi migracje tylko dla aplikacji w INSTALLED_APPS
.
Tworzenie modeli¶
Teraz zdefiniujemy twoje modele – w istocie layout twojej bazy danych z dodatkowymi meta-danymi.
Filozofia
Model jest pojedynczym, pełnym źródłem informacji o twoich danych. Zawiera zasadnicze pola i zachowania danych, które przechowujesz. Django stosuje się do zasady DRY. Celem jest zdefiniowanie modelu danych w jednym miejscu i automatyczne czerpanie z niego przez inne elementy.
Wliczają się w to migracje – inaczej niż na przykład w Ruby On Rails, migracje całkowicie pochodzą z pliku modeli, i są co do istoty tylko historią, przez którą Django może przewijać, aby aktualizować schemat bazy danych, by był zgodny z bieżącymi modelami.
W naszej prostej aplikacji ankietowej, stworzymy dwa modele: Question
and Choice
. Question
ma pytanie i datę publikacji. Choice
ma dwa pola: treść wyboru i podsumowanie głosów. Każdy Choice
jest związane z Question
.
Te koncepty są reprezentowane przez proste klasy Pythona. Zmień plik polls/models.py
, aby wyglądał tak:
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
Kod jest prostolinijny. Każdy model jest reprezentowany przez klasę, która dziedziczy po django.db.models.Model
. Każdy model ma kilka zmiennych klasowych, z których każda reprezentuje pole bazy danych w modelu.
Każde pole jest reprezentowane przez instancję klasy Field
– na przykład CharField
dla pól znakowych i DateTimeField
dla dat i czasu. Mówi to Django, jakie dane przechowuje każde pole.
Nazwa każdej instancji Field
(np. question_text
lub pub_date
) jest nazwą pola, w formacie przyjaznym maszynom. Użyjesz tej wartości w kodzie Pythona i twoja baza danych użyje jej jako nazwy kolumny.
Można użyć opcjonalnego pierwszego argumentu pozycyjnego w Field
, aby wyznaczyć nazwę w postaci czytelnej dla człowieka. Jest ona używana w kilku introspekcyjnych częściach Django i może służyć jako dokumentacja. Jeśli nie podamy tego argumentu, Django będzie używać nazwy maszynowej. W tym przykładzie mamy zdefiniowaną nazwę w postaci czytelnej dla człowieka tylko dla Question.pub_date
. Dla wszystkich innych pól w tym modelu, nazwy maszynowe będą wystarczające jako nazwy pól w formie czytelnej dla człowieka.
Niektóre klasy Field
mają wymagane argumenty. Na przykład CharField
wymaga podania atrybutu max_length
. Jest on używany nie tylko w schemacie bazy danych, ale również w walidacji, jak wkrótce zobaczymy.
Field
może mieć też kilka opcjonalnych argumentów; w tym przypadku ustawiliśmy wartość atrybutu default
pola votes
na 0.
I wreszcie, zwróć uwagę na zdefiniowaną relację przy użyciu ForeignKey
. Mówi to Django, że każdy Choice
jest związany z pojedynczym Question
. Django wspiera wszystkie powszechne relacje w bazach danych: wiele-do-jednego, wiele-do-wielu i jeden-do-jednego.
Włączanie modeli¶
Taki mały kawałek kodu modelu daje Django wiele informacji. Na ich podstawie, Django jest w stanie:
- Stworzyć schemat bazy danych (polecenia
CREATE TABLE
) dla tej aplikacji. - Stworzyć pythonowe API dostępu do bazy danych do dostępu do obiektów
Question
iChoice
.
Ale najpierw musimy powiedziesz naszemu projektowi, że aplikacja polls
jest zainstalowana.
Filozofia
Aplikacje Django są „wtyczkowe”: możesz używać aplikacji w wielu projektach i możesz udostępniać aplikacje, ponieważ nie muszą one być związane z daną instalacją Django.
Aby zawrzeć aplikację w naszym projekcie, musimy dodać odniesienie do jej klasy konfiguracyjnej w ustawieniu INSTALLED_APPS
. Klasa PollsConfig
jest w pliku polls/apps.py
, więc jej kropkowana ścieżka to 'polls.apps.PollsConfig'
. Zmień plik mysite/settings.py
i dodaj tę kropkowaną ścieżkę do ustawienia INSTALLED_APPS
. Będzie to wyglądało tak:
INSTALLED_APPS = [
'polls.apps.PollsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
Teraz Django wie, że ma zawierać aplikację polls
. Uruchommy następne polecenie:
$ python manage.py makemigrations polls
Powinieneś zobaczyć coś podobnego do tego:
Migrations for 'polls':
polls/migrations/0001_initial.py:
- Create model Choice
- Create model Question
- Add field question to choice
Uruchamiając makemigrations
, mówisz Django, że dokonałeś jakichś zmian w swoich modelach (w tym przypadku stworzyłeś nowe) i chcesz, aby te zmiany były przechowane jako migracja.
Migracje, to sposób w jaki Django przechowuje zmiany twoich modeli (i przez to zmiany schematu bazy danych) – są po prostu plikami na dysku. Możesz przeczytać migrację dla twojego nowego modelu, jeśli masz ochotę; to plik polls/migrations/0001_initial.py
. Nie przejmuj się, nie musisz ich czytać za każdym razem, kiedy Django je tworzy, ale zostały one zaprojektowane, aby były modyfikowalne przez dewelopera, na wypadek, gdybyś chciał ręcznie poprawić to, jak Django zmienia rzeczy.
Jest komenda, która uruchomi dla ciebie migracje i będzie zarządzać automatycznie schematem bazy danych – nazywa się migrate
i zaraz do niej dojdziemy – ale najpierw zobaczmy, jaki kod SQL ta migracja uruchomiła. Komenda sqlmigrate
bierze jako argument nazwy migracji i zwraca ich SQL:
$ python manage.py sqlmigrate polls 0001
Powinieneś zobaczyć coś podobnego do tego (sformatowaliśmy dla czytelności):
BEGIN;
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
"id" serial NOT NULL PRIMARY KEY,
"choice_text" varchar(200) NOT NULL,
"votes" integer NOT NULL
);
--
-- Create model Question
--
CREATE TABLE "polls_question" (
"id" serial NOT NULL PRIMARY KEY,
"question_text" varchar(200) NOT NULL,
"pub_date" timestamp with time zone NOT NULL
);
--
-- Add field question to choice
--
ALTER TABLE "polls_choice" ADD COLUMN "question_id" integer NOT NULL;
ALTER TABLE "polls_choice" ALTER COLUMN "question_id" DROP DEFAULT;
CREATE INDEX "polls_choice_7aa0f6ee" ON "polls_choice" ("question_id");
ALTER TABLE "polls_choice"
ADD CONSTRAINT "polls_choice_question_id_246c99a640fbbd72_fk_polls_question_id"
FOREIGN KEY ("question_id")
REFERENCES "polls_question" ("id")
DEFERRABLE INITIALLY DEFERRED;
COMMIT;
Zwróć uwagę na następującą rzecz:
- Dokładny output będzie różnił się w zależności od bazy danych, której używasz. Przykład powyżej jest wygenerowany dla PostgreSQLa.
- Nazwy tabel są wygenerowanie automatycznie przez połączenie nazwy aplikacji (
polls
) i nazwy modelu małymi literami –question
ichoice
. (Możesz nadpisać to zachowanie.) - Klucze główne (ID) są dodane automatycznie. (Możesz to też nadpisać.)
- W konwencji, Django dodaje
„_id”
do nazwy pola klucza obcego. (Tak, także to możesz nadpisać.) - Relacja klucza obcego jest wyraźna przez constraint
FOREIGN KEY
. Nie przejmuj się częściąDEFERRABLE
; to tylko mówi PostgreSQLowi, aby nie egzekwował więzu klucza obcego aż do końca transakcji. - Jest to dostosowane do bazy danych, której używasz, więc pola typowe dla bazy danych, takie jak
auto_increment
(MySQL),serial
(PostgreSQL) lubinteger primary key autoincrement
(SQLite) są obsługiwane dla ciebie automatycznie. To samo tyczy się wstawiania nazw pól w cudzysłowy – na przykład używania pojedynczego lub podwójnego cudzysłowu. - Komenda
sqlmigrate
nie uruchomi migracji na twojej bazie danych – po prostu drukuje ją na ekran, abyś zobaczył, jaki kod SQL jest według Django wymagany. Jest to przydatne do sprawdzenia co zamierza zrobić Django lub jeśli masz administratorów bazy danych, którzy oczekują skryptów SQL na potrzeby zmian.
Jeśli jesteś zainteresowany, możesz też uruchomić python manage.py check
; sprawdzi to jakiekolwiek problemy w twoim projekcie bez robienia migracji lub dotykania bazy danych.
Teraz uruchom ponowinie migrate
, aby stworzyć te tabele modeli w twojej bazie danych:
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
Rendering model states... DONE
Applying polls.0001_initial... OK
Komenda migrate
bierze wszystkie migracje, które jeszcze nie zostały zastosowane (Django śledzi, które są już zastosowane używając specjalnej tabeli w twojej bazie danych nazwanej django_migrations
) i uruchamia je na twojej bazie danych – to znaczy synchronizuje zmiany, które zrobiłeś w modelach ze schematem danych w bazie danych.
Migracje są potężnym narzędziem, pozwalając ci zmieniać twoje modele w czasie, gdy rozwijasz swój projekt, bez konieczności usuwania bazy danych lub tabel i tworzenia nowych – specjalizuje się w upgrade’owaniu twojej bazy danych na żywo, bez tracenia danych. Omówimy je bardziej dogłębnie w późniejszej części tutorialu, lecz teraz zapamiętaj trzy kroki do tworzenia zmian w modelach:
- Zmień swoje modele (w
models.py
). - Uruchom
python manage.py makemigrations
, aby stworzyć migracje dla tych zmian - Uruchom
python manage.py migrate
, aby zastosować te zmiany na bazie danych.
Powodem, dla którego komendy do tworzenia i stosowania migracji są rozdzielne, jest to, że będziesz commitował migracje do swojego systemu kontroli wersji i zawrzesz je w swojej aplikacji; one nie tylko ułatwiają dewelopment, ale też są użyteczne dla innych deweloperów i w produkcji.
Przeczytaj dokumentację django-admin, aby uzyskać pełną informację, co może robić narzędzie manage.py
.
Zabawa z API¶
Teraz wskoczmy do interaktywnego shella Pythona i pobawmy się z otwartym API, które daje Django. Aby wywołać Pythonowego shella, użyj tej komendy:
$ python manage.py shell
Używamy tego zamiast po prostu napisać „python”, ponieważ manage.py
ustawia zmienną środowiskową DJANGO_SETTINGS_MODULE
, która daje Django pythonową ścieżkę importu do twojego pliku mysite/settings.py
.
Kiedy już jesteś w shellu, zbadaj API bazy danych:
>>> from polls.models import Choice, Question # Import the model classes we just wrote.
# No questions are in the system yet.
>>> Question.objects.all()
<QuerySet []>
# Create a new Question.
# Support for time zones is enabled in the default settings file, so
# Django expects a datetime with tzinfo for pub_date. Use timezone.now()
# instead of datetime.datetime.now() and it will do the right thing.
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
# Save the object into the database. You have to call save() explicitly.
>>> q.save()
# Now it has an ID.
>>> q.id
1
# Access model field values via Python attributes.
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)
# Change values by changing the attributes, then calling save().
>>> q.question_text = "What's up?"
>>> q.save()
# objects.all() displays all the questions in the database.
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>]>
Ale zaraz. <Question: Question object (1)>
nie jest pomocną reprezentacją tego obiektu. Poprawmy to edytując model Question
(w pliku polls/models.py
) i dodając metodę __str__()
zarówno do Question
jak i Choice
:
from django.db import models
class Question(models.Model):
# ...
def __str__(self):
return self.question_text
class Choice(models.Model):
# ...
def __str__(self):
return self.choice_text
Dodanie metod __str__()
do twoich modeli jest ważne, nie tylko dla twojej własnej wygody, gdy używasz interaktywnego prompta, ale także dlatego, że reprezentacje obiektów są używane w automatycznie generowanym panelu administracyjnym Django.
Zwróć uwagę, że są to normalne metody Pythona. Dodajmy własną metodę, tylko na pokaz:
import datetime
from django.db import models
from django.utils import timezone
class Question(models.Model):
# ...
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
Zwróć uwagę na import datetime
i from django.utils import timezone
, odwołujące się kolejno do standardowego modułu Pythona datetime
i narzędzi Django związanych ze strefami czasowymi w django.utils.timezone
. Jeśli nie jesteś zaznajomiony z obsługą stref czasowych w Pythonie, możesz dowiedzieć się więcej w dokumentacji wsparcia stref czasowych.
Zapisz te zmiany i uruchom nowy interaktywny shell Pythona uruchamiając znów python manage.py shell
:
>>> from polls.models import Choice, Question
# Make sure our __str__() addition worked.
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>
# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>
# Get the question that was published this year.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>
# Request an ID that doesn't exist, this will raise an exception.
>>> Question.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Question matching query does not exist.
# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
# The following is identical to Question.objects.get(id=1).
>>> Question.objects.get(pk=1)
<Question: What's up?>
# Make sure our custom method worked.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True
# Give the Question a couple of Choices. The create call constructs a new
# Choice object, does the INSERT statement, adds the choice to the set
# of available choices and returns the new Choice object. Django creates
# a set to hold the "other side" of a ForeignKey relation
# (e.g. a question's choice) which can be accessed via the API.
>>> q = Question.objects.get(pk=1)
# Display any choices from the related object set -- none so far.
>>> q.choice_set.all()
<QuerySet []>
# Create three choices.
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)
# Choice objects have API access to their related Question objects.
>>> c.question
<Question: What's up?>
# And vice versa: Question objects get access to Choice objects.
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> q.choice_set.count()
3
# The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships.
# This works as many levels deep as you want; there's no limit.
# Find all Choices for any question whose pub_date is in this year
# (reusing the 'current_year' variable we created above).
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
# Let's delete one of the choices. Use delete() for that.
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()
Po więcej informacji na temat relacji między modelami, zobacz Dostęp do powiązanych obiektów.
Wprowadzenie do panelu administracyjnego Django¶
Filozofia
Wygenerowanie strony administracyjnej dla pracowników lub klientów do dodawania, zmieniania i usuwania treści jest żmudną pracą, która nie wymaga dużo kreatywności. Z tego powodu Django całkowicie automatyzuje tworzenie interfejsu administracyjnego.
Django było pisane w środowisku publicystów, z bardzo wyraźnym oddzieleniem „wydawców treści” i „publiczną” witryną. Managerowie stron korzystają z systemu, aby dodać nowe historie, wydarzenia, wyniki sportowe, itp. i ta zawartość jest wyświetlana na publicznej witrynie. Django rozwiązuje problem tworząc jednolity interfejs dla administratorów witryn do edycji treści.
Panel administracyjny nie jest przeznaczony do użycia przez odwiedzających stronę. Jest dla menadżerów witryny.
Tworzenie konta administratora¶
Najpierw musimy stworzyć użytkownika, który może logować się do panelu administracyjnego. Uruchom następującą komendę:
$ python manage.py createsuperuser
Wprowadź swoją pożądaną nazwę użytkownika i naciśnij enter.
Username: admin
Zostaniesz poproszony o swój adres e-mail:
Email address: admin@example.com
Ostatnim krokiem jest wprowadzenie hasła. Zostaniesz poproszony o wprowadzenie swojego hasła dwa razy, drugi raz na potwierdzenie pierwszego.
Password: **********
Password (again): *********
Superuser created successfully.
Uruchom serwer deweloperski¶
Panel administracyjny Django jest domyślnie uruchomiony. Uruchommy serwer deweloperski i poznajmy go.
Jeśli serwer nie jest uruchomiony, wystartuj go w ten sposób:
$ python manage.py runserver
Teraz otwórz przeglądarkę internetową i wejdź na „/admin/” swojej lokalnej domeny – na przykład http://127.0.0.1:8000/admin/. Powinieneś zobaczyć ekran logowania panelu administracyjnego:
Tłumaczenie jest domyślnie włączone, więc ekran logowania może zostać wyświetlony w twoim języku, zależnie od ustawień twojej przeglądarki i jeśli Django ma tłumaczenie dla tego języka.
Wejście do panelu administracyjnego¶
Teraz spróbuj się zalogować kontem superusera, które stworzyłeś w poprzednim kroku. Powinieneś zobaczyć stronę główną panelu administracyjnego Django:
Powinieneś zobaczyć kilka typów modyfikowalnej treści: grupy i użytkowników. Pochodzą one z django.contrib.auth
, frameworka uwierzytelniania Django.
Udostępnij aplikację ankietową do modyfikowania w panelu administracyjnym¶
Ale gdzie jest nasza aplikacja ankietowa? Nie wyświetla się na stronie głównej panelu.
Jest do zrobienia tylko jedna rzecz: musimy powiedzieć panelowi, że obiekty Question
mają interfejs administracyjny. Aby to zrobić, otwórz plik polls/admin.py
i zmień go, aby wyglądał tak:
from django.contrib import admin
from .models import Question
admin.site.register(Question)
Poznaj funkcjonalność wolnego panelu administracyjnego¶
Kiedy już zarejestrowaliśmy Question
, Django wie, że powinno być wyświetlane na stronie głównej panelu:
Kliknij w „Questions”. Jesteś teraz na stronie „change list” dla pytań. Ta strona wyświetla wszystkie pytania w bazie danych i pozwala wybrać ci jedno do zmiany. Jest tutaj pytanie „What’s up?”, które stworzyliśmy wcześniej:
Kliknij w pytanie „What’s up?”, aby je edytować:
Rzeczy, na które należy zwrócić tutaj uwagę:
- Formularz jest automatycznie wygenerowany z modelu
Question
. - Różne typu pól modeli (
DateTimeField
,CharField
) mają odpowiednie widgety kontrolek HTML. Każdy typ pola wie jak się wyświetlać w panelu Django. - Każde
DateTimeField
dostaje wolne javascriptowe skróty. Daty dostają skrót „Dzisiaj” i popup z kalendarzem a czas dostaje skrót „Teraz” i wygodny popup, który wylistowuje często wprowadzane godziny.
Dolna część strony daje ci klika możliwości:
- Zapisz – Zapisuje zmiany i powraca do strony change-list dla tego typu obiektów.
- Zapisz i kontynuuj edycję – Zapisuje zmiany i przeładowuję stronę panelu dla tego obiektu.
- Zapisz i dodaj nowe – Zapisuje zmiany i ładuje nowy, pusty formularz dla tego typu obiektu.
- Usuń – Wyświetla stronę potwierdzenia usunięcia.
Jeśli wartość pola „Date published” nie zgadza się z czasem, w którym stworzyłeś pytanie w Tutorialu 1, prawdopodobnie oznacza to, że zapomniałeś podać poprawnej wartości ustawienia TIME_ZONE
. Zmień je, przeładuj stronę i sprawdź, że pojawia się poprawna wartość.
Zmień „Date published” klikając skróty „Dzisiaj” i „Teraz”. Następniej kliknij „Zapisz i kontynuuj edycję”. Następnie kliknij w „Historia” w prawym górnym rogu. Zobaczysz stronę wylistowującą wszystkie zmiany dokonane na tym obiekcie przez panel administracyjny Django, z czasem i nazwą użytkownika osoby, która zrobiła zmianę:
Jeśli czujesz się dobrze z API modeli i zaprzyjaźniłeś się z panelem administracyjnym, przeczytaj 3. część tego tutoriala, aby dowiedzieć się jak dodać więcej widoków do naszej aplikacji ankietowej.