# dokumentasi Django 2.0.8

# Catatan terbitan Django 1.9

Desember 1, 2015

Selamat datang di Django 1.9!

Catatan terbitan ini melingkupi new features, sama halnya beberapa backwards incompatible changes anda ingin sadari dari ketika meningkatkan dari Django 1.8 atau versi terlama. Kami telah dropped some features yang telah mencapai akhir dari siklus pengusangan mereka, dan kami telah begun the deprecation process for some features.

Lihat panduan Meningkatkan Django ke versi terbaru jika anda sedang memperbaharui proyek yang ada.

## Kesesuaian Python

Django 1.9 membutuhkan Python 2.7, 3.4, or 3.5. Kami sangat menganjurkan dan hanya secara resmi mendukung terbitan terakhir dari setiap rangkaian.

Rangkaian Django 1.8 adalah dukungan terakhir untuk mendukung Python 3.2 dan 3.3.

## Apa yang baru di Django 1.9

### Melakukan tindakan setelah perbaikan transaksi

Kaitan `on_commit()` baru mengizinkan melakukan tindakan setelah sebuah transaksi basisdata berhasil diperbaiki. Ini berguna untuk tugas seperti mengirim surel pemberitahuan, membuat antrian tugas, atau membatalkan cache.

Fungsi ini dari paket django-transaction-hooks telah dipadukan kedalam Django.

### Pengesahan sandi

Django sekarang menawarkan pengesahan sandi untuk membantu mencegah penggunaan dari sandi lemah oleh pengguna. Pengesahan dipadaukan di perubahan sandi disertakan dan menyetel formulir dan cukup memadukan di kode lain apapum. Pengesahan dilakukan oleh satu atau lebih pengesah, dikonfigurasikan di pengaturan `AUTH_PASSWORD_VALIDATORS` baru.

Empat pengesah disertakan di Django, yang dapat memaksa panjang minimal, bandingkan sandi pada atribut pengguna seperti nama mereka, pastikan sandi tidak seluruhnya numerik, atau periksa kembali sebuah daftar disertakan dari sandi umum. Anda dapat memadukan banyak pengesah, dan beberapa pengesah mempunyai penyesuaian pilihan konfigurasi. Sebagai contoh, anda dapat memilih menyediakan sebuah daftar penyesuaian dari sandi umum. Setiap pengesah menyediakan sebuah teks bantuan untuk menjelaskan persyaratannya ke pengguna.

Secara awalan, tidak ada pengesahan dilakukan dan semua sandi diterima, jadi jika anda tidak menyetel `AUTH_PASSWORD_VALIDATORS`, anda tidak akan melihat perubahan apapun. Di proyek baru dibuat dengan cetakan `startproject` awalan, kumpulan sederhana dari pengesah diadakan. Untuk mengadakan pengesahan dasar di formulir autentifikasi yang disertakan untuk proyek anda, anda dapat menyetel, sebagai contoh:

    AUTH_PASSWORD_VALIDATORS = [
        {
            'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
        },
    ]

Lihat Pengesahan sandi untuk lebih rinci.

### Perizinan mixin untuk tampilan berdasarkan-kelas

Django sekarang dibekali dengan campuran `AccessMixin`, `LoginRequiredMixin`, `PermissionRequiredMixin`, dan `UserPassesTestMixin` untuk menyediakan kegunaan dari `django.contrib.auth.decorators` untuk tampilan berdasarkan-kelas. Campuran ini telah diambil dari, atau setidaknya diilhami oleh, proyek django-braces.

Ada sedikit perbedaan diantara penerapan Django dan ``django-braces`, meskipun:

- Atribut `raise_exception` hanya dapat menjadi `True` atau `False`. Penyesuaian pengecualian atau callable tidak didukung.
- Metode `handle_no_permission()` tidak mengambil argumen `request`. Permintaan saat ini tersedia di `self.request`.
- Penyesuaian `test_func()` dari `UserPassesTestMixin` tidak mengambil sebuah argumen `user`. Pengguna saat ini tersedia di `self.request.user`.
- Atribut `permission_required` mendukung sebuah string (menentukan satu perizinan) atau sebuah daftar/tuple dari string (menentukan banyak perizinan) yang butuh dipenuhi untuk memberikan akses.
- Atribut `permission_denied_message` baru mengizinkan melewatkan sebuah pesan ke pengecualian `PermissionDenied`.

### Gaya baru untuk `contrib.admin`

The admin sports a modern, flat design with new SVG icons which look perfect on HiDPI screens. It still provides a fully-functional experience to YUI's A-grade browsers. Older browser may experience varying levels of graceful degradation.

### Menjalankan percobaan secara sejalan

Pilihan `test` command now supports a `--parallel` untuk menjalankan percobaan proyek di banyak pengolahan secara sejalan.

Setiap pengolahan mendapatkan basisdatanya sendiri. Anda harus memastikan bahwa kasus-kasus percobaan berbeda tidak mengakses sumberdaya sama. Sebagai contoh, kasus-kasus percobaan yang menyentuh sistem berkas harus membuat direktori sementara untuk penggunaan mereka sendiri.

Pilihan diadakan secara awalan untuk deretan percobaan sendiri Django disediakan:

- SO mengukung itu (semua kecuali Windows)
- backend basisdata mendukung itu (semua backend siap-pakai kecuali Oracle)

### Fitur kecil

#### `django.contrib.admin`

- Tampilan admin sekarang mempunyai atribut `model_admin` atau `admin_site`
- URL dari tampilan rubah admin telah berubah (sebelumnya di `/admin/<app>/<model>/<pk>/` secara awalan dan sekarang di `/admin/<app>/<model>/<pk>/change/`). Ini tidak harus mempengaruhi aplikasi anda meskipun anda mengkode keraskan URL admin. Dalam kasus itu, ganti tautan tersebut dengan reversing admin URLs . Catat bahwa URL lama masih megnalihkan ke satu yang baru dari kesesuaian kebelakang, tetapi itu mungkin dipindahkan di versi akan datang.
- `ModelAdmin.get_list_select_related()` telah ditambahkan untuk mengizinkan perubahan nilai-nilai `select_related()` di permintaan daftar rubah admin berdasarkan pada permintaan.
- Variabel konteks `available_apps`, yang mendaftar aplikasi tersedia untuk pengguna saat ini, telah ditambahkan ke metode `AdminSite.each_context()`.
- `AdminSite.empty_value_display` dan `ModelAdmin.empty_value_display` telah ditambahkan untuk menimpa tampilan dari nilai-nilai kosong di daftar rubah admin. Anda dapat juga menyesuaikan nilai untuk setiap bidang.
- Ditambahkan acara jQuery when an inline form is added or removed pada perubahan halaman formulir.
- Widget pengambil waktu menyertakan pilihan '6 p.m' untuk ketetapan dari memiliki pilihan yang telah ditetapkan setiap 6 jam.
- Pembangkitan keong JavaScript sekarang mendukung karakter Rumania.

#### `django.contrib.admindocs`

- Bagian model dari `admindocs` sekarang juga menggambarkan metode yang mengambil argumen, daripada mengabaikan mereka.

#### `django.contrib.auth`

- Perhitungan perulangan awal untuk pengacak sandi PBKDF2 telah ditingkatkan oleh 20%. Perubahan kesesuaian kebelakang tidak akan mempengaruhi pengguna yang mempunyai subkelas `django.contrib.auth.hashers.PBKDF2PasswordHasher` untuk merubah nilai awal.
- `BCryptSHA256PasswordHasher` akan sekarang memperbaharui sandi jika atribut `rounds` nya berubah.
- `AbstractBaseUser` dan `BaseUserManager` dipindahkan ke modul `django.contrib.auth.base_user` baru sehingga mereka dapat diimpor tanpa menyertakan `django.contrib.auth` di `INSTALLED_APPS` (melakukannya memunculkan peringatan pengusangan di versi terlama dan tidak lagi didukung di Django 1.9).
- Argumen perizinan dari `permission_required()` menerima semua macam dari perulangan, tidak hanya daftar dan tuple.
- `PersistentRemoteUserMiddleware` baru membuat itu memungkinkan menggunakan `REMOTE_USER` untuk pengaturan dimana kepala hanya dikumpulkan pada halaman masuk daripada setiap permintaan di sesi.
- Tampilan `password_reset()` menerima sebuah parameter `extra_email_context`.

#### `django.contrib.contenttypes`

- Itu sekarang memungkinkan menggunakan `order_with_respect_to` dengan `GenericForeignKey`.

#### `django.contrib.gis`

- Semua metode `GeoQuerySet` telah diusangkan dan diganti oleh equivalent database functions. Segera setelah metode warisan telah diganti di kode anda, anda harus bahkan dapat memindahkan `GeoManager` khusus dari kelas-kelas diadakan-GIS anda.
- Antarmuka GDAL sekarang mendukung instansiasi berdasarkan-berkas dan GDALRaster objects dalam-memori dari data mentah. Penyetel untuk sifat raster seperti proyeksi atau nilai-nilai pixel telah ditambahkan.
- Untuk pengguna PostGIS, `RasterField` baru mengizinkan storing GDALRaster objects. Itu mendukung pembuatan indeks spasial otomatis dan proyeksi ulang ketika menyimpan sebuah model. Itu belum mendukung permintaan spasial.
- Metode `GDALRaster.warp()` baru mengizinkan membengkokkan sebuah raster dengan menentukan sifat sasaran seperti asal, lebar, tinggi, atau ukuran pixel (terhadap lainnya).
- Metode `GDALRaster.transform()` mengizinkan perubahan sebuah raster menjadi sebuah spasial berbeda mengacu sistem dengan menentukan sebuah sasaran `srid`.
- Kelas `GeoIP2` baru mengizinkan menggunakan basisdata GeoLite2 MaxMind yang menyertakan dukungan untuk alamat IPv6.
- Versi pustaka OpenLayer awalan disertakan dalam widget telah diperbaharui dari 2.13 menjadi 2.13.1.

#### `django.contrib.postgres`

- Ditambahkan dukungan untuk pencarian `rangefield.contained_by` untuk beberapa bidang siap pakai yang berhubungan ke jangkauan bidang
- Ditambahkan `JSONField`.
- Ditambahkan Fungsi pengumpulan khusus PostgreSQL.
- Ditambahkan fungsi basisdata `TransactionNow`.

#### `django.contrib.sessions`

- Model sesi dan kelas-kelas `SessionStore` untuk backend `db` dan `cached_db` direfaktor untuk mengizinkan penyesuaian backend basisdata untuk membangun atas mereka. Lihat Memperpanjang mesin sesi didukung-basisdata untuk rincian lebih.

#### `django.contrib.sites`

- `get_current_site()` sekarang menangani kasus dimana `request.get_host()` mengembalikan `domain:port`, sebagai contoh `example.com:80`. Jika pencarian gagal karena rumah tidak cocok sebuah rekaman di basisdata dan rumah mempunyai sebuah port, port dilucuti dan pencarian dicoba dengan hanya sebagian ranah.

#### `django.contrib.syndication`

- Dukungan untuk lampiran per umpan barang telah ditambahkan. Jika banyak lampiran ditentukan pada umpan RSS, sebuah pengecualian dimunculkan sebagai umpan RSS, tidak seperti umpan Atom, tidak mendukung banyak lampiran per umpan barang.

#### Tembolok

- `django.core.cache.backends.base.BaseCache` sekarang mempunyai metode `get_or_set()`.
- `django.views.decorators.cache.never_cache()` sekarang mengirim kepala meyakinkan (ditambahkan `no-cache, no-store, must-revalidate` ke `Cache-Control`) untuk lebih baik mencegah menyimpan sementara. Ini juga ditambahkan di Django 1.8.8.

#### CSRF

- Nama kepala permintaan digunakan untuk otentifikasi CSRF dapat disesuaikan dengan `CSRF_HEADER_NAME`.
- Kepala pengacu CSRF sekarang disahkan terhadap pengaturan `CSRF_COOKIE_DOMAIN` jika disetel. Lihat Bagaimana itu bekerja untuk rincian.
- Pengaturan `CSRF_TRUSTED_ORIGINS` baru menyediakan cara mengizinkan permintaan tidak aman lintas-asli (sebagai contoh `POST`) terhadap HTTPS.

#### Backend basisdata

- Backend PostgreSQL (`django.db.backends.postgresql_psycopg2`) juga tersedia sebagai `django.db.backends.postgresql`. Nama lama akan lanjut menjadi tersedia untuk kesesuaian kebelakang.

#### Penyimpanan Berkas

- `Storage.get_valid_name()` sekarang dipanggil ketika `upload_to` dapat dipanggil.
- `File` sekarang mempunyai metode `seekable()` ketika menggunakan Python 3.

#### Formulir

- `ModelForm` menerima pilhan `Meta` baru `field_classes` untuk menyesuaikan jenis dari bidang. Lihat Mengesampingan nilai awal untuk rincian.
- Anda sekarang dapat menentukan urutan dimana bidang-bidang formulir dengan atribut `field_order`, argumen pembangun `field_order`, atau metode `order_fields()`.
- Sebuah awalan formulir dapat ditentukan didalam sebuah kelas formulir, bukan hanya ketika menginstasiasikan sebuah formulir. Lihat Awalan untuk formulir untuk rincian.
- Anda sekarang dapat specify keyword arguments yang ingin melewatkan ke pembangun dari formulir di sebuah formset.
- `SlugField` sekarang menerima sebuah argumen `allow_unicode` untuk mengizinkan karakter Unicode dalam keong.
- `CharField` sekarang menerima sebuah argumen `strip` untuk melucuti masukan data dari awalan dan buntutan ruang kosong. Ketika awalan ini menjadi `True` ini adalah perilaku berbeda dari terbitan sebelumnya.
- Bidang-bidang formulir sekarang mendukung argumen `disabled`, mengizinkan widget bidang ditampilkan ditiadakan oleh peramban.
- Itu sekarang menimpa menyesuaikan ikatan bidang dengan menimpa metode `get_bound_field()` bidang.

#### Tampilan Umum

- Tampilan berdasarkan-kelas dibangkitkan menggunakan `as_view()` sekarang mempunyai atribut `view_class` dan `view_initkwargs`.
- `method_decorator()` sekarang dapat digunakan dengan sebuah daftar atau tuple dari penghias. Itu juga dapat digunakan untuk decorate classes instead of methods.

#### Internasionalisasi

- Tampilan `django.views.i18n.set_language()` sekarang dengan benar mengarahkan ke translated URLs, ketika tersedia.
- Tampilan `django.views.i18n.javascript_catalog()` sekarang bekerja dengan benar jika digunakan banyak kali dengan konfigurasi berbeda pada halaman sama.
- Fungsi `django.utils.timezone.make_aware()` memperoleh sebuah argumen `is_dst` untuk membantu menyelesaikan waktu tidak pasti selama masa peralihan DST.
- Anda sekarang dapat menggunakan beragam lokal didukung oleh gettext. Ini adalah biasanya digunakan untuk bahasa yang dapat ditulis dalam tulisan berbeda, sebagai contoh Latin dan Cyrillic (sebagai contoh `be@latin`).
- Ditambahkan tampilan `django.views.i18n.json_catalog()` untuk membantu membangun penyesuaian sisi-klien pustaka i18n diatas terjemahan Django. Itu mengembalikan sebuah obyek JSON mengandung sebuah katalog terjemahan, pengaturan bentuk, dan aturan jamak.
- Ditambahkan atribut `name_translated` pada obyek dikembalikan oleh etiket cetakan `get_language_info`. Juga ditambahkan penyaring cetakan berhubungan: `language_name_translated`.
- Anda sekarang dapat menjalankan `compilemessages` dari direktori akar dari proyek anda dan itu akan menemukan semua berkas pesan aplikasi dibuat oleh `makemessages`.
- `makemessages` sekarang memanggil xgettext sekali per direktori lokal daripada sekali per berkas diterjemahkan. Ini mempercepat membangun lokalisasi.
- `blocktrans` mendukung memberikan keluarannya ke sebuah variabel menggunakan `asvar`.
- Dua bahasa baru tersedia: Spanyol Kolombia dan Gael Skotlandia.

#### Pengelolaan perintah

- Perintah `sendtestemail` baru membiarkan anda mengirim sebuah percobaan surel untuk dengan mudah menegaskan bahwa pengiriman surel melalui Django bekerja.
- Untuk meningkatkan kesiapan dari pembangkitan kode SQL oleh `sqlmigrate`, pembangkit kode SQL untuk setiap tindaan perpindahan didahului oleh gambaran tindakan.
- Keluaran perintah `dumpdata` sekarang menentukan urutan. Bahkan, ketika pilihan `--output` ditentukan, itu juga menampilkan batang kemajuan dalam terminal.
- Perintah `createcachetable` sekarang mempunyai bendera ``--dry-run``untuk mencetak SQL daripada menjalankannya.
- Perintah `startapp` membuat sebuah berkas `apps.py`. Sejak itu tidak menggunakan `default_app_config` (a discouraged API), anda harus menentukan jalur konfigurasi aplikasi, sebagai contoh `'polls.apps.PollsConfig'`, dalam `INSTALLED_APPS` untuk itu digunakan (daripada hanya `'polls'`).
- Ketika menggunakan backend PostgreSQL, perintah `dbshell` dapat terhubung ke basisdata menggunakan sandi dari berkas pengaturan anda (daripada membutuhkannya untuks ecara manual dimasukkan).
- paket `django` mungkin dilarikan sebagai sebuah tulisan, yaitu `python -m django`, yang akan berperilaku sama seperti `django-admin`.
- Perintah pengelolaan yang mempunyai pilihan `--noinput` sekarang juga mengambil `--noinput` sebagai sebuah nama lain untuk pilihan itu.

#### Perpindahan

- Perpindahan inisial sekarang ditandai dengan sebuah atribut kelas `initial = True` yang mengizinkan option:migrate --fake-initial untuk lebih mudah mengenali perpindahan inisial.

- Ditambahkan dukungan untuk serialisasi dari instance `functools.partial` dan `LazyObject`.

- Ketika menyediakan `None` sebagai sebuah nilai dalam `MIGRATION_MODULES`, Django akan menganggap aplikasi sebuah aplikasi tanpa perpindahan.

- Ketika memberlakukan perpindahan, langkah "Rendering model states" yang ditampilkan ketika menjalankan perpindahan dengan bertele-tele 2 atau lebih tinggi sekarang menghitung hanya untuk perpindahan yang telah diberlakukan. Keadaan model sedang diberlakukan dibangkitkan di permintaan, secara drastis mengurangi sejumlah memori yang dibutuhkan.

  Bagaimanapun, perbaikan ini tidak tersedia ketika tidak memberlakukan perpindahan dan karena itu masih membutuhkan pra perhitungan dan penyimpanan dari keadaan perpindahan menengah.

  Perbaikan ini juga membutuhkan bahwa Django tidak lagi mendukung rencana perpindahan campuran. Rencana campuran terdiri dari daftar perpindahan dimana beberapa sedang diberlakukan dan lainnya tidak diberlakukan. Ini tidak pernah secara resmi didukung dan tidak pernah mempunyai API umum yang mendukung kebiasaan ini.

- Perintah `squashmigrations` sekarang mendukung menentukan permulaan perpindahan dari dimana perpindahan dilumatkan.

#### Model

- `QuerySet.bulk_create()` sekarang bekerja pada model proxi.
- Konfigurasi basisdata mendapatkan sebuah pilihan `TIME_ZONE` untuk interaksi dengan basisdata yang menyimpan datetime di waktu lokal dan tidak mendukung zona waktu ketika `USE_TZ` adalah `True`.
- Ditambahkan metode `RelatedManager.set()` pada pengelola terkait dibuat oleh `ForeignKey`, `GenericForeignKey`, dan `ManyToManyField`.
- Metode `add()` pada sebuah foreign key balikan sekarang mempunyai parameter `bulk` untuk mengizinkan menjalankan satu permintaan tanpa memperhatikan dari sejumlah obyek sedang dtambahkan daripada satu permintaan per obyek.
- Ditambahkan parameter `keep_parents` pada `Model.delete()` untuk mengizinkan haya menghapus data anak di model yang menggunakan warisan banyak-tabel.
- `Model.delete()` dan `QuerySet.delete()` mengembalikan sejumlah obyek dihapus.
- Ditambahkan sebuah pemeriksaan sistem untuk mencegah menentukan kedua `Meta.ordering` dan `order_with_respect_to` pada model sama.
- Pencarian `Date and time` dapat ditambatkan dengan pecnarian lain (seperti `exact`, `gt`, `lt`, dll.). Sebagai contoh: `Entry.objects.filter(pub_date__month__gt=6)`.
- Pencarian waktu (jam, menit, detik) sekarang didukung oleh `TimeField` untuk semua backend basisdata. Dukungan untuk backend selain dari SQLite telah ditambahkan tetapi tidak terdokumentasikan di Django 1.7.
- Anda dapat menentukan parameter `output_field` dari kumpulan `Avg` untuk mengumpulkan terhadap kolom bukan-numerik, seperti `DurationField`.
- Ditambahkan pencarian `date` pada `DateTimeField` untuk mengizinkan meminta bidang dengan hanya sebagian tanggal.
- Ditambahkan fungsi basisdata `Greatest` dan `Least`.
- Ditambahkan fungsi basisdata `Now`, yang mengembalikan tanggal dan waktu saat ini.
- `Transform` sekarang sebuah subkelas dari Func() yang mengizinkan `Transform` untuk digunakan di sisi tangan kanan dari pernyataan, sama seperti `Func` biasa. Ini mengizinkan mendaftarkan beberapa fungsi basisdata seperti `Length`, `Lower`, dan `Upper` sebagai perubahan bentuk.
- `SlugField` sekarang menerima sebuah argumen `allow_unicode` untuk mengizinkan karakter Unicode di keong.
- Ditambahkan dukungan untuk mengacu keterangan di `QuerySet.distinct()`.
- `connection.queries` menampilkan permintaan dengan parameter pengganti pada SQLite.
- Query expressions dapat sekarang digunakan ketika membuat instance model baru menggunakan `save()`, `create()`, dan `bulk_create()`.

#### Permintaan dan Tanggapan

- Meskipun `HttpResponse.reason_phrase` adalah jelas disetel, itu sekarang ditentukan oleh nilai saat ini dari `HttpResponse.status_code`. Merubah nilai dari `status_code` diluar dari pembangun akan juga merubah nilai dari `reason_phrase`.
- Tampilan mencari kesalahan sekarang menampilkan rincian dari tambatan pengecualian pada Python 3.
- Awalan tampilan kesalahan 40x sekarang menerima sebuah pameter penempatan kedua, pengecualian yang membangkitkan tampilan.
- Tampilan penangan kesalahan sekarang mendukung `TemplateResponse`, secara umum digunakan dengan tampilan berdasarkan-kelas.
- Pengecualian dimunculkan oleh metode `render()` sekarang dilewatkan ke metode `process_exception()` untuk setiap middleware.
- Permintaan middleware sekarang dapat menyetel `HttpRequest.urlconf` menjadi `None` untuk mengembalikan perubahan apapun dibuat oleh middleware sebelumnya dan mengembalikan menggunakan `ROOT_URLCONF`.
- Pemeriksaan `DISALLOWED_USER_AGENTS` di `CommonMiddleware` sekarang memunculkan sebuah pengecualian `PermissionDenied` sebagai lawan ke mengembalikan sebuah `HttpResponseForbidden` sehingga `handler403` dipanggil.
- Ditambahkan `HttpRequest.get_port()` untuk mengambil port berasal dari permintaan.
- Ditambahkan parameter `json_dumps_params` pada `JsonResponse` untuk mengizinkan melewatkan argumen kata kunci ke panggilan `json.dumps()` digunakan untuk membangkitkan tanggapan.
- `BrokenLinkEmailsMiddleware` sekarang mengabaikan 404 ketika pengarah setara pada URL yang diminta. Untuk mengelak pemeriksaan pengarah kosong sudah diterapkan, beberapa Web bot menyetel pengarah ke URL diminta.

#### Templat

- Etiket cetakan dibuat dengan pembantu `simple_tag()` sekarang dapat menyimpan hasil dalam sebuah variabel cetakan dengan menggunakan argumen `as`.
- Ditambahkan sebuah metode `Context.setdefault()`.
- Pencatat :ref:`django.template <django-template-logger> telah ditambahkan dan menyertakan pesan berikut:
  - Pesan tingkatan `DEBUG` untuk konteks variabel hilang.
  - Sebuah peringatan tingkat `WARNING` untuk pengecualian tidak tertangkap dimunculkan selama membangun dari sebuah `{% include %}` ketika suasana mencari kesalahan mati (sangat membantu sejak `{% include %}` mendiamkan pengecualian dan mengembalikan sebuah string kosong).
- Etiket cetakan `firstof` mengukung menyimpan keluaran di sebuah variabel menggunakan 'as'.
- `Context.update()` sekarang dapat digunakan sebagai pengelola konteks.
- Pemuat cetakan Django sekarang dapat memperpanjang cetakan berulang.
- The debug page template postmortem now include output from each engine that is installed.
- Debug page integration untuk penyesuaian mesin cetakan telah ditambahkan.
- Backend `DjangoTemplates` mendapatkan kemampuan untuk mendaftarkan pustaka dan siap pakai secara eksplisit melalui cetakan `OPTIONS`.
- Penyaring `timesince` dan `timeuntil` telah diperbaiki untuk berurusan dengan tahun kabisat ketika diberikan jangkauan waktu yang besar.
- Etiket `include` sekarang menyimpan sementara objek cetakan diurai selama membangun cetakan, mempercepat penggunaan kembali seperti untuk perulangan.

#### Pengujian

- Ditambahkan metode `json()` pada tanggapan klien percobaan untuk memberikan akses ke tanggapan badan sebagai JSON.
- Ditambahkan metode `force_login()` ke klien percobaan. Gunakan metode ini untuk merangsang pengaruh dari pengguna masuk kedalam situs selagi melewati langkah-langkah otentifikasi dan pemeriksaan dari `login()`.

#### URL

- Pernyataan melihat-lihat regular expression sekarang diizinkan di pola URL
- Namespace aplikasi sekarang dapat disetel menggunakan sebuah atribut `app_name` pada modul atau obyek disertakan. Itu juga dapat disetel dengan melewatkan 2-tuple dari (<list of patterns>, <application namespace>) sebagai argumen pertama pada `include()`.
- Pemeriksaan sistem telah ditambahkan untuk kesalahan corak URL umum.

#### Pengesah

- Ditambahkan `django.core.validators.int_list_validator()` untuk membangkitkan pengesah dari string mengandung integer terpisah dengan penyesuaian karakter.
- `EmailValidator` sekarang membatasi panjang dari label nama ranah menjadi 63 karakter per RFC 1034.
- Ditambahkan `validate_unicode_slug()` untuk mensahkan siput yang mungkin mengandung karakter Unicode.

## Perubahan bertentangan kebelakang di 1.9

Peringatan

Sebagai tambahan pada uraian berubah di bagian ini, pastikan meninjau Fitur-fitur dipindahkan di 1.9 untuk fitur yang telah mencapai akhir dari siklus pengusangan mereka dan karena itu telah dipindahkan. Jika anda belum memperbaharui kode anda dalam linimasa pengusangan untuk fitur diberikan, perpindahan ini mungkin muncul sebagai perubahan ketidaksesuaian kebelakang.

### API backend basisdata

- Sepasang percobaan baru bergantung pada kemampuan dari backend untuk mengintrospeksi kolom awalan (mengembalikan hasil sebagai `Field.default`). Anda dapat menyetel fitur basisdata `can_introspect_default` menjadi `False` jika backend anda tidak menerapkan ini. Anda mungkin ingin meninjau penerapan pada backend yang Django sertakan untuk acuan (#24245).

- Mendaftarkan penyadur global atau perubah pada tingkat dari modul API-DB untuk menangani informasi zona waktu dari nilai-nilai `datetime` dilewatkan sebagai parameter permintaan atau dikembalikan sebagai hasil permintaan di basisdata yang tidak mendukung zona waktu adalah kecil. Itu dapat bertentangan dengan pustaka-pustaka lain.

  Cara yang dianjurkan untuk menambah zona waktu ke nilai-nilai `datetime` diambil dari basisdata adalah mendaftarkan perubah untuk `DateTimeField` di `DatabaseOperations.get_db_converters()`.

  Fitur basisdata `needs_datetime_string_cast` telah dipindahkan. Backend basisdata yang disetel harus mebdaftarkan perubah sebagai gantinya, seperti dijalankan diatas.

- Metode `DatabaseOperations.value_to_db_<type>()` telah dinamai menjadi `adapt_<type>field_value()` untuk mencerminkan metode `convert_<type>field_value()`.

- Untuk menggunakan pencarian `date` baru, backend basisdata pihak-ketiga mungkin butuh menerapkan metode ``DatabaseOperations.datetime_cast_date_sql()`.

- Metode `DatabaseOperations.time_extract_sql()``telah ditambahkan. Dia memanggil metode ``date_extract_sql()` yang ada. Metode ini ditimpan oleh backend SQLite untuk menambah waktu pencarian (jam, menit, detik) pada `TimeField`, dan mungkin dibutuhkan oleh backend basisdata pihak-ketiga.

- Metode `DatabaseOperations.datetime_cast_sql()` (jangan bingung dengan `DatabaseOperations.datetime_cast_date_sql()` disebutkan diatas) telah dipindahkan. Metode ini melayani untuk membentuk tanggal pada Oracle jauh sebelum 1.0, tetapi itu belum ditimpa oleh backend inti apapun bertahun-tahun dan belum dipanggil dimanapun di kode Django atau percobaan.

- Untuk mendukung paralelisasi percobaan, anda harus menerapkan metode `DatabaseCreation._clone_test_db()` dan setel `DatabaseFeatures.can_clone_databases = True`. Anda mungkin harus menyesuaikan `DatabaseCreation.get_test_db_clone_settings()`.

### Pengaturan awalan yang dimana tuple adalah sekarang daftar.

Pengaturan awalan di `django.conf.global_settings` dipadukan dari daftar dan tuple. Semua pengaturan yang sebelumnya tuple sekarang adalah daftar.

### Atribut `is_usable` pada pemuat cetakan dipindahkan

Pemuat cetakan Django sebelumnya membutuhkan sebuah atribut `is_usable` untuk ditentukan. Jika sebuah pemuat dikonfigurasikan di pengaturan cetakan dan atribut ini adalah `False`, pemuat akan secara diam mengabaikan. Dalam praktiknya, ini hanya digunakan oleh pemuat telur untuk mengenali jika alat pengaturan telah dipasang. Atribut `is_usable` sekarang dipindah dan pemuat telur sebagai gantinya gagal pada waktu jalan jika alat pengaturan tidak dipasang.

### Kumpulan terkait penetapan langsung

Penugasan langsung dari objek terkait di ORM digunakan untuk melakukan `clear()` diikuti oleh sebuah panggilan pada `add()`. Ini menyebabkan sia-sia perubahan data besar dan dicegah menggunakan sinyal `m2m_changed` untuk melacak perubahan individu di hubungan many-to-many.

Penugasan langsung sekarang bergantung pada metode `set()` baru pada pengelola terkait yang secara awalan hanya mengolah perubahan diantara setelan terkait yang ada dan satu yang baru ditugaskan. Perilaku sebelumnya dapat dipulihkan dengan mengganti penugasan langsung dengan sebuah panggilan pada `set()` dengan argumen kata kunci `clear=True`.

`ModelForm`, dan oleh karena itu `ModelAdmin`, secara internal bergantung pada penugasan langsung untuk hubungan many-to-many dan sebagai sebuah konsekuensi sekarang menggunakan perilaku baru.

### Pemuat cetakan berdasarkan sistem berkas menangkap lebih pengecualian tertentu

Ketika menggunakan pemuat cetakan `filesystem.Loader` atau `app_directories.Loader`, versi paling awal dari Django memunculkan sebuah kesalahan `TemplateDoesNotExist` jika sebuah sumber cetakan ada tetapi tidak dapat dibaca. Ini dapat terjadi dibawah banyak keadaan, seperti jika Django tidak mempunyai perizinan untuk membuka berkas, atau jika sumber cetakan adalah sebuah direktori. Sekarang, Django hanya mendiamkan pengecualian jika sumber cetakan tidak ada. Semua keadaan lain menghasilkan IOError` asli sedang dimunculkan.

### Pengalihan HTTP tidak lagi memaksa ke URI mutlak

Pengalihan relatif tidak lagi dirubah ke URI mutlak. RFC 2616 membutuhkan kepala `Location` di tanggapan pengalihan menjadi URI mutlak, tetapi itu telah digantikan oleh RFC 7231 yang mengizinkan URI relatif dalam `Location`, mengenali praktik sebenarnya dari agen pengguna, kebanyakan semua dari yang mendukung mereka.

Karena itu, URL diharapkan dilewatkan ke `assertRedirects` harus seara umum tidak lagi menyertakan skema dan bagian ranah dari URL. Sebagai contoh, `self.assertRedirects(response, 'http://testserver/some-url/')` harus diganti dengan `self.assertRedirects(response, '/some-url/')` (meskipun pengalihan secara khusus mengandung sebuah URL mutlak, tentu saja).

Dalam kasus yang jarang bahwa anda butuh perilaku lama (ditemukan dengan versi lama dari Apache dengan `mod_wsgi` yang menterjemahkan pengalihan relatif sebagai sebuah "internal redirect"), anda dapat memulihkan itu dengan menulis penyesuaian middleware:

    class LocationHeaderFix(object):
        def process_response(self, request, response):
            if 'Location' in response:
                response['Location'] = request.build_absolute_uri(response['Location'])
            return response

### Dukungan dibuang untuk PostgreSQL 9.0

Dukungan hulu untuk PostgreSQL 9.0 berakhir di September 2015. Sebagai konsekuensinya, Django 1.9 menyetel PostgreSQL 9.1 sebagai versi minimal dia secara resmi dukung.

### Dukungan dibuang untuk Oracle 11.1

Dukungan hulu untuk PostgreSQL 11.1 berakhir di Agustus 2015. Sebagai konsekuensinya, Django 1.9 menyetel PostgreSQL 11.2 sebagai versi minimal Oracle secara resmi dukung.

### Perilaku dalam jumlah besar dari metode `add()` dari pengelola terkait

Untuk memperbaiki penampilan, metode `add()` dari pengelola terkait dibuat oleh `ForeignKey` dan `GenericForeignKey` berubah dari rangkaian dari `Model.save()` panggilan ke satu panggilan `QuerySet.update()` tunggal. Perubahan berarti bahwa sinyal `pre_save` dan `post_save` tidak dikirm lagi. Anda dapat menggunakan argumen kata kunci `bulk=False` untuk kembali ke perilaku sebelumnya.

### Cetakan `LoaderOrigin` dan `StringOrigin` dipindahkan

Di versi sebelumnya dari Django, ketika mesin cetakan diinisialisasikan dengan mencari kesalahan sebagai `True`, sebuah instance dari `django.template.loader.LoaderOrigin` atau `django.template.base.StringOrigin` disetel sebagai atribut asli di obyek cetakan. Kelas-kelas ini telah dipadukan kedalam `Origin` dan sekarang selalu disetel tanpa memperhatikan dari pengaturan mesin mencari kesalahan. Untuk tingkat minimal dari kesesuaian kebelakang, nama-nama kelas lama akan disimpan sebagai nama lain ke kelas `Origin` baru sampai Django 2.0.

### Perubahan pada konfigurasi pencatatan awalan

Untuk membuatnya lebih mudah menulis penyesuaian konfigurasi pencatatan, konfigurasi pencatatan awalan Django tidak lagi menentukan pencatat `django.request` dan `django.security`. Sebagai gantinya, itu menentukan pencatat `django` tunggal, disaring pada tingkat `INFO`, dengan dua penangan:

- `console`: disaring di tingkat `INFO` dan hanya aktif jika `DEBUG=True`.
- `mail_admins`: disaring di tingkat `ERROR` dan hanya aktif jika `DEBUG=True`.

Jika anda tidak menimpa pencatat awalan Django, anda harus melihat minimal perubahan di perilaku, tetapi anda mungkin melihat beberapa pencatatan baru pada konsol `runserver`, sebagai contoh.

Jika anda menimpa pencatat awalan Django, anda harus memeriksa untuk melihat bagaimana konfigurasi anda bergabung dengan awalan baru.

### Rincian `HttpRequest` dalam pelaporan kesalahan

Itu berlebihan menampilkan rincian penuh dari `HttpRequest` setiap kali itu muncul sebagai variabel tumpukan bingkai dalam versi HTML dari halaman mencari kesalahan dan kesalahan surel. Dengan demikian, permintaan HTTP akan sekarang menampilkan perwakilan standar sama seperti variabel lain, (`repr(request)`). Hasilnya, metode `ExceptionReporterFilter.get_request_repr()` dan tidak terdokumentasi fungsi `django.http.build_request_repr()` dipindahkan.

Isi dari versi teks dari surel dirubah untuk menyediakan jejak kebelakang dari struktur sama seperti dalam kasus permintaan AJAX. Rincian jejak kebelakang dibangun oleh metode `ExceptionReporter.get_traceback_text()`.

### Pemindahan dari sadar zona waktu penyadur global dan perubah untuk datetime

Django tidak lagi mendaftarkan penyadur global dan perubah untuk mengelola informasi zona waktu pada nilai-nilai `datetime` dikirim ke basisdata sebagai permintaan parameter atau membaca dari basisdata dalam hasil permintaan. Perubahan ini mempengaruhi proyek yang memenuhi semua kondisi berikut:

- Pengaturan `USE_TZ` adalah `True`.
- Basisdata adalah SQLite, MySQL, Oracle, atau sebuah basisdata pihak-ketiga yang tidak mendukung zona waktu. Dalam keraguan, anda dapat memeriksa nilai dari `connection.features.supports_timezones`.
- Kode meminta basisdata diluar dari ORM, khususnya dengan `cursor.execute(sql, params)`.

Jika anda sedang melewatkan parameter `datetime` kesadaran ke permintaan tersebut, anda harus merubah mereka menjadi datetime yang tidak dibuat-buat di UTC.

    from django.utils import timezone
    param = timezone.make_naive(param, timezone.utc)

Jika anda gagal untuk melakukannya, perubahan akan dilakukan seperti di versi paling awal (dengan peringatan pengusangan) sampai Django 1.11. Django 2.0 tidak akan melakukan perubahan apapun, yang mungkin menghasilkan di kerusakan data.

Jika anda sedang membaca nilai-nilai `datetime` dari hasil, mereka akan menjadi tidak dibuat-buat daripada sadar. Anda dapat mengimbangi sebagai berikut:

    from django.utils import timezone
    value = timezone.make_aware(value, timezone.utc)

Anda tidak memerlukan semua ini jika anda sedang meminta basisdata melalui ORM, bahkan jika anda sedang menggunakan permintaan `raw()`. ORM merawat pengelolaan informasi zona waktu.

### Modul etiket cetakan diimpor ketika cetakan sedang dikonfigurasikan

Backend `DjangoTemplates` sekarang melakukan penemuan pada modul etiket cetakan terpasang ketika diinstasiasikan. Perbaharuan ini mengadakan pustaka untuk disediakan jelas melalui kuncu `'libraries'` dari `OPTIONS` ketika menentukan sebuah backend `DjangoTemplates` . Impor atau kesalahan sintaksis dalam modul etiket cetakan sekarang gagal awal pada waktu instasiasi daripada ketika sebuah cetakan dengan sebuah etiket `{% load %}` adalah pertama yang disusun.

### `django.template.base.add_to_builtins()` dipindahkan

Meskipun itu adalah API pribadi, proyek umumnya menggunakan `add_to_builtins()` untuk membuat etiket cetakan dan ketersedian penyaring tanpa menggunakan etiket `{% load %}`. API ini telah dirumuskan. Proyek harus sekarang menentukan pustaka siap-pakai melalui kunci `'builtins'` dari `OPTIONS` ketika menentukan backend `DjangoTemplates`.

### `simple_tag` sekarang membungkus etiket keluaran di `conditional_escape`

Secara umum, etiket cetakan tidak meloloskan otomatis isi mereka, dan perilaku ini adalah documented. Untuk etiket-etiket seperti `inclusion_tag`, ini adalah bukan sebuah masalah karena cetakan disertakan akan melakukan pelolosan otomatis. Untuk `assignment_tag()`, keluaran akan diloloskan ketika itu adalah digunakan sebagai sebuah variabel di cetakan.

Untuk kasus-kasus penggunaan yang diharapkan dari `simple_tag`, bagaimanapun, itu adakah mudah mengakhiri dengan HTML yang tidak benar dan kemungkinan sebuah serangan XSS. Sebagai contoh:

    @register.simple_tag(takes_context=True)
    def greeting(context):
        return "Hello {0}!".format(context['request'].user.first_name)

Di versi terlama dari Django, ini akan menjadi masalah XSS karena `user.first_name` tidak diloloskan.

Di Django 1.9, ini diperbaiki: jika konteks cetakan mempunyai `autoescape=True` setel (awal) kemudian `simple_tag` akan membungkus keluaran dari fungsi etiket dengan `conditional_escape()`.

Untuk memperbaiki `simple_tag` anda, itu adalah terbaik untuk memberlakukan praktik berikut:

- Kode apapun yang membangkitkan HTML harus menggunakan salah satu sistem cetakan atau `format_html()`.
- Jika keluaran dari `simple_tag` butuh meloloskan, gunakan `escape()` atau `conditional_escape()`.
- Jika anda benar-benar yakin bahwa anda sedang mengeluarkan HTML dari sumber terpercaya (sebagai contoh bidang CMS yang menyimpan HTML dimasukkan oleh admin), anda dapat menandai itu saja menggunakan `mark_safe()`.

Etiket yang mengikuti aturan ini akan benar dan aman apakah mereka mereka berjalan di Django 1.9+ atau paling awal.

### `Paginator.page_range`

`Paginator.page_range` sekarang sebuah perulangan daripada sebuah daftar.

Di versi dari Django sebelum 1.8, `Paginator.page_range` mengembalikan sebuah `list` di Python 2 dan `range` di Python 3. Django 1.8 terus-menerus mengembalikan sebuah daftar, tetapi sebuah perulang adalah lebih efesien.

Kode yang ada yang bergantung pada fitus khusus `list`, seperti pengindeksan, dapat dihubungkan dengan merubah perulang kedalam sebuah `list` menggunakan `list()`.

### `QuerySet` tersirat `__in` pencarian dipindahkan

Di versi paling awal, permintaan seperti:

    Model.objects.filter(related_id=RelatedModel.objects.all())

akan tidak langsung berubah ke:

    Model.objects.filter(related_id__in=RelatedModel.objects.all())

mengembalikan dalam SQL seperti `"related_id IN (SELECT id FROM ...)"`.

Tersirat `__in` ini tidak lagi terjadi jadi "IN" SQL adalah sekarang "=", dan jika sub permintaan mengembalikan hasil banyak, setidaknya beberapa basisdata akan melempar sebuah kesalahan.

### Dukungan perambah `contrib.admin`

Admin tidak lagi mendukung Internet Explorer 8 dan dibawah, ketika peramban ini telah mencapai akhir-dari-hidup.

CSS dan gambar untuk mendukung Internet Explorer 6 dan 7 telah dipindahkan. Ikon PNG dan GIF telah diganti dengan ikon SVG, yang tidak didukung oleh Internet Explorer 8 dan sebelumnya.

Pustaka jQuery ditanam di admin telah ditingkatkan dari versi 1.11.2 ke 2.1.4. jQuery 2.x mempunyai API sama seperti jQuery 1.x, tetapi tidak mendukung Internet Explorer 6, 7, or 8, mengizinkan untuk penampilan lebih baik dan ukuran berkas lebih kecil. Jika anda butuh mendukung IE8 dan harus juga menggunakan versi terakhir dari Django, anda dapat menimpa salinan admin dari jQuery dengan milik anda dengan membuat aplikasi Django dengan struktur ini:

    app/static/admin/js/vendor/
        jquery.js
        jquery.min.js

### `SyntaxError` ketika memasang alat penyetelan Django 5.5.x

Ketika memasang Django 1.9 atau 1.9.1 dengan alat penyetelan 5.5.x, anda akan melihat:

    Compiling django/conf/app_template/apps.py ...
      File "django/conf/app_template/apps.py", line 4
        class {{ camel_case_app_name }}Config(AppConfig):
              ^
    SyntaxError: invalid syntax

    Compiling django/conf/app_template/models.py ...
      File "django/conf/app_template/models.py", line 1
        {{ unicode_literals }}from django.db import models
                                 ^
    SyntaxError: invalid syntax

Itu aman mengabaikan kesalahan-kesalahan ini (Django akan masih memasang baik-naik saja), tetapi anda dapat menghindari mereka dengan meningkatkan alat penyetelan ke versi paling saat ini. Jika anda sedang menggunakan pip, anda dapat meningkatkan menggunakan `pip install -U pip` yang akan juga meningkatkan alat penyetelan. Ini akan diselesaikan di versi nanti dari Django seperti digambarkan di Catatan terbitan Django 1.9.2.

### Bermacam-macam

- Berkas-berkas tetap jQuery di `contrib.admin` telah dipindahkan kedalam subdirektori `vendor/jquery`.
- Teks ditampilkan untuk kolom null di daftar rubah admin sel-sel `list_display` telah berubah dari `(None)` (atau terjemahannya setara) menjadi `-` (sebuah tanda garis).
- `django.http.responses.REASON_PHRASES` dan `django.core.handlers.wsgi.STATUS_CODE_TEXT` telah dipindahkan. Gunakan stdlib Python sebagai gantinya: `http.client.responses` untuk Python 3 dan httplib.responses untuk Python 2.
- `ValuesQuerySet` dan `ValuesListQuerySet` telah dipindahkan.
- Cetakan `admin/base.html` tidak lagi menyetel `window.__admin_media_prefix__` atau `window.__admin_utc_offset__`. Acuan gambar di JavaScript yang menggunakan nilai itu untuk membangun URL mutlak telah dipindahkan ke CSS untuk penyesuaian yang lebih mudah. Perimbangan UTC disimpan pada sebuah atribut data dari etiket `<body>`.
- Pengesahan `CommaSeparatedIntegerField` telah diolah untuk melarang nilai-nilai seperti `','`, `',1'`, dan `'1,,2'`.
- Inisialisasi formulir telah dipindahkan dari metode `ProcessFormView.get()` ke metode `FormMixin.get_context_data()` baru. Ini mungkin ketidaksesuaian kebelakang jika anda telah menimpa metode `get_context_data()` tanpa memanggil `super()`.
- Dukungan untuk PostGIS 1.5 telah dibuang.
- Bidang `django.contrib.sites.models.Site.domain` telah dirubah menjadi `unique`.
- Untuk memaksa pengasingan percobaan, permintaan basisdata tidak diizinkan secara awalan di percobaan `SimpleTestCase` lagi. Anda dapat meniadakan perilaku ini dengan mengatur atribut kelas `allow_database_queries` menjadi `True` pada kelas percobaan anda.
- `ResolverMatch.app_name` telah dirubah untuk mengandung jalur namespace penuh dalam aksus dari namespace bersarang. Untuk kemantapan dengan `ResolverMatch.namespace`, nilai kosong adalah sekarang sebuah string kosong sebagai gantinya `None`.
- Untuk memperkeras keamanan, kunci sesi harus setidaknya 8 karakter.
- Fungsi pribadi `django.utils.functional.total_ordering()` telah dipindahkan. Itu mengandung sebuah pemecahan untuk kesalahan `functools.total_ordering()` di Python versi lebih lama dari 2.7.3.
- Serialisasi XML (antara melalui `dumpdata` atau the syndication framework) digunakan untuk mengeluarkan karakter apapun itu terima. Sekarang jika isi untuk diserialisasikan mengandung karakter kendali apapun tidak diizinkan di standar XML 1.0, serialisasi akan gagal dengan sebuah `ValueError`.
- `CharField` sekarang mengupas masukan dari awalan dan buntutan ruang kosong secara awalan. Ini dapat ditiadakan dengan mengatur argumen `strip` baru menjadi `False`.
- Teks cetakan yang diterjemahkan dan menggunakan dua atau lebih tanda persen berurutan, sebagai contoh `"%%"`, mungkin mempunyai msgid baru setelah `makemessages` dijalankan (yang paling disukai terjemahan akan ditandai tidak jelas). `msgid` baru akan ditandai `"#, python-format"`.
- Jika tidak ada `request.current_app` maupun `Context.current_app` disetel, etiket cetakan `url` akan sekarang menggunakan namespace dari permintaan saat ini. Setel `request.current_app` menjadi `None` jika anda tidak ingin menggunakan petunjuk namespace.
- Pengaturan `SILENCED_SYSTEM_CHECKS` sekarang pesan diam dari semua tingkatan. Sebelumnya, pesan dari tingkat `ERROR` atau lebih tinggi dicetak ke konsol.
- Bidang `FlatPage.enable_comments` dipindahkan dari `FlatPageAdmin` ketika itu tidak digunakan oleh aplikasi. Jika proyek anda atau aplikasi pihak-ketiga menggunakannya, create a custom ModelAdmin untuk menambahkan itu kembali.
- Nilai kembalian dari `setup_databases()` dan argumen pertama dari `teardown_databases()` berubah. Mereka dulu tuple `(old_names, mirrors)`. Sekarang mereka hanya barang pertama, `old_names`.
- Secara awalan `LiveServerTestCase` berusaha menemukan port tersedia di jangkauan 8081-8179 sebagai gantinya dari hanya mencoba port 8081.
- Sistem pemeriksaan untuk `ModelAdmin` sekarang memeriksa instance daripada kelas-kelas.
- API pribadi untuk memberlakukan rencana perpindahan campuran telah dibuang untuk alasan penampilan. Perpindahan campuran terdiri dari sebuah daftar perpindahan dimana beberapa sedang diberlakukan dan lainnya tidak diberlakukan.
- Kelas-kelas penggambar obyek yang terkait di `django.db.models.fields.related` (API pribadi) dipindahkan dari modul `related` ke `related_descriptors` dan dinamai sebagai berikut:
  - ReverseSingleRelatedObjectDescriptor` adalah `ForwardManyToOneDescriptor`
  - `SingleRelatedObjectDescriptor` adalah `ReverseOneToOneDescriptor`
  - `ForeignRelatedObjectsDescriptor` adalah `ReverseManyToOneDescriptor`
  - `ManyRelatedObjectsDescriptor` adalah `ManyToManyDescriptor`
- Jika anda menerapkan sebuah penyesuaian tampilan `handler404`, itu harus mengembalikan sebuah tanggapan dengan kode keadaan HTTP 404. Gunakan `HttpResponseNotFound` atau lewatkan `status=404` ke `HttpResponse`. Jika tidak `APPEND_SLASH` tidak akan bekerja dengan benar dengan `DEBUG=False`.

## Fitur usang di 1.9

### `assignment_tag()`

Django 1.4 menambahkan pembantu `assignment_tag` untuk memudahkan pembuatan dari etiket cetakan tang menyimpan hasil di variabel cetakan. Pembantu `simple_tag()` telah mendapatkan kemampuan sama ini, membuat `assignment_tag` usang. Etiket yang menggunakan `assignment_tag` harus diperbaharui untuk menggunakan `simple_tag`.

### Sintaksis {% cycle %}` dengan argumen dipisah-koma

Etiket `cycle` mendukung sintaksis lama rendah dari versi Django sebelumnya:

    {% cycle row1,row2,row3 %}

Penguraiannya menyebabkan kesalahan dengan sintaksis saat ini, jadi dukungan untuk sintaksis lama akan dipindahkan di Django 1.10 mengikuti percepatan pengusangan.

### Argumen `ForeignKey` dan `OneToOneField` `on_delete`

Untuk meningkatkan kesadaran tentang penghapusan model ke bawah, argumen `on_delete` dari `ForeignKey` dan `OneToOneField` akan diwajibkan di Django 2.0.

Model diperbaharui dan perpindahan yang ada untuk jelasnya menyetel argumen. Sejak awalan adalah `models.CASCADE`, tambah `on_delete=models.CASCADE` untuk semua `ForeignKey` dan `OneToOneField` yang tidak menggunakan pilihan berbeda. Anda dapat juga melewatkannya sebagai argumen penemparan kedua jika anda tidak peduli tentang penyesuaian dengan versi terlama dari Django

### `Field.rel` berubah

`Field.rel` dan metode dan atributnya telah berubah untuk mencocokkan API bidang terkait. Atribut `Field.rel` dinamai kembali menjadi `remote_field` dan banyak dari metodenya dan atribut baik dirubah atau dinamai kembali.

Tujuan dari perubahan ini adalah menyediakan sebuah dokumentasi API untuk hubungan bidang.

### Metode penyesuaian `GeoManager` dan `GeoQuerySet`

Semua penyesuaian metode `GeoQuerySet` (`area()`, `distance()`, `gml()`, ...) telah diganti oleh pernyataan geografis yang setara di keterangan (lihat di fitur baru). Dengan demikian kebutuhan untuk menyetel sebuah penyesuaian `GeoManager` ke model diadakan-GIS sekarang usang. Segera setelah kode anda tidak memanggil setiap dari metode digusangkan, anda dapat cukup memindahkan baris `objects = GeoManager()` dari model anda.

### Pemuat cetakan API telah berubah

Pemuat cetakan Django telah diperbaharui untuk mengizinkan perpanjangan cetakan berulang. Perubahan ini mengharuskan sebuah API pemuat cetakan baru. Metode `load_template()` dan `load_template_sources()` lama sekarang diusangkan. Rincian tentang API baru dapat ditemukan in the template loader documentation.

### Melewatkan 3-tuple atau sebuah `app_name` pada `include()`

Bagian namespace instance dari melewatkan sebuah tuple sebagai sebuah argumen pada `include()` telah diganti dengan melewatkan argumen `namespace` pada `include()`. Sebagai contoh:

    polls_patterns = [
         url(...),
    ]

    urlpatterns = [
        url(r'^polls/', include((polls_patterns, 'polls', 'author-polls'))),
    ]

menjadi:

    polls_patterns = ([
         url(...),
    ], 'polls')  # 'polls' is the app_name

    urlpatterns = [
        url(r'^polls/', include(polls_patterns, namespace='author-polls')),
    ]

Argumen `app_name` pada `include()` telah diganti dengan melewatkan 2-tuple (seperti diatas), atau melewatkan sebuah obyek atau modul dengan sebuah atribut `app_name` (seperti dibawah). Jika `app_name` disetel di cara baru ini, argumen `namespace` tidak lagi dibutuhkan. Itu akan awalan pada nilai dari `app_name`. Sebagai contoh, pola URL di pengajaran tambahan berubah dari:

mysite/urls.py

    urlpatterns = [
        url(r'^polls/', include('polls.urls', namespace="polls")),
        ...
    ]

kepada:

mysite/urls.py

    urlpatterns = [
        url(r'^polls/', include('polls.urls')),  # 'namespace="polls"' removed
        ...
    ]

polls/urls.py

    app_name = 'polls'  # added
    urlpatterns = [...]

Perubahan ini juga berarti bahwa cara lama dari menyertakan sebuah instance `AdminSite` adalah diusangkan. Sebagai gantinya, lewatkan `admin.site.urls` secara langsung ke `url()`:

urls.py

    from django.conf.urls import url
    from django.contrib import admin

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
    ]

### Namespace aplikasi URL diwajibkan jika mengatur sebuah namespace instance

Di masa lalu, namespace instance tanpa sebuah namespace aplikasi akan melayani tujuan yang sama sebagai namespace aplikasi, tetapi itu tidak mungkin membalikkan pola jika ada sebuah namespace aplikasi dengan nama sama. Termasuk yang menentukan sebuah namespace instance mewajibkan itu termasuk URLconf menyetel sebuah namespace aplikasi.

### Parameter `current_app` pada tampilan `contrib.auth`

Semua tampilan di `django.contrib.auth.views` mempunyai struktur berikut:

    def view(request, ..., current_app=None, ...):

        ...

        if current_app is not None:
            request.current_app = current_app

        return TemplateResponse(request, template_name, context)

Pada Django 1.8, `current_app` disetel pada obyek `request`. Untuk kemantapan, tampilan ini akan membutuhkan pemanggil untuk menyetel `current_app` pada `request` sebagai gantinya dari melewatkan itu di argumen terpisah.

### `django.contrib.gis.geoip`

Modul `django.contrib.gis.geoip2` menggantikan `django.contrib.gis.geoip`. Modul baru menyediakan API mirip kecuali bahwa itu tidak menyediakan warisan metode kesesuaian API Python-GeoIP.

### Bermacam-macam

- Argumen `weak` pada `django.dispatch.signals.Signal.disconnect()` telah diusangkan karena itu tidak mempunyai pengaruh.
- Metode `check_aggregate_support()` dari `django.db.backends.base.BaseDatabaseOperations` telah diusangkan dan akan dipindahkan di Django 2.0. `check_expression_support()` yang lebih umum harus digunakan sebagai gantinya.
- `django.forms.extras` diusangkan. Anda dapat menemukan `SelectDateWidget` di `django.forms.widgets` (atau cukup `django.forms`) sebagai gantinya.
- API pribadi `django.db.models.fields.add_lazy_relation()` diusangkan,
- Penghias `django.contrib.auth.tests.utils.skipIfCustomUser()` diusangkan. Dengan perubahan penemuan percobaan di Django 1.6, percobaan untuk aplikasi `django.contrib` tidak lagi berjaan sebagai bagian dari proyek pengguna. Karena itu, penghias `@skipIfCustomUser` tidak lagi dibutuhkan untuk menghias percobaan di `django.contrib.auth`.
- Jika anda menyesuaikan beberapa error handlers, tanda tangan tampilan dengan hanya satu parameter permintaan diusangkan. Tampilan harus sekarang juga menerima parameter penempatan `exception` kedua.
- Atribut `django.utils.feedgenerator.Atom1Feed.mime_type` dan `django.utils.feedgenerator.RssFeed.mime_type` diusangkan dalam mendukung `content_type`.
- `Signer` sekarang menerbitkan sebuah peringatan jika sebuah pemisah tidak sah digunakan. Ini akan menjadi sebuah pengecualian di Django 1.10.
- `django.db.models.Field._get_val_from_obj()` diusangkan dalam mendukung `Field.value_from_object()`.
- `django.template.loaders.eggs.Loader` diusangkan ketika penyaluran aplikasi sebagai telur adalah tidak dianjurkan.
- Arumen kata kunci `callable_obj` pada `SimpleTestCase.assertRaisesMessage()` diusangkan. Lewatkan dapat dipanggil sebagai argumen penempatan sebagai gantinya.
- Atribut `allow_tags` di metode dari `ModelAdmin` telah diusangkan. Gunakan `format_html()`, `format_html_join()`, atau `mark_safe()` ketika membangun nilai kembali metode sebagai gantinya.
- Argumen kata kunci `enclosure` pada `SyndicationFeed.add_item()` diusangkan. Gunakan argumen `enclosures` baru yang menerima sebuah daftar obyek `Enclosure` sebagai gantinya yang satu.
- Nama lain `django.template.loader.LoaderOrigin` and `django.template.base.StringOrigin` untuk `django.template.base.Origin` diusangkan.

## Fitur-fitur dipindahkan di 1.9

Fitur-fitur ini telah mencapai akhir siklus pengusangan mereka dan dipindahkan di Django 1.9. Lihat Fitur usang di 1.7 untuk rincian, termasuk bagaimana memindahkan penggunaan fitur ini.

- `django.utils.dictconfig` dipindahkan.
- `django.utils.importlib` dipindahkan
- `django.utils.tzinfo` dipindahkan.
- `django.utils.unittest` dipindahkan.
- Perintah `syncdb` dipindahkan.
- `django.db.models.signals.pre_syncdb` dan `django.db.models.signals.post_syncdb` dipindahkan.
- Dukungan untuk `allow_syncdb` pada perute basisdata dipindahkan.
- Menyeimbangkan otomatis dari aplikasi tanpa perpindahan adalah dipindahkan. Perpindahan adalah wajib untuk aplikasi meskipun anda melewatkan pilihan `migrate --run-syncdb`.
- Perintah pengelolaan SQL untuk aplikasi tanpa perpindahan, `sql`, `sqlall`, `sqlclear`, `sqldropindexes`, dan `sqlindexes`, dipindahkan.
- Dukungan untuk memuat otomatis dari alat bantu `initial_data` dan data SQL awal dipindahkan.
- Semua model-model butuh ditentukan dalam sebuah aplikasi terpasang atau menyatakan sebuah `app_label` yang jelas. Lebih lanjut, itu tidak memungkinkan mengimpor mereka sebelum aplikasi mereka dimuat. Khususnya, itu tidak memungkinkan mengimpor model-model didalam paket akar dari sebuah aplikasi.
- Model dan formulir `IPAddressField` dipindahkan. Sebuah bidang keong tetap untuk kesesuaian dengan riwayat perpindahan.
- `AppCommand.handle_app()` tidak lagi didukung.
- `RequestSite` dan `get_current_site()` tidak lagi dapat diimpor dari `django.contrib.sites.models`.
- Dukungan FastCGI melalui perintah pengleolaan `runfcgi` dipindahkan.
- `django.utils.datastructures.SortedDict` dipindahkan.
- `ModelAdmin.declared_fieldsets` dipindahkan.
- Modul-modul `util` yang disediakan kesesuaian kebelakang dipindahkan:
  - `django.contrib.admin.util`
  - `django.contrib.gis.db.backends.util`
  - `django.db.backends.util`
  - `django.forms.util`
- `ModelAdmin.get_formsets` dipindahkan.
- Shim kesesuaian kebelakang diperkenalkan untuk menamai kembali metode `BaseMemcachedCache._get_memcache_timeout()` pada `get_backend_timeout()` akan dipindahkan.
- Pilihan-pilihan `--natural` dan `-n` untuk `dumpdata` dipindahkan.
- Argumen `use_natural_keys` untuk `serializers.serialize()` dipindahkan.
- API pribadi `django.forms.forms.get_declared_fields()` dipindahkan.
- Kemampuan menggunakan `SplitDateTimeWidget` dengan `DateTimeField` dipindahkan.
- Sifat `WSGIRequest.REQUEST` dipindahkan.
- Kelas `django.utils.datastructures.MergeDict` dipindahkan.
- Kode bahasa `zh-cn` and `zh-tw` telah dipindahkan.
- Internal `django.utils.functional.memoize()` dipindahkan.
- `django.core.cache.get_cache` dipindahkan.
- `django.db.models.loading` dipindahkan.
- Melewatkan argumen callable ke queryset tidak lagi memungkinkan.
- `BaseCommand.requires_model_validation` dipindahkan dalam mendukung `requires_system_checks`. Pengesah admin diganti oleh pemeriksaan admin.
- Atribut `ModelAdmin.validator_class` dan `default_validator_class` dipindahkan.
- `ModelAdmin.validate()` dipindahkan.
- `django.db.backends.DatabaseValidation.validate_field` dipindahkan mendukung metode `check_field`.
- Perintah pengelolaan `validate` dipindahkan.
- `django.utils.module_loading.import_by_path` dipindahkan mendukung `django.utils.module_loading.import_string`.
- Etiket cetakan `ssi` dan `url` dipindahkan dari pustaka etiket cetakan `future`.
- `django.utils.text.javascript_quote()` dipindahkan.
- Pengaturan percobaan basisdata sebagai masukan berdiri sendiri dalam pengaturan basisdata, diawali oleh `TEST_`, tidak lagi didukung.
- cache_choices option to `ModelChoiceField` dan `ModelMultipleChoiceField` dipindahkan.
- Nilai awal dari atribut `RedirectView.permanent` telah dirubah dari `True` ke `False`.
- `django.contrib.sitemaps.FlatPageSitemap` dipindahkan mendukung `django.contrib.flatpages.sitemaps.FlatPageSitemap`.
- API pribadi `django.test.utils.TestTemplateLoader` dipindahkan.
- Modul `django.contrib.contenttypes.generic` dipindahkan.