# Dokumentasi Django 6.0.7

# Menghubungkan aplikasi anda dari Django 0.96 ke 1.0

Django 1.0 memutus kesesuaian dengan 0.96 di beberapa kawasan.

Panduan ini akan membantu anda menghubungkan proyek 0.96 dan apliaksi ke 1.0. Bagian pertama dari dokumen ini termasuk perubahan umum dibutuhkan untuk berjalan dengan 1.0. Jika setelah melalui bagian pertama kode anda masih rusak, periksa bagian Less-common Changes untuk daftar ikatan masalah kesesuaian yang kurang umum.

Lihat juga

1.0 release notes. Dokumen itu menjelaskan fitur-fitur baru di 1.0 lebih dalam; panduan menghubungkan lebih diperhatikan dengan bantuan anda dengan cepat memperbaharui kode anda.

## Perubahan umum

Bagian ini menggambarkan perubahan diantara 0.96 dan 1.0 yang paling pengguna butuhkan untuk dibuat.

### Gunakan Unicode

Merubah harfiah deretan karakter (`'foo'`) menjadi harfiah Unicode (`u'foo'`). Django sekarang menggunakan deretan karakter Unicode seluruhnya. Di kebanyakan tempat, deretan karakter mentah akan lanjut bekerja, tetapi memperbaharui untuk menggunakan harfiah Unicode akan mencegah pengaburan beberapa masalah.

Lihat Data Unicode untuk rincian penuh.

### Model

Perubahan umum ke berkas model anda:

#### Namai kembali `maxlength` ke `max_length`

Namai kembali argumen `maxlength` anda ke `max_length` (ini dirubah agar selaras dengan bidang-bidang formulir):

#### Ganti `__str__` dengan `__unicode__`

Ganti fungsi `__str__` model anda dengan metode `__unicode__`, dan pastikan anda use Unicode (`u'foo'`) di metode itu.

#### Pindahkan `prepopulated_from`

Pindahkan argumen `prepopulated_from` pada bidang model. Itu tidak lagi sah dan telah dipindahkan ke kelas `ModelAdmin` di `admin.py`. Lihat the admin, dibawah ini, untuk rincian lebih tentang dirubah ke admin.

#### Pindahkan `core`

Pindahkan argumen `core` dari bidang model anda. itu tidak lagi dibutuhkan, sejak kegunaan yang setara (bagian dari inline editing) ditangani dengan berbeda oleh antarmuka admin sekarang. Anda tidak harus khawatir tentang penyuntingan berderet sampai anda menuju bagian the admin, dibawah. Untuk sekarang, pindahkan semua acuan ke `core`.

#### Ganti `class Admin:` dengan `admin.py`

Pindahkan semua pernyataan `class Admin` sebelah dalam dari model anda. Mereka tidak merusak apapun jika anda meninggalkan mereka, tetapi mereka juga tidak akan melakukan apapun. Untuk mendaftarkan aplikasi dengan admin anda akan pindahkan pernyataan itu ke berkas `admin.py`; lihat the admin dibawah untuk lebih rinci.

Lihat juga

Seorang penyumbang pada djangosnippets telah menuli skembali sebuah tulisan yang akan scan your models.py and generate a corresponding admin.py.

#### Contoh

DIbawah ini adalah sebuah contoh berkas `models.py` dengan semua perubahan anda ingin buat:

Lama (0.96) `models.py`:

    class Author(models.Model):
        first_name = models.CharField(maxlength=30)
        last_name = models.CharField(maxlength=30)
        slug = models.CharField(maxlength=60, prepopulate_from=("first_name", "last_name"))

        class Admin:
            list_display = ["first_name", "last_name"]

        def __str__(self):
            return "%s %s" % (self.first_name, self.last_name)

Baru (1.0) `models.py`:

    class Author(models.Model):
        first_name = models.CharField(max_length=30)
        last_name = models.CharField(max_length=30)
        slug = models.CharField(max_length=60)

        def __unicode__(self):
            return "%s %s" % (self.first_name, self.last_name)

Baru (1.0) `admin.py`:

    from django.contrib import admin
    from models import Author

    class AuthorAdmin(admin.ModelAdmin):
        list_display = ["first_name", "last_name"]
        prepopulated_fields = {"slug": ("first_name", "last_name")}

    admin.site.register(Author, AuthorAdmin)

### Admin

Satu dari perubahan terbesar di 1.0 adalah admin baru. Antarmuka administratif Django (`django.contrib.admin`) telah sepenuhnya di refaktor; pengertian admin sekarang sepenuhnya dipisahkan dari pengertian model, kerangka kerja telah ditulis kembali untuk menggunakan pustaka penanganan formulir baru Django dan dirancang kembali dengan perpanjangan dan penyesuaian dalam pikiran.

Practically, this means you'll need to rewrite all of your `class Admin` declarations. You've already seen in models above how to replace your `class Admin` with an `admin.site.register()` call in an `admin.py` file. Below are some more details on how to rewrite that `Admin` declaration into the new syntax.

#### Gunakan sintaksis berderet yang baru

Pilihan `edit_inline` baru semua telah dipindahkan ke `admin.py`. Ini adalah contoh:

Lama (0.96):

    class Parent(models.Model): ...

    class Child(models.Model):
        parent = models.ForeignKey(Parent, edit_inline=models.STACKED, num_in_admin=3)

Baru (1.0):

    class ChildInline(admin.StackedInline):
        model = Child
        extra = 3

    class ParentAdmin(admin.ModelAdmin):
        model = Parent
        inlines = [ChildInline]

    admin.site.register(Parent, ParentAdmin)

Lihat Obyek InlineModelAdmin untuk rinci.

#### Sederhanakan `fields`, atau gunakan `fieldsets`

Sintaksis `fields` lama sangat membingungkan, dan telah disederhanakan. Sintaksis lama masih bekerja, tetapi anda akan butuh menggunakan `fieldsets` sebagai gantinya.

Lama (0.96):

    class ModelOne(models.Model):
        ...

        class Admin:
            fields = ((None, {"fields": ("foo", "bar")}),)

    class ModelTwo(models.Model):
        ...

        class Admin:
            fields = (
                ("group1", {"fields": ("foo", "bar"), "classes": "collapse"}),
                ("group2", {"fields": ("spam", "eggs"), "classes": "collapse wide"}),
            )

Baru (1.0):

    class ModelOneAdmin(admin.ModelAdmin):
        fields = ("foo", "bar")

    class ModelTwoAdmin(admin.ModelAdmin):
        fieldsets = (
            ("group1", {"fields": ("foo", "bar"), "classes": "collapse"}),
            ("group2", {"fields": ("spam", "eggs"), "classes": "collapse wide"}),
        )

Lihat juga

- Informasi lebih rinci mengenai perubahan dan alasan dibelakang mereka dapat ditemukan pada NewformsAdminBranch wiki page

- Admin baru datang dengan satu ton fitur baru; anda dapat membaca tentang mereka di admin documentation.

### URL

#### Perbaharui akar `urls.py` anda.

Jika anda menggunakan situs admin, anda butuh memperbaharui akar `urls.py` anda.

Lama (0.96) `urls.py`:

    from django.conf.urls.defaults import *

    urlpatterns = patterns(
        "",
        (r"^admin/", include("django.contrib.admin.urls")),
        # ... the rest of your URLs here ...
    )

Baru (1.0) `urls.py`:

    from django.conf.urls.defaults import *

    # The next two lines enable the admin and load each admin.py file:
    from django.contrib import admin

    admin.autodiscover()

    urlpatterns = patterns(
        "",
        (r"^admin/(.*)", admin.site.root),
        # ... the rest of your URLs here ...
    )

### View

#### Gunakan `django.forms` sebagai gantinya `newforms`

Ganti `django.newforms` dengan `django.forms` -- Django 1.0 dinamai kembali modul `newforms` (diperkenalkan di 0.96) untuk `forms` lama kosong. Modul `oldforms` juga dipindahkan.

Jika anda sudah menggunakan pustaka `newforms`, dan anda menggunakan anjuran kami sintaksis pernyataan `import`, semua anda harus lakukan adalah merubah pernyataan impor anda.

Lama:

    from django import newforms as forms

Baru:

    from django import forms

Jika anda sedang menggunakan sistem formulir lama (dahulu dikenal sebagai `django.forms` dan `django.oldforms`), anda akan harus menuli skembali formulir anda. Tempat bagus untuk memulai adalah forms documentation

#### Menangani berkas terunggah menggunakan API baru

Rubah penggunaan berkas-berkas terunggah -- yaitu, masukan di `request.FILES` -- sebagai kamus sederhana dengan `UploadedFile` baru. Sintaksis kamus lama tidak lagi bekerja.

Jadi, dalam tampilan seperti:

    def my_view(request):
        f = request.FILES["file_field_name"]
        ...

...anda butuh membuat perubahan berikut:

Lama (0.96) | Baru (1.0)
--- | ---
`f['content']` | `f.read()`
`f['filename']` | `f.name`
`f['content-type']` | `f.content_type`

#### Bekerja dengan bidang berkas menggunakan API baru

Penerapan internal dari `django.db.models.FileField` telah berubah. Hasil nampak dari ini adalah bahwa cara anda mengakses atribut khusus (URL, berkas nama, ukuran gambar, dll.) dari bidang model ini telah berubah. Anda akan butuh membuat perubahan berikut, menganggap `FileField` model anda dipanggil `myfile`:

Lama (0.96) | Baru (1.0)
--- | ---
`myfile.get_content_filename()` | `myfile.content.path`
`myfile.get_content_url()` | `myfile.content.url`
`myfile.get_content_size()` | `myfile.content.size`
`myfile.save_content_file()` | `myfile.content.save()`
`myfile.get_content_width()` | `myfile.content.width`
`myfile.get_content_height()` | `myfile.content.height`

Catat bahwa atribut `width` dan `height` hanya masuk akal untuk bidang `ImageField`. Rincian lebih dapat ditemukan di dokumentasi model API.

#### Gunakan `Paginator` daripada `ObjectPaginator`

`ObjectPaginator` di 0.96 telah dipindahkan dan diganti dengan versi diperbaiki, `django.core.paginator.Paginator`.

### Templat

#### Belajar mencintai pelolosan otomatis

Secara awal, sistem cetakan sekarang otomatis meloloskan HTML keluaran setiap variabel. Untuk mempelajari lebih, lihat Pelolosan HTML otomatis.

Untuk meniadakan pelolosan otomatis untuk variabel tersendiri, gunakan `safe` filter:

    This will be escaped: {{ data }}
    This will not be escaped: {{ data|safe }}

Untuk meniadakan pelolosan otomatis untuk keseluruhan cetakan, bungkus cetakan (atau cukup bagian tertentu dari cetakan) di etiket `autoescape`:

    {% autoescape off %}
       ... unescaped template content here ...
    {% endautoescape %}

## Perubahan kurang umum

Perubahan berikut lebih kecil, lebih perubahan lokal. Mereka hanya berpengaruh lebih pengguna lanjutan, tetapi itu mungkin bernilai baik membaca melalui daftar dan memeriksa kode anda untuk hal-hal ini.

### Sinyal

- Tambah `**kwargs` pada setiap penangan sinyal terdaftar.

- Hubungkan, putuskan, dan kirim sinyal melalui metode pada obyek `Signal` daripada melalui modul metode di `django.dispatch.dispatcher`.

- Pindahkan tiap penggunaan pilihan pengirim `Anonymous` dan `Any`; mereka tidak lagi ada. Anda masih dapat menerima sinyal dikirim oleh pengirim dengan menggunakan `sender=None`

- Buat sinyal penyesuaian apa saja anda telah nyatakan kedalam instance dari `django.dispatch.Signal` sebagai ganti dari obyek anonim.

Berikut rekap dari perubahan kode yang perlu anda lakukan:

Lama (0.96) | Baru (1.0)
--- | ---
`def callback(sender)` | `def callback(sender, **kwargs)`
`sig = object()` | `sig = django.dispatch.Signal()`
`dispatcher.connect(callback, sig)` | `sig.connect(callback)`
`dispatcher.send(sig, sender)` | `sig.send(sender)`
`dispatcher.connect(callback, sig, sender=Any)` | `sig.connect(callback, sender=None)`

### Komentar

Jika anda menggunakan aplikasi `django.contrib.comments` Django 0.96, anda akan btuuh meningkatkan ke aplikasi komentar baru diperkenalkan di 1.0. Lihat panduan peningkatan untuk rincian.

### Tag templat

#### Etiket `spaceless`

Template tag `spaceless` sekarang menghapus semua spasi diantara tag HTML, alih-alih mempertahankan satu buah spasi.

### Rasa lokal

#### Rasa lokal U.S

`django.contrib.localflavor.usa` telah dinamai kembali ke `django.contrib.localflavor.us`. Perubahan ini dibuat untuk mencocokan penamaan skema dari rasa lokal lainnya. Untuk memindahkan kode anda, anda yang butuh lakukan adalah merubah impor.

### Sesi

#### Mendapatkan kunci sesi baru

`SessionBase.get_new_session_key()` telah dinamai kembali menjadi `_get_new_session_key()`. `get_new_session_object()` tidak lagi ada.

### Perlengkapan

#### Memuat sebuah baris yang tidak memanggil `save()`

Sebelumnya, memuat sebuah baris secara otomatis menjalankan metode `save()` model. Ini bukan lagi kasus, jadi tiap bidang (sebagai contoh: timestamp) yang dikumpulkan otomatis oleh `save()` sekarang butuh nilai eksplisit di tiap perlengkapan tetap.

### Pengaturan

#### Pengecualian terbaik

`EnvironmentError` lama telah dipisah menjadi `ImportError` ketika Django gagal menemukan modul pengaturan dan `RuntimeError` ketika anda mencoba mengkonfigurasi kembali pengaturan setelah selesai menggunakan mereka.

#### `LOGIN_URL` telah dipindahkan

Ketetapan `LOGIN_URL` dipindah dari `django.contrib.auth` kedalam modul `settings`. Daripada menggunakan `from django.contrib.auth import LOGIN_URL` mengacu pada `settings.LOGIN_URL`.

#### Perilaku `APPEND_SLASH` telah diperbaharui

Di 0.96, jika sebuah URL tidak berakhir di garis miring atau mempunyai titik di akhir komponen dari jalurnya, dan `APPEND_SLASH` adalah True, Django akan mengalihkan ke URL sama, tetapi dengan tanda miring ditambahkan pada akhir. Sekarang, Django memeriksa apakah pola tanpa ekor garis miring akan cocok oleh sesuatu di pola URL anda. Jika demikian, tidak ada pengalihan, karena itu dianggap anda sengaja ingin menangkap pola itu.

Untuk kebanyakan orang, ini tidak akan membutuhkan perubahan. Beberapa orang, meskipun, mempunyai pola URL yang terlihat seperti ini:

    r"/some_prefix/(.*)$"

Sebelumnya, pola itu akan dialihkan untuk mempunyai sebuah ekor garis miring. Jika anda selalu ingin garis miring pada URL itu, tulis kembali pola sebagai:

    r"/some_prefix/(.*/)$"

### Perubahan model kecil

#### Pengecualian berbeda dari `get()`

Pengelola sekarang mengembalikan pengecualian `MultipleObjectsReturned` daripada `AssertionError`:

Lama (0.96):

    try:
        Model.objects.get(...)
    except AssertionError:
        handle_the_error()

Baru (1.0):

    try:
        Model.objects.get(...)
    except Model.MultipleObjectsReturned:
        handle_the_error()

#### `LazyDate` telah dinyalakan

Kelas pembantu `LazyDate` tidak lagi ada.

Nilai bidang awalan dan permintaan argumen keduanya obyek callable, jadi instance dari `LazyDate` dapat diganti dengan acuan pada `datetime.datetime.now`:

Lama (0.96):

    class Article(models.Model):
        title = models.CharField(maxlength=100)
        published = models.DateField(default=LazyDate())

Baru (1.0):

    import datetime

    class Article(models.Model):
        title = models.CharField(max_length=100)
        published = models.DateField(default=datetime.datetime.now)

#### `DecimalField` adalah baru, dan `FloatField` sekarang float tepat.

Lama (0.96):

    class MyModel(models.Model):
        field_name = models.FloatField(max_digits=10, decimal_places=3)
        ...

Baru (1.0):

    class MyModel(models.Model):
        field_name = models.DecimalField(max_digits=10, decimal_places=3)
        ...

Jika anda lupa membuat perubahan ini, anda akan melihat kesalahan tentang `FloatField` bukan mengambil atribut `max_digits` di `__init__`, karena `FloatField` baru mengambil argumen terkait tidak teliti.

Jika anda sedang menggunakan MySQL atau PostgreSQL, tidak dibtuuhkan perubahan lebih lanjut. Jenis kolom basisdata untuk `DecimalField` adalah sama untuk `FloatField` lama.

Jika anda menggunakan SQLite, anda butuh memaksa basisdata melihat kolom yang sesuai sebagai jenis desimal, daripada float. untuk melakukan ini, anda akan butuh memuat kembali data anda. Lakukam ini setelah anda membuat perubahan untuk menggunakan `DecimalField` di kode anda dan kode Django diperbaharui.

Peringatan

Sokong basisdata anda dahulu!

For SQLite, this means making a copy of the single file that stores the database (the name of that file is the `DATABASE_NAME` in your `settings.py` file).

Untuk meningkatkan setiap aplikasi untuk menggunakan sebuah `DecimalField`, anda dapat melakukan berikut, mengganti `<app>` di kode dibawah ini dengan setiap nama aplikasi:

    $ ./manage.py dumpdata --format=xml <app> > data-dump.xml
    $ ./manage.py reset <app>
    $ ./manage.py loaddata data-dump.xml

Catatan:

1. Itu sangat penting bahwa anda mengingat untuk menggunakan bentuk XML dalam langkah pertama dari pengolahan ini. Kami sedang menggunakan fitur dari data buangan XML yang membuat belokan float ke desimal dengan SQLite memungkinkan.

2. In the second step you will be asked to confirm that you are prepared to lose the data for the application(s) in question. Say yes; we'll restore this data in the third step.

3. `DecimalField` tidak digunakan di tiap aplikasi yang dibekali dengan Django sebelum perubahan ini dibuat, jadi anda tidak butuh khawatir tentang melakukan prosedur ini untuk tiap model Django standar.

Jika sesuatu berjalan salah di pengolahan diatas, cukup salin berkas basisdata sokongan anda terhadap berkas asli dan mulai kembali.

### Internasionalisasi

#### `django.views.i18n.set_language()` sekarang membutuhkan permintaan POST

Sebelumnya, permintaan GET telah digunakan. Perilaku lama berarti bahwa keadaan (lokal digunakan untuk menampilkan situs) dapat berubah dengan permintaan GET, yaitu terhadap anjuran spesifikasi HTTP. Kode memanggil tampilan ini harus memastikan bahwa permintaan POST sekaragn dibuat, sebagai gantinya GET. Ini berarti anda tidak dapat lagi menggunakan tautan mengakses tampilan, tetapi harus menggunakan pengajuan formulir dari sejenis (sebagai contoh tombol).

#### `_()` tidak lagi siap pakai

`_()` (obyek callable yang namanya adalah garis bawah tunggal) tidak lagi monkeypatch kedalam siap pakai -- yaitu, itu tidak lagi tersedia secara ajaib di setiap modul.

Jika anda sebelumnya bergantung pada `_()` selalu menjadi hadir, anda harus sekarang secara eksplisit mengimpor `ugettext` atau `ugettext_lazy`, jika sesuai, dan namai itu menjadi `_` anda sendiri:

    from django.utils.translation import ugettext as _

### Obyek HTTP request/response

#### Akses kamus ke `HttpRequest`

`HttpRequest` objects no longer directly support dictionary-style access; previously, both `GET` and `POST` data were directly available on the `HttpRequest` object (e.g., you could check for a piece of form data by using `if 'some_form_key' in request` or by reading `request['some_form_key']`). This is no longer supported; if you need access to the combined `GET` and `POST` data, use `request.REQUEST` instead.

Itu sangat disarankan, bagaimanapun, bahwa anda selalu secara eksplisit mencari di kamus yang sesuai untuk jenis dari permintaan anda harapkan untuk menerima (`request.GET` or `request.POST`); bergantung pada gabungan kamus `request.REQUEST` dapat menutup data datang asli.

#### Mengakses kepala `HTTPResponse`

`django.http.HttpResponse.headers` telah dinamai kembali ke `_headers` dan `HttpResponse` sekarang mendukung penahanan pemeriksaan secara langsung. Jadi gunakan `if header in response:` daripada `if header in response.headers:`.

### Hubungan umum

#### Hubungan umum telah dipindahkan keluar dari inti

Kelas-kelas hubungan umum -- `GenericForeignKey` dan `GenericRelation` -- telah dipindahkan kedalam modul `django.contrib.contenttypes`.

### Pengujian

#### meth:django.test.Client.login telah berubah

Lama (0.96):

    from django.test import Client

    c = Client()
    c.login("/path/to/login", "myuser", "mypassword")

Baru (1.0):

    # ... same as above, but then:
    c.login(username="myuser", password="mypassword")

### Pengelolaan perintah

#### Menjalankan pengelolaan perintah dari kode anda

`django.core.management` telah direfaktor.

Panggilan pada pengelolaan pelayanan di kode anda sekarang butuh untuk menggunakan `call_command`. Sebagai contoh, jika anda mempunyai beberapa percobaan yang memanggil flush dan load_data:

    from django.core import management

    management.flush(verbosity=0, interactive=False)
    management.load_data(["test_data"], verbosity=0)

...anda akan butuh merubah kdoe ini untuk dibaca:

    from django.core import management

    management.call_command("flush", verbosity=0, interactive=False)
    management.call_command("loaddata", "test_data", verbosity=0)

#### Sub perintah sekarang harus mendahulukan pilihan

`django-admin.py` dan `manage.py` sekarang membutuhkan sub perintah untuk mendahulukan pilihan. Jadi:

    $ django-admin.py --settings=foo.bar runserver

...tidak lagi bekerja dan harus dirubah menjadi:

    $ django-admin.py runserver --settings=foo.bar

### Kongsi

#### `Feed.__init__` telah berubah

metode `__init__()` dari kongsi kelas `Feed` kerangka kerja sekarang mengambil sebuah obyek `HttpRequest` sebagai parameter keduanya, daripada URL umpan. Ini mengizinkan kongsi kerangka kerja untuk bekerja tanpa membutuhkan kerangka kerja situs. Ini hanya mempengaruhi kode yang subkelas `Feed` dan menimpa metode `__init__()`, dan kode yang memanggil `Feed.__init__()` secara langsung.

### Struktur data

#### SortedDictFromList` telah pergi

`django.newforms.forms.SortedDictFromList` telah dipindahkan. `django.utils.datastructures.SortedDict` sekarang dapat membuat obyek dengan urutan dari tuple-tuple.

Untuk memperbaharui kode anda:

1. Gunakan `django.utils.datastructures.SortedDict` dimanapun anda menggunakan `django.newforms.forms.SortedDictFromList`.

2. Karena `django.utils.datastructures.SortedDict.copy` tidak mengemblikan salinan dalam sebagai `SortedDictFromList.copy()` lakukan, anda akan butuh memperbaharui kode anda jika anda bergantung pada saliann dalam. Lakukan ini dengan menggunakan `copy.deepcopy` secara langsung.

### Fungsi basisdata backend

#### Fungsi basisdata backend telah diubah namanya

Hampir semua dari fungsi tingkatan backend basisdata telah dinamai kembali dan/atau ditempatkan kembali. Tidak ada dari ini didokumentasikan, tetapi anda akan butuh merubah kode anda jika anda sedang menggunakan tiap fungsi ini, semua dari yang berada di `django.db`:

Lama (0.96) | Baru (1.0)
--- | ---
`backend.get_autoinc_sql` | `connection.ops.autoinc_sql`
`backend.get_date_extract_sql` | `connection.ops.date_extract_sql`
`backend.get_date_trunc_sql` | `connection.ops.date_trunc_sql`
`backend.get_datetime_cast_sql` | `connection.ops.datetime_cast_sql`
`backend.get_deferrable_sql` | `connection.ops.deferrable_sql`
`backend.get_drop_foreignkey_sql` | `connection.ops.drop_foreignkey_sql`
`backend.get_fulltext_search_sql` | connection.ops.fulltext_search_sql`
`backend.get_last_insert_id` | `connection.ops.last_insert_id`
`backend.get_limit_offset_sql` | `connection.ops.limit_offset_sql`
`backend.get_max_name_length` | `connection.ops.max_name_length`
`backend.get_pk_default_value` | `connection.ops.pk_default_value`
`backend.get_random_function_sql` | `connection.ops.random_function_sql`
`backend.get_sql_flush` | `connection.ops.sql_flush`
`backend.get_sql_sequence_reset` | `connection.ops.sequence_reset_sql`
`backend.get_start_transaction_sql` | `connection.ops.start_transaction_sql`
`backend.get_tablespace_sql` | `connection.ops.tablespace_sql`
`backend.quote_name` | `connection.ops.quote_name`
`backend.get_query_set_class` | `connection.ops.query_set_class`
`backend.get_field_cast_sql` | `connection.ops.field_cast_sql`
`backend.get_drop_sequence` | `connection.ops.drop_sequence_sql`
`backend.OPERATOR_MAPPING` | `connection.operators`
`backend.allows_group_by_ordinal` | `connection.features.allows_group_by_ordinal`
`backend.allows_unique_and_pk` | `connection.features.allows_unique_and_pk`
`backend.autoindexes_primary_keys` | `connection.features.autoindexes_primary_keys`
`backend.needs_datetime_string_cast` | `connection.features.needs_datetime_string_cast`
`backend.needs_upper_for_iops` | `connection.features.needs_upper_for_iops`
`backend.supports_constraints` | `connection.features.supports_constraints`
`backend.supports_tablespaces` | `connection.features.supports_tablespaces`
`backend.uses_case_insensitive_names` | `connection.features.uses_case_insensitive_names`
`backend.uses_custom_queryset` | `connection.features.uses_custom_queryset`