# Dokumentasi Django 6.0.7

# Menulis aplikasi Django kedua anda, bagian 2

Ttutorial ini memulai dimana Tutorial 1 ditinggalkan. Kami akan menyetelbasisdata, buat model pertama anda, dan dapatkan pengenalan cepat pada dibangkitkan-otomatis situs admin Django.

Dimana mendapatkan bantuan:

Jika anda memiliki masalah melalui tutorial ini, harap geser ke Getting Help bagian dari FAQ.

## Pengaturan basisdata

Sekarang, buka `mysite/settings.py`. Dia adalah modul Phyton biasa dengan variabel tingkat-modul mewakili pengaturan Django.

By default, the `DATABASES` configuration uses SQLite. If you're new to databases, or you're just interested in trying Django, this is the easiest choice. SQLite is included in Python, so you won't need to install anything else to support your database. When starting your first real project, however, you may want to use a more scalable database like PostgreSQL, to avoid database-switching headaches down the road.

If you wish to use another database, see details to customize and get your database running.

Ketika anda menyunting `mysite/settings.py`, setel `TIME_ZONE` ke zona waktu anda.

Juga, catat pengaturan `INSTALLED_APPS` pada bagian atas berkas. Yang menahan nama dari semua aplikasi Django yang diaktifkan di instance Django. Aplikasi dapat digunakan d banyak proyek, dan anda dapat memaketkan dan menyebarkan mereka untuk digunakan oleh lainnya di proyek mereka.

Secara awal, `INSTALLED_APPS` mengandung aplikasi berikut, semua yang datang dengan Django:

- `django.contrib.admin` -- Situs admin. Anda akan menggunakannya segera.

- `django.contrib.auth` -- Sebuah sistem pembuktian keaslian.

- `django.contrib.contenttypes` -- Sebuah kerangka untuk jenis isi.

- `django.contrib.sessions` -- Sebuah kerangka sesi.

- mod:django.contrib.messages -- Kerangka pesan.

- `django.contrib.staticfiles` -- Kerangka untuk mengelola berkas statis.

Aplikasi ini disertakan secara awal sebagai kenyamanan untuk kasus umum.

Beberapa aplikasi ini memanfaatkan setidaknya satu tabel basisdata, meskipun, jadi kami butuh untuk membuat tabel di basisdata sebelum kami dapat menggunakannya. Untuk melakukannya, jalankan perintah berikut:

/ 

    $ python manage.py migrate

    ...\> py manage.py migrate

Perintah `migrate` mencari `INSTALLED_APPS` setelan dan membuat tabel database yang diperlukan menurut pengaturan basisdata anda dalam berkas `mysite/settings.py` dan perpindahan basisdata disertai dengan aplikasi (kami akan membahas itu nanti). Anda akan melihat sebuah pesan untuk setiap perpindahan yang sudah dilakukan, jalankan baris-perintah klien untuk basisdata anda dan ketik `\dt` (PostgreSQL), `SHOW TABLES;` (MariaDB, MySQL), `.tables` (SQLite), atau `SELECT TABLE_NAME FROM USER_TABLES;` (Oracle) untuk menampilkan tabel-tabel Django yang dibuat.

Untuk minimalis

Seperti yang kami katakan diatas, aplikasi awal disertakan untuk kasus umum, tetapi tidak setiap orang membutuhkan mereka. Jika anda tidak membutuhkan sebagian atau semua dari mereka, silahkan komentari atau hapus baris yang diinginkan dari `INSTALLED_APPS` sebelum menjalankan `migrate`. Perintah `migrate` akan hanya menjalankan pemindahan tempat untuk aplikasi di `INSTALLED_APPS`.

## Membuat model

Sekarang kami akan menentukan model anda -- Pada dasarnya, tata letak basisdata anda, dengan metadata tambahan.

Filosofi

Sebuah model adalah tunggal, sumber tetap dari informasi tentang data anda. Itu mengandung bidang yang diperlukan dan perilaku dari data anda sedang simpan. Django mengikuti DRY Principle. Tujuannya adalah untuk menentukan model data dalam satu tempat dan otomatis mengambil hal-hal dari itu.

This includes the migrations, which are derived from your models file. They form a history that Django uses to update your database schema to match your current models.

Dalam aplikasi jejak pendapat kami, kami akan membuat dua model: `Question` dan `Choice`. `Question` memiliki pertanyaan dan tanggal penerbitan. `Choice` memiliki dua bidang: teks dari pilihan dan perhitungan pilihan. Setiap `Choice` dikaitkan dengan `Question`.

Konsep ini diwakilkan oleh kelas Python. Sunting berkas `polls/models.py` sehingga terlihat seperti ini:

`polls/models.py`

    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)

Disini, setiap model diwakilkan dengan kelas yang subkelas `django.db.models.Model`. Masing-masing model mempunyai sejumlah variabel kelas, setiapnya mewakilkan sebuah bidang basisdata dalam model.

Setiap bidang diwakilkan oleh contoh dari kelas `Field` class -- sebagai contoh `CharField` untuk bidang karakter dan `DateTimeField` untuk tanggal waktu. Ini memberitahu Django jenis apa dari data setiap bidang yang disimpan.

Nama dari setiap instance `Field` (sebagai contoh question_text` or `pub_date`) adalah nama bidang, di bentuk mesin-bersahabat. Anda akan menggunakan nilai ini di kode Phyton, dan basisdata anda akan menggunakannya sebagai nama kolom.

Anda dapat menggunakan pilihan argumen penempatan pertama pada `Field` untuk merancang nama dapat dibaca-manusia. Itu digunakan di pasangan bagian mawas diri dari Django dan dia mengganda sebagai dokumentasi. Jika bidang ini tidak disediakan, Django akan menggunakan nama dapat dibaca-manusia. Di contoh ini, kami telah hanya menentukan nama dapat dibaca-manusia untuk `Question.pub_date`. Untuk semua bidang lain di model ini, nama dapat dibaca-mesin akan mencukupi sebagai nama dapat dibaca-manusia nya.

Beberapa kelas `Field` mempunyai argumen wajib. `CharField`, sebagai contoh, membutuhkan anda memberikannya sebuah `max_length`. Yang digunakan tidak hanya untuk di skema basisdata, tetapi di pengesahan, seperti yang segera kita lihat.

Sebuah `Field` dapa juga mempunyai beragam argumen pilihan; dalam kasus ini, kami telah menyetel nilai `default` dari `pilih` ke 0.

Akhirnya, catatan hubungan ditentukan, menggunakan `ForeignKey`. Yang mengatakan Django setiap `Choice` terhubung pada `Question` tunggal. Django mendukung semua hubungan basisdata umum: banyak-ke-satu, banyak-ke-banyak, dan satu-ke-satu.

## Mengaktifkan model

Ada banyak informasi yang dapat disampaikan oleh beberapa baris contoh kode di atas. Dengan kode ini, Django dapat melakukan:

- Buat skema basisdata (pernyataan `CREATE TABLE`) untuk aplikasi ini.

- Buat API akses-basisdata Phyton untuk mengakses obyek `Pertanyaan` dan `Pilihan`.

Tetapi pertama kami butuh untuk memberitahu proyek kam bahwa aplikasi `jejak pendapat` telah terpasang.

Filosofi

Aplikasi Django dapat `ditanam`: Anda dapat menggunakan sebuah aplikasi dalam banyak proyek, dan anda dapat menyebarkan aplikasi, karena mereka tidak harus diikat pada pemasangan Django yang diberikan.

Untuk menyertakan aplikasi di proyek kami, kami butuh menambahkan acuan pada kelas konfigurasinya di pengaturan `INSTALLED_APPS`. Kelas `PollsConfig` ada di berkas `polls/apps.py`, jadi jalur bertitiknya adalah `'polls.apps.PollsConfig'`. Sunting berkas `mysite/settings.py` dan tambah jalur bertitik itu ke pengaturan `INSTALLED_APPS`. itu akan terlihat seperti ini:

`mysite/settings.py`

    INSTALLED_APPS = [
        "polls.apps.PollsConfig",
        "django.contrib.admin",
        "django.contrib.auth",
        "django.contrib.contenttypes",
        "django.contrib.sessions",
        "django.contrib.messages",
        "django.contrib.staticfiles",
    ]

Sekarang Django tahu menyertakan aplikasi `polls`. Mari kita jalankan perintah lain:

/ 

    $ python manage.py makemigrations polls

    ...\> py manage.py makemigrations polls

Anda harus melihat sesuatu yang mirip pada berikut:

    Migrations for 'polls':
      polls/migrations/0001_initial.py
        + Create model Question
        + Create model Choice

Dengan menjalankan `makemigrations`, anda mengatakan ke Django bahwa anda telah membuat beberapa perubahan di model anda (dalam kasus ini, anda telah membuat satu baru) dan itu anda ingin perubahan disimpan sebagai migration.

Perpindahan adalah bagaimana Django menyimpan perubahan ke model anda (dan dengan demikian skema basisdata anda) - mereka adalah berkas-berkas di cakram. Anda dapat membaca perpindahan untuk model baru anda jika anda suka; itu adalah berkas `polls/migrations/0001_initial.py`. Jangan khawatir, anda tidak diharapkan membaca mereka setiap waktu Django membuatnya, tetapi mereka dirancang untuk menjadi dapat-disunting-manusia dalam kasus anda ingin secara manual mengutik bagaimana Django merubah hal-hal.

Terdapat perintah yang akan menjalankan perpindahan tempat untuk anda dan mengelola skema basisdata anda otomatis - itu disebut `migrate`, dan kami akan datang ke dia sebentar lagi - tetapi pertama mari kita lihat SQL apa yang memindahkan tempat akan berjalan. Perintah `sqlmigrate` mengambil nama perpindahan tempat dan mengembalikan SQL mereka:

/ 

    $ python manage.py sqlmigrate polls 0001

    ...\> py manage.py sqlmigrate polls 0001

Anda harus melihat sesuatu mirip pada berikut (kami telah membentuk kembali dia untuk dapat dibaca):

    BEGIN;
    --
    -- Create model Question
    --
    CREATE TABLE "polls_question" (
        "id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
        "question_text" varchar(200) NOT NULL,
        "pub_date" timestamp with time zone NOT NULL
    );
    --
    -- Create model Choice
    --
    CREATE TABLE "polls_choice" (
        "id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
        "choice_text" varchar(200) NOT NULL,
        "votes" integer NOT NULL,
        "question_id" bigint NOT NULL
    );
    ALTER TABLE "polls_choice"
      ADD CONSTRAINT "polls_choice_question_id_c5b4b260_fk_polls_question_id"
        FOREIGN KEY ("question_id")
        REFERENCES "polls_question" ("id")
        DEFERRABLE INITIALLY DEFERRED;
    CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");

    COMMIT;

Catatan berikut:

- Keluaran pasti akan bermacam tergantung di basisdata anda gunakan. Contoh diatas adalah membangkitkan untuk PostgreSQL.

- Nama tabel otomatis dibangkitkan dengan memadukan nama dari aplikasi (`polls`) dan nama huruf kecil dari model -- `question` and `choice`. (Anda dapat menimpa kebiasaan ini.)

- Kunci utama (ID) ditambahkan otomatis. (Anda dapat menimpa ini, juga.)

- Berdasarkan kebiasaan, Django menambahkan `"_id"` ke nama bidang foreign key. (Ya, anda dapat menimpa ini, juga.)

- Hubungan foreign key dibuat jelas dengan batasan `FOREIGN KEY`. Jangan khawatir mengenai bagian `DEFERRABLE`; itu menceritakan PostgreSQL agar tidak memaksa foreign key sampai akhir transaksi.

- Itu disesuaikan ke basisdata yang anda sedang gunakan, sehingga jenis-jenis bidang khusus-basisdata seperti `auto_increment` (MySQL), `bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY` (PostgreSQL), atau `integer primary key autoincrement` (SQLite) ditangani untuk anda secara otomatis. Sama berlaku untuk mengutip nama bidang -- yaitu, menggunakan kutip ganda dan kutip tunggal.

- Perintah `sqlmigrate` sebenarnya tidak menjalankan perpindahan pada basisdata anda - malahan, itu mencetak nya ke layar shingga anda dapat melihat apa yang Django SQL pikir dibutuhkan. Itu sangat berguna untuk memeriksa apak yang Django akan lakukan atau jika anda memiliki administrator basisdata yang membutuhkan tulisan SQL untuk perubahan.

Jika anda tertarik, anda dapat juga menjalankan `python periksa manage.py`; pemeriksaan ini untuk masalah apapun di proyek anda tanpa membuat perindahan tempat atau menyentuk basisdata.

Sekarang, jalankan `migrate` kembali untuk membuat tabel model tersebut di basisdata anda:

/ 

    $ python manage.py migrate
    Operations to perform:
      Apply all migrations: admin, auth, contenttypes, polls, sessions
    Running migrations:
      Applying polls.0001_initial... OK

    ...\> py manage.py migrate
    Operations to perform:
      Apply all migrations: admin, auth, contenttypes, polls, sessions
    Running migrations:
      Applying polls.0001_initial... OK

Perintah `migrate` membawa semua pemindahan tempat yang belum diberlakukan (Django melacak yang mana diberlakukan menggunakan tabel khusus di basisdata anda disebut `django_migrations`) dan menjalankan mereka terhadap basisdata anda - pada dasarnya, sinkronisasi perubahan anda buat ke model anda dengan skema di basisdata.

Pemindahan tempat adalah sangat kuat dan membuat anda merubah model anda lembur, ketika anda mengembangkan proyek anda, tanpa buth menghapus basisdata anda atau tabel dan membuat satu yang baru - Dia khusus dalam meningkatkan basisdata langsung, tanpa kehilangan data. Kami akan melingkupi mereka lebih dalam di bagian kemudian dari tutorial, tetapi untuk sekarang, ingat panduan tiga-langkah untuk membuat perubahan model:

- Rubah model anda (di``models.py``).

- Run `python manage.py makemigrations` to create migrations for those changes.

- Jalankan `python manage.py migrate` untuk memberlakukan perubahan tersebut ke basisdata.

Alasan bahwa ada perintah terpisah untuk membuat dan memberlakukan perpindahan karena anda akan menyerahkan perpindahan ke sistem kendali versi anda dan mengirimkan mereka dengan aplikasi anda; mereka tidak hanya membuat pengembangan anda lebih mudah, mereka juga berguna oleh pengembang-pengembang lain dan dalam produksi.

Baca django-admin documentation untuk informasi penuh pada apa kegunaan `manage.py` dapat lakukan.

## Bermain dengan API

Sekarang, mari kita melompat ke dalam shell Phyton dan bermain dengan API bebas Django yang diberikan ke anda. Untuk memintah shell Phyton, gunakan perintah ini:

/ 

    $ python manage.py shell

    ...\> py manage.py shell

We're using this instead of simply typing "python", because `manage.py` sets the `DJANGO_SETTINGS_MODULE` environment variable, which gives Django the Python import path to your `mysite/settings.py` file. By default, the `shell` command automatically imports the models from your `INSTALLED_APPS`.

Once you're in the shell, explore the database API:

    # 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=datetime.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)>]>

Tunggu dulu. `<Question: Question object (1)>` bukanlah perwakilan membantu dari obyek ini. Mari kita perbaiki itu dengan menyunting modl `Question` (dalam berkas `polls/models.py`) dan menambahkan sebuah metode `__str__()` pada kedua `Question` dan `Choice`:

`polls/models.py`

    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

Sangat penting menambahkan cara `__str__()` ke model anda, tidak hanya kenyamanan anda ketika berurusan dengan prompt interaktif, tetapi juga karena perwakilan obyek digunakan di seluruh admin dibangkitkan-otomatis Django.

Mari kita tambahkan sebuah metode penyesuaian pada model ini:

`polls/models.py`

    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)

Catat tambahand dari `import datetime` dan `from django.utils import timezone`, untuk mengacu standar Phyton modul `datetime` dan kegunaan zona-waktu-terhubung Django di `django.utils.timezone`, masing-masing. Jika anda belum akrab dengan penanganan zona waktu di Phyton, anda dapat mempelajari lebih di dokumen dukungan zona waktu.

Save these changes and start a new Python interactive shell. (If a three-chevron prompt (>>>) indicates you are still in the shell, you need to exit first using `exit()`). Run `python manage.py shell` again to reload the models.

    # 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 (defined as "choice_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()

Untuk informasi lebih di kaitan model, lihat Accessing related objects. Untuk lebih bagaimana menggunakan garis bawah ganda untuk melakukan bidang lookup melalui API, lihat Field lookups. Untuk rincian penuh di basisdata API, lihat Database API reference kami.

## Memperkenalkan Admin Django

Filosofi

Membangkitkan situs admin untuk staf atau klien anda untuk menambah, merubah, dan menghapus isi adalah pekerjaan membosankan yang tidak membutuhkan banyak kreatifitas. Untuk alasan itu, Django sepenuhnya otomatisasi pembuatan antarmuka admin untuk model.

Django ditulis di lingkungan ruang berita, dengan pemisahan jelas antara situs "penerbit umum" dan "umum". Pengelola situs menggunakan sistem untuk menambahkan cerita berita, acara, skor olahraga, dll. dan isi itu ditampilkan di situs umum. Django mengatasi masalah dari pembuatan antarmuka terpadu untuk administrator situs untuk menyunting isi.

Admin tidak diperuntukkan untuk digunakan oleh pengunjung situs. Itu untuk pengelola situs.

### Membuat pengguna admin

Pertama kami akan butuh membuat pengguna yang dapat masuk ke situs admin. Jalankan perintah berikut:

/ 

    $ python manage.py createsuperuser

    ...\> py manage.py createsuperuser

Masukkan nama pengguna anda inginkan dan tekan enter.

    Username: admin

Anda akan diarahkan ke alamat surel yang anda inginkan:

    Email address: admin@example.com

Langkah akhir adalah memasukkan sandi anda. Anda akan diminta memasukkan sandi anda dua kali, kedua kali sebagai penegasan dari yang pertama.

    Password: **********
    Password (again): *********
    Superuser created successfully.

### Nyalakan peladen pengembangan

Situs Admin Django diaktifkan secara awal. Mari kita nyalakan peladen pengembangan dan jelajahi dia.

Jika peladen tidak berjalan nyalakan seperti biasa:

/ 

    $ python manage.py runserver

    ...\> py manage.py runserver

Sekarang, buka peramban jaringan dan pergi ke "/admin/" di domain lokal anda -- yaitu, http://127.0.0.1:8000/admin/. Anda seharusnya melihan layar masuk admin:

Sejak translation dinyalakan secara awalan, jika anda mensetel `LANGUAGE_CODE`, layar masuk akan ditampilkan dalam bahasa yang diberikan (jika Django memiliki terjemahan yang sesuai).

### Masuk situs admin

Sekarang, coba masuk dengan akun superuser anda telah buat di langkah sebelumnya. Anda seharusnya melihat halaman index admin Django:

Anda seharusnya melihat beberapa jenis isi dapat disunting: kelompok dan pengguna. Mereka disediakan oleh `django.contrib.auth`, kerangka pembuktian keaslian dikirim oleh Django.

### Buat aplikasi jejak pendapat dapat di rubah di admin

Tetapi dimana aplikasi jejak pendapat kami? DIa tidak ditampilkan di halaman index admin.

Hanya satu hal lagi untuk dilakukan: kami butuh memberitahu admin bahwa obyek `Question` memiliki antarmuka admin. Untuk melakukan ini, buka berkas `polls/admin.py`, dan sunting itu untuk terlihat seperti ini:

`polls/admin.py`

    from django.contrib import admin

    from .models import Question

    admin.site.register(Question)

### Jelajahi fungsi admin bebas

Sekarang kita telah mendaftarkan `Question`, Django mengetahui bahwa itu harus ditampilkan di halaman index admin:

Klik `Question`. Sekarang anda berada di halaman "change list" untuk pertanyaan. Halaman ini menampilkan semua pertanyaan di basisdata dan membiarkan anda memilih satu untuk merubahnya. Ada pertanyaan "Ada apa? kami buat sebelumnya:

Klik pertanyaan "Ada apa?" untuk menyuntingnya:

Hal-hal untuk dicatat disini:

- Formulir otomatis dibangkitkan dari model `Question`.

- Jenis bidang model berbeda ((`DateTimeField`, `CharField`) berhubungan ke widget masukan HTML sesuai. Setiap jenis dari bidang mengetahui bagaimana menampilkan diri sendiri di admin Django.

- Setiap `DateTimeField` mendapatkan jalan pintas Javascript bebas. Tanggal mendapatkan jalan pintas "Hari ini" dan popup kalender, dan waktu mendapatkan jalan pintas "Sekarang" dan popup nyaman yang menampilkan waktu dimasukkan umum.

Bagian bawah halaman memberikan anda pasangan pilihan:

- Simpan -- Simpan perubahan dan kembalikan halaman daftar-rubah untuk jenis ini dari obyek.

- Simpan dan lanjutkan menyunting -- Simpan perubahan dan muat kembali halaman admin untuk obyek ini.

- Simpan dan tambah lain -- Simpan perubahan dan muat baru, formulir kosong untuk jenis ini dari obyek.

- Hapus -- Tampilkan halaman penegasan hapus.

Jika nilai "Tanggal diterbitkan" tidak cocok waktu ketika anda membuat pertanyaan di Tutorial 1, itu kemungkinan berarti anda lupa untuk mengatur nilai benar untuk pengaturan `TIME_ZONE`. Rubah itu, muat kembali halaman dan periksa bahwa nilai benar muncul.

Rubah "Tanggal diterbitkan" dengan mengklik jalan pintas "Hari ini" dan "Sekarang". Lalu klik "Simpan dan lanjut menyunting". Lalu klik "Sejarah" di kanan atas. Anda akan melihat halaman menampilkan semua perubahan yang dibuat pada obyek ini melalui admin Django, dengan stempel waktu dan nama pengguna dari orang yang membuat perubahan:

Ketika anda sudah nyaman dengan API model dan telah mengakrabkan diri anda dengan situs admin, baca part 3 of this tutorial untuk mempelajari tentang bagaimana menambahkan tampilan lebih ke aplikasi jejak pendapat kami.