# dokumentasi Django 2.0.8

# Membuat query

Sekali anda telah membuat data models 1 anda, Django otomatis memberikan anda pemisahan API yang membuat anda membuat, mengambil, memperbaharui dan menghapus obyek. Dokumen ini menjelaskan bagaimana menggunakan API ini. mengacu pada data model reference 2 untuk rincian penuh dari beragam pilihan pencarian model.

Sepanjang panduan ini (dan dalam acuan), kami akan mengacu ke model-model berikut, yang meliputi aplikasi Weblog:

    from django.db import models

    class Blog(models.Model):
        name = models.CharField(max_length=100)
        tagline = models.TextField()

        def __str__(self):
            return self.name

    class Author(models.Model):
        name = models.CharField(max_length=200)
        email = models.EmailField()

        def __str__(self):
            return self.name

    class Entry(models.Model):
        blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
        headline = models.CharField(max_length=255)
        body_text = models.TextField()
        pub_date = models.DateField()
        mod_date = models.DateField()
        authors = models.ManyToManyField(Author)
        n_comments = models.IntegerField()
        n_pingbacks = models.IntegerField()
        rating = models.IntegerField()

        def __str__(self):
            return self.headline

## Membuat obyek

Untuk mewakili data tabel-basisdata dalam obyek Python, Django menggunakan sistem intuitif: Sebuah kelas model mewakili sebuah tabel basisdata, dan sebuah instance dari kelas itu mewakili rekaman tertentu dalam tabel basisdata.

Untuk membuat sebuah obyek, instansiasi itu menggunakan argumen katakunci pada kelas model, kemudian memanggil `save()` untuk menyimpan itu ke basisdata.

Menganggap model tinggal di berkas `mysite/blog/models.py`, ini adalah sebuah contoh:

    >>> from blog.models import Blog
    >>> b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
    >>> b.save()

Ini melakukan pernyataan SQL `INSERT` dibelakang layar. Django tidak mengenai basisdata sampai anda secara jelas memanggil `save()`.

Cara `save()` tidak mempunyai nilai kembalian.

lihat juga

`save()` mengambil sejumalh pilihan keuntungan tidak digambarkan disini. Lihat dokumentasi untuk `save()` untuk rincian lengkap.

Untuk membuat dan menyimpan sebuah obyek dalam langkah tunggal, gunakan cara `create()`.

## Menyimpan perubahan ke obyek

Untuk menyimpan perubahan ke sebuah obyek yang sudah ada di basisdata gunakan `save()`.

Diberikan instance `Blog` `b5` yang telah disimpan ke basisdata, contoh ini merubah namanya dan memperbaharui rekamannya dalam basisdata:

    >>> b5.name = 'New name'
    >>> b5.save()

Ini melakukan pernyataan SQL `UPDATE` dibelakang layar. Django tidak mengenai basisdata sampai anda secara jelas memanggil `save()`.

### Menyimpan bidang `ForeignKey` dan `ManyToManyField`

Memperbaharui bidang `ForeignKey` bekerja tepat cara sama ketika menyimpan bidang biasa -- cukup menugaskan sebuah obyek dari jenis yang benar pada bidang dalam pertanyaan. Contoh ini memperbaharui atribut `blog` dari sebuah instance `Entry`, menganggap instance-instance sesuai dari `Entry` dan `Blog` sudah disimpan ke basisdata (jadi kami dapat mengambil mereka dibawah):

    >>> from blog.models import Blog, Entry
    >>> entry = Entry.objects.get(pk=1)
    >>> cheese_blog = Blog.objects.get(name="Cheddar Talk")
    >>> entry.blog = cheese_blog
    >>> entry.save()

Memperbaharui sebuah `ManyToManyField` bekerja sedikit berbeda -- gunakan metode `add()` pada bidang untuk menambahkan rekaman ke hubungan. Contoh ini menambahkan instance `Author` `joe` ke obyek `entry`:

    >>> from blog.models import Author
    >>> joe = Author.objects.create(name="Joe")
    >>> entry.authors.add(joe)

Untuk menambahkan banyak rekaman pada `ManyToManyField` dalam sekali pergi, sertakan banyak argumen dalam panggilan pada `add()`, seperti ini:

    >>> john = Author.objects.create(name="John")
    >>> paul = Author.objects.create(name="Paul")
    >>> george = Author.objects.create(name="George")
    >>> ringo = Author.objects.create(name="Ringo")
    >>> entry.authors.add(john, paul, george, ringo)

Django akan mengeluh jika anda mencoba memberikan atau menambahkan sebuah obyek dari jenis salah.

## Mengambil obyek

Untuk mengambil obyek-obyek dari basisdata anda, bangun sebuah `QuerySet` melalui `Manager` pada kelas model anda.

Sebuah `QuerySet` mewakili sebuah kumpulan dari ibyek-obyek dari basisdata anda. itu dapat memiliki nol, satu atau banyak penyaring. Penyaring mempersempit hasil permintaan berdasarkan pada parameter yang diberikan. Dalam istilah SQL, `QuerySet` menyamakan pada pernyataan `SELECT`, dan penyaring membatasi klausa seperti `WHERE` atau `LIMIT`.

Anda mendapatkan `QuerySet` dengan menggunakan `Manager` model anda. Setiap model mempunyai setidaknya satu `Manager`, dan itu memanggil `objects` secara awalan. Akses itu langsung melalui kelas model, seperti itu:

    >>> Blog.objects
    <django.db.models.manager.Manager object at ...>
    >>> b = Blog(name='Foo', tagline='Bar')
    >>> b.objects
    Traceback:
        ...
    AttributeError: "Manager isn't accessible via Blog instances."

Catatan

`Managers` dapat diakses hanya melalui kelas-kelas model, daripada dari instance model, untuk melaksanakan pemisahan diantara tindakan "tingkat-tabel" dan tindakan "tingkat-rekam".

`Manager` adalah sumber utama dari `QuerySets` untuk sebuah model. Sebagai contoh, `Blog.objects.all()` mengembalikan `QuerySet` yang mengandung semua obyek `Blog` dalam basisdata.

### Mengambil semua obyek

Cara termudah untuk mengambil obyek dari sebuah tabel adalah mendapatkan semua dari mereka. Untuk melakukan ini, gunakan metode `all()` pada sebuah `Manager`:

    >>> all_entries = Entry.objects.all()

Metode `all()` mengembalikan semua `QuerySet` dari semua obyek dalam basisdata.

### Mengambil obyek spesifik dengan menyaring

`QuerySet` dibalikkan oleh `all()` menggambarkan semua obyek-obyek dalam tabel basisdata. Biasanya, meskipun, anda akan butuh memilih hanya sub kumpulan dari kumpulan lengkap dari obyek.

Untuk membuat semacam sub kumpulan, anda menyaring `QuerySet` awalan, menambahkan kondisi penyaringan. Dua cara paling umum untuk menyaring `QuerySet` adalah:

`filter(**kwargs)`
  Mengembalikan `QuerySet` baru mengandung obyek-obyek yang cocok dari parameter pencarian yang diberikan.
`exclude(**kwargs)`
  Mengembalikan `QuerySet` baru mengandung obyek-obyek yang tidak cocok dari parameter pencarian yang diberikan.

Parameter pencarian (`**kwargs` dalam penertian fungsi diatas) harus berupa dalam bentuk digambarkan dalam Field lookups dibawah.

Sebagai contoh, untuk mendapatkan `QuerySet` dari masukan blog dari tahun 2006, gunakan `filter()` seperti itu:

    Entry.objects.filter(pub_date__year=2006)

Dengan kelas pengelola awalan, itu adalah sama seperti:

    Entry.objects.all().filter(pub_date__year=2006)

#### Menambatkan penyaringan

Hasil dari pengilangan `QuerySet` adalah itu sendiri `QuerySet`, jadi itu mungkin menambatkan pengilangan bersama-sama. Sebagai contoh:

    >>> Entry.objects.filter(
    ...     headline__startswith='What'
    ... ).exclude(
    ...     pub_date__gte=datetime.date.today()
    ... ).filter(
    ...     pub_date__gte=datetime.date(2005, 1, 30)
    ... )

Ini mengambil awal `QuerySet` dari semua masukan dalam basisdata, tambah sebuah penyaring, kemudian sebuah pengecualian, kemudian penyaring lain. Hasil akhir adalah sebuah `QuerySet` mengandung semua masukan dengan judul yang mulai dengan "What", yang diterbitkan diantara 30 Januari 2005, dan hari saat ini.

#### Disaring `QuerySet` adalah unik

Setiap kali anda menyaring sebuah `QuerySet`, anda mendapatkan `QuerySet` merek-baru yaitu tidak ada cara mengikat ke `QuerySet` sebelumnya. Setiap penyaringan membuat `QuerySet` terpisah dan berbeda yang dapat disimpan, digunakan dan digunakan kembali.

Contoh:

    >>> q1 = Entry.objects.filter(headline__startswith="What")
    >>> q2 = q1.exclude(pub_date__gte=datetime.date.today())
    >>> q3 = q1.filter(pub_date__gte=datetime.date.today())

Ketiga `QuerySets` ini terpisah. Pertama adalah dasar `QuerySet` mengandung semua masukan yang mengandung judul dimulai dengan "What". kedua adalah sub kumpulan dari pertama, dengan sebuah tambahan kriteria yang tidak menyertakan rekaman yang `pub_date` adalah hari ini atau di masa depan. Ketiga adalah sub kumpulan dari pertama, dengan tambahan kriteria yang hanya memilih rekaman yang `pub_date` adalah hari ini atau di masa depan. Awalan `QuerySet` (`q1`) tidak terpengaruh dengan pengolahan penyaringan.

#### `QuerySet` adalah lazy

`QuerySets` adalah lazy -- tindakan dari membuat `QuerySet` tidak melibatkan aktifitas basisdata apapun. Anda dapat menumpuk penyaring bersama-sama sepanjang hari, dan Django tidak sebenarnya menjalankan permintaan sampai `QuerySet` dinilai. Coba lihat contoh ini:

    >>> q = Entry.objects.filter(headline__startswith="What")
    >>> q = q.filter(pub_date__lte=datetime.date.today())
    >>> q = q.exclude(body_text__icontains="food")
    >>> print(q)

Meskipun ini terlihat mengenai basisdata tiga kali, sebenarnya itu mengenai basisdata hanya sekali, pada baris terakhir (`print(q)`). Secara umum, hasil dari `QuerySet` tidak diambil dari basisdata sampai anda "meminta" untuk mereka. Ketika anda melakukan, `QuerySet` dinilai dengan mengakses basisdata. Untuk rincian lebih pada sebenarnya ketika penilaian mengambil tempat, lihat Ketika QuerySet dinilai.

### Mengambil obyek tunggal dengan `get()`

`filter()` akan selalu memberikan anda `QuerySet`, bahkan jika hanya obyek tunggal yang cocok permintaan - dalam kasus ini, itu akan berupa `QuerySet` mengandung unsur tunggal.

Jika anda mengetahui hanya ada satu obyek yang cocok permintaan anda, anda dapat menggunakan metode meth:~django.db.models.query.QuerySet.get pada sebuah `Manager` yang mengembalikan obyek secara langsung:

    >>> one_entry = Entry.objects.get(pk=1)

Anda dapat menggunakan pernyataan permintaan apapun dengan `get()`, seperti dengan `filter()` - kembali, lihat Field lookups dibawah.

Catat bahwa ada perbedaan diantara menggunakan `get()`, dan menggunakan `filter()` dengan potongan `[0]`. Jika tidak ada hasil yang cocok dengan permintaan, `get()` akan memunculkan pengecualian `DoesNotExist`. Pengecualian ini adalah sebuah atribut dari kelas model yang permintaan sedang dilakukan - jadi dalam kode diatas, jika tidak ada obyek `Entry` dengan primary key dari 1, Django akan memunculkan `Entry.DoesNotExist`.

Demikain pula, Django akan mengeluh jika lebih dari satu barang cocok permintaan `get()`. Dalam kasus ini, itu akan memunculkan `MultipleObjectsReturned`, yang kembali adalah sebuah atribut dari kelas model itu sendiri.

### Cara `QuerySet` lain

Kebanyakan waktu anda akan gunakan `all()`, `get()`, `filter()` dan `exclude()` ketika anda butuh mencari obyek-obyek dari basisdata. Bagaimanapun, itu jauh dari semua yang ada; lihat QuerySet API Reference untuk daftar lengkap dari semua ragam metode `QuerySet`.

### Membatasi `QuerySet`

Gunakan sub kumpulan dari sintaksis memotong-array Python untuk membatasi `QuerySet` anda pada nomor tertentu dari hasil. Ini adalah setara daro klausa `LIMIT` dan `OFFSET` SQL.

Sebagai contoh, ini mengembalikan 5 obyek pertama (`LIMIT 5`):

    >>> Entry.objects.all()[:5]

Ini mengembalikan enam dari 10 obyek (`OFFSET 5 LIMIT 5`):

    >>> Entry.objects.all()[5:10]

Pengindeksan negatif (yaitu `Entry.objects.all()[-1]`) tidak didukung.

Umumnya, memotong `QuerySet` mengembalikan `QuerySet` baru -- itu tidak menilai permintaan. Sebuah pengevualian jika anda menggunakan parameter "step" dari sintaksis potongan Python. Sebagai contoh, ini akan sebenarnya menjalankan permintaan untuk menjalankan daftar dari setiap detik obyek dari 10 pertama:

    >>> Entry.objects.all()[:10:2]

Penyaring atau pengurut lebih lanjut dari irisan queryset dilarang karena sifat ambigu dari bagaimana itu mungkin bekerja.

Untuk mengambil obyek tunggal daripada sebuah list (sebagai contoh `SELECT foo FROM bar LIMIT 1`), gunakan indeks sederhana sebagai gantinya dari potongan. Sebagai contoh, ini mengembalikan `Entry` pertama dalam basisdata, setelah mengurutkan masukan secara alfabet berdasarkan judul:

    >>> Entry.objects.order_by('headline')[0]

Ini kurang lebih setara pada:

    >>> Entry.objects.order_by('headline')[0:1].get()

Catat, bagaimanapun, yang pertama dari ini akan memunculkan `IndexError` selagi kedua akan memunculkan `DoesNotExist` jika tidak ada obyek cocok dari kriteria yang diberikan. Lihat `get()` untuk rincian lebih.

### Bidang pencarian

Pencarian bidang adalah bagaimana anda menentukan isi dari sebuah klausa SQL `WHERE`. Mereka ditentukan sebagai argumen kata kunci pada `QuerySet` metode metode `filter()`, `exclude()` dan `get()`.

Argumen kata kunci pencarian dasar mengambil formulir `field__lookuptype=value`. (Itu adalah garis bawah ganda). Sebagai contoh:

    >>> Entry.objects.filter(pub_date__lte='2006-01-01')

terjemahan (kurang lebih) ke dalam SQL berikut:

    SELECT * FROM blog_entry WHERE pub_date <= '2006-01-01';

Bagaimana ini mungkin

Python mempunyai kemampuan untuk menentukan fungsi-fungsi yang menerima argumen nilai-nama beruubah-ubah yang namanya dan nilainya dinilai pada waktu berjalan. Untuk informasi lebih, lihat Keyword Arguments dalam tutorial Python resmi.

Bidang ditentukan dalam pencarian harus berupa nama dari bidang model. meskipun ada satu pengecualian, dalam kasus dari `ForeignKey` anda dapat menentukan nama bidang akhiran dengan `_id`. Dalam kasus ini, parameter nilai diharapkan mengandung nilai mentah dari foreign primary key model. Sebagai contoh:

    >>> Entry.objects.filter(blog_id=4)

Jika anda melewatkan argumen kata kunci tidak sah, fungsi pencarian akan memunculkan `TypeError`.

API basisdata mendukung sekitar dua lusin jenis pencarian; acuan lengkap dapat ditemukan dalam field lookup reference 1. Untuk memberikan anda selera dari apa yang tersedia, ini adalah beberapa dari pencarian lebih umum anda mungkin gunakan:

`exact`

  Sebuah pencocokan "tepat". Sebagai contoh:

      >>> Entry.objects.get(headline__exact="Cat bites dog")

  Akan membangkitkan SQL bersama baris ini:

      SELECT ... WHERE headline = 'Cat bites dog';

  Jika anda tidak menyediakan jenis pencarian -- yaitu, jika argumen kata kunci anda tidak mengandung garis bawah ganda -- jenis pencarian dianggap `tepat`.

  Sebagai contoh, dua pernyataan berikut adalah setara:

      >>> Blog.objects.get(id__exact=14)  # Explicit form
      >>> Blog.objects.get(id=14)         # __exact is implied

  Ini adalah untuk kenyamanan, karena pencarian `exact` adalah kasus umum.

`iexact`

  Pencocokan kasus-tidak-peka. Jadi, permintaan:

      >>> Blog.objects.get(name__iexact="beatles blog")

  Akan cocok `Blog` berjudul `"Beatles Blog"`, `"beatles blog"`, atau bahkan `"BeAtlES blOG"`.

`contains`

  Percobaan penahanan kasus-peka . Sebagai contoh:

      Entry.objects.get(headline__contains='Lennon')

  Kurang lebih menterjemahkan ke SQL ini:

      SELECT ... WHERE headline LIKE '%Lennon%';

  Catat ini akan cocok dengan judul `'Today Lennon honored'` tetapi tidak `'today lennon honored'`.

  Ada juga versi kasus-tidak-peka, `icontains`.

`startswith`, `endswith`
  Pencarian mulai-dengan dan berakhir-dengan, masing-masing. Ada juga versi kasus-tidak-peka dipanggil `istartswith` dan `iendswith`.

Kembali, ini hanya menggores permukaan. Acuan lengkap dapat ditemukan di field lookup reference 1.

### Pencarian yang menjangkau hubungan

Django menawarkan cara hebat dan intituitif untuk "mengikuti" hubungan dalam pencarian, merawat dari SQL `JOIN` untuk anda otomatis, dibelakang layar. Untuk menjangkau hubungan, cukup gunakan nama bidang dari bidang terkait terhadap model, dipisahkan oleh garisbawah ganda, sampai anda mendapatkan bidang anda inginkan.

Contoh ini mengambil semua obyek `Entry` dengan `Blog` yang `name` adalah `'Beatles Blog'`:

    >>> Entry.objects.filter(blog__name='Beatles Blog')

Jangkauan ini dapat sedalam anda sukai.

Itu bekerja kebelakang, juga. Untuk mengacu hubungan "reverse", cukup gunakan nama huruf kecil dari model.

Contoh ini mengambil semua obyek `Blog` yang setidaknya saru `Entry` yang `headline` mengandung `'Lennon'`:

    >>> Blog.objects.filter(entry__headline__contains='Lennon')

Jika anda menyaring terhadap banyak hubungan dan satu dari model mengengah tidak mempunyai nilai yang memenuhi kondisi penyaring, Django akan memperlakukan itu sebagai jika sebuah kosong (semua nilai adalah `NULL`), tetapi obyek sah disana. Semua ini berarti bahwa tidak ada kesalahan akan dimunculkan. Sebagi contoh, dalam penyaringan ini:

    Blog.objects.filter(entry__authors__name='Lennon')

(jika ada model `Author` terkait), jika tidak ada `author` terkait dengan sebuah masukan, itu akan diperlakukan seperti jika tidak ada juga `name` terlampir, daripada memunculkan kesalahan karena dari `author` hilang. Biasanya ini adalah tepatnya apa anda ingin miliki terjadi. Kasus satu-satunya dimana itu mungkin membingungkan adalah jika anda menggunakan `isnull`. Jadi:

    Blog.objects.filter(entry__authors__name__isnull=True)

akan mengembalikan obyek `Blog` yang mempunyai `name` kosong pada `author` dan juga itu yang mempunyai `author` kosong pada `entry`. Jika anda tidak ingin obyek terakhir itu, anda dapat menulis:

    Blog.objects.filter(entry__authors__isnull=False, entry__authors__name__isnull=True)

#### Membentangkan hubungan banyak-nilai

Ketika anda menyaring sebuah obyek berdasarkan pada sebuah `ManyToManyField` atau membalikkan `ForeignKey`, ada dua perbedaan urutan dari penyaringan anda mungkin tertarik. Pertimbangkan hubungan `Blog`/`Entry` (`Blog` pada `Entry` adalah hubungan one-to-many). Kami mungkin tertarik dalam menemukan blog yang memiliki sebuah masukan yang mempunyai kedua "Lennon" dalam judul dan telah diterbitkan di 2008. Atau kami mungkin ingin menemukan blog yang mempunyai sebuah masukan dengan "Lennon" dalam judul sama halnya sebuah masukan yang telah diterbitkan di 2008. Sejak ada banyak masukan terkait dengan `Blog` tunggal, kedua dari permintaan ini adalah memungkinkan dan masuk akal dalam beberapa keadaan

Jenis keadaan sama muncul dengan `ManyToManyField`. Sebagai contoh, jika sebuah `Entry` mempunyai `ManyToManyField` disebut `tags`, kami mungkin ingin menemukan masukan terkait ke etiket disebut "music" dan "bands" atau kami mungkin ingin sebuah masukan yang mengandung sebuth etiket dengan nama dari "music" dan status dari "public".

Untuk menangani kedua keadan ini, Django mempunyai cari yang cocok dari mengolah panggilan `filter()`. Apapun didalam panggilan `filter()` tunggal diberlakukan secara terus menerus untuk menyaring barang-barang mencocokkan semua lingkungan tersebut. Panggilan `filter()` berturut-turut lebih lanjut membatasi setelan dari obyek, tetapi untuk hubungan banyak-nlai, mereka berlaku ke obyek apapun terkait pada model utama, tidak perlu obyek-obyek itu yang telah dipilih oleh panggilan `filter()` paling awal.

Itu mungkin sedikit sedikit membingungkan, jadi semoga sebuah contoh untuk menjelaskan. Untuk memilih semua blog yang mengandungmasukan dengan "Lennon" dalam judul dan telah diterbitkan di 2008 (masukan sama memuaskan kedua keadaan), kami akan menulis:

    Blog.objects.filter(entry__headline__contains='Lennon', entry__pub_date__year=2008)

Untuk memilih semua blog yang mengandung sebuah masukan dengan "Lennon" di judul, sama halnya sebuah masukan yang telah diterbitkan di 2008, kami akan menulis:

    Blog.objects.filter(entry__headline__contains='Lennon').filter(entry__pub_date__year=2008)

Sekiranya hanya ada satu blog yang mempunyai kedua masukan mengandung "Lennon" dan masukan dari 2008 tetapi bahwa tidak satupun dari masukan dari 2008 mengandung "Lennon". Permintaan pertmana tidak akan mengembalikan blog apapun, tetapi kedua permintaan akan mengembalikan itu satu blog.

Dalam contoh kedua, penyaring pertama membatasi queryset ke semua blog-blog tersebut terkait ke masukan dengan "Lennon" di judul. Penyaring kedua membatasi kumpulan blog further ke itu yang juga terkait ke masukan yang telah diterbirkan di 2008. Masukan dipilih oleh penyaring kedua mungkin atau mungkin tidak sama seperti masukan di penyaring pertama. Kami sedang menyaring barang-barang `Blog` dengan setiap pernyataan penyaring, bukan barang-barang `Entry`.

Catatan

Perilaku dari `filter()` untuk permintaan yang menjangkau hubungan banyak-nilai, seperti digambarkan diatas, tidak diterapkan setara untuk `exclude()`. Malahan, keadaan dalam panggilan `exclude()` tunggal tidak akan butuh mengacu ke barang sama.

Sebagai contoh, permintaan berikut akan tidak menyertakan blog-blog yang mengandung kedua masukan dengan "Lennon" di judul dan masukan diterbitkan di 2008:

    Blog.objects.exclude(
        entry__headline__contains='Lennon',
        entry__pub_date__year=2008,
    )

Bagaimanapun, tidak seperti perilaku ketika menggunakan `filter()`,ini tidak akan membatasi blog-blog berdasarkan pada masukan yang memuaskan kedua keadaan. Untuk melakukan itu, yaitu untuk memilih semua blog yang tidak mengandung masukan diterbitkan dengan "Lennon" yang telah diterbitkan di 2008, anda butuh membuat dua permintaan:

    Blog.objects.exclude(
        entry__in=Entry.objects.filter(
            headline__contains='Lennon',
            pub_date__year=2008,
        ),
    )

### Penyaring dapat mengacu bidang pada model

Dalam contoh yang diberikan sejauh ini, kami telah membangun berkas-berkas penyaring yang membandingkan nilai dari bidang model dengan ketetapan. Tetapi apa jika anda ingin membandingkan nilai dai bidang model dengan bidang lain pada model sama?

Django menyediakan `F expressions` untuk mengizinkan perbandingan. Instance dari `F()` bertindak sebagai sebuah acuan pada model dalam permintaan. Acuan ini kemudian dapat digunakan dalam penyaring permintaan untuk membandingkan nilai-nilai dari dua bidang berbeda pada instance model sama.

Sebagai contoh, untuk menemukan daftar dari semua masukan blog yang telah mempunyai komentar lebih dari pingback, kami membangun obyek `F()` untuk mengacu jumlah pingback, dan menggunakan obyek `F()` itu dalam permintaan:

    >>> from django.db.models import F
    >>> Entry.objects.filter(n_comments__gt=F('n_pingbacks'))

Django mendukung penggunaan aritmatika penambahan, pengurangan, perkalian, pembagian modulus, dan power dengan obyek `F()`, kedua dengan ketetapan dan dengan obyek `F()` lain. Untuk menemukan semua masukan blog dengan lebih dari dua kali sebanyak komentar seperti pingback, kami merubah permintaan:

    >>> Entry.objects.filter(n_comments__gt=F('n_pingbacks') * 2)

Untuk menemukan semua masukan dimana penilaian dari masukan sedikit dari penjumlahan hitungan pingback dan hitungan komentar, kami akan menerbitkan permintaan:

    >>> Entry.objects.filter(rating__lt=F('n_comments') + F('n_pingbacks'))

Anda dapat juga menggunakan pernyataan garis bawah untuk menjangkau hubungan dalam sebuah obyek `F()`. Sebuah obyek `F()` dengan garis bawah ganda akan memperkenalkan join apapun dibutuhkan untuk mengakses obyek terkait. Sebagai contoh, untuk mengambil semua masukan dimana nama penulis sama seperti nama blog, kami dapat menerbitkan permintaan:

    >>> Entry.objects.filter(authors__name=F('blog__name'))

Untuk bidang-bidang tanggal dan tanggal/waktu, anda dapat menambah atau mengurangi obyek `timedelta`. Berikut akan mengembalikan semua masukan yang telah diubah lebih dari 3 hari setelah mereka diterbitkan.

    >>> from datetime import timedelta
    >>> Entry.objects.filter(mod_date__gt=F('pub_date') + timedelta(days=3))

Obyek `F()` mendukung tindakan bitwise dengan .bitand()`, `.bitor()`, `.bitrightshift()`, dan `.bitleftshift()`. Sebagai contoh:

    >>> F('somefield').bitand(16)

Changed in Django 1.11:

Dukungan untuk `.bitrightshift()` dan `.bitleftshift()` telah ditambahkan.

### Jalan pintas pencarian `pk`

Untuk kemudahan, Django menyediakan jalan pintas pencarian `pk`, yang berdiri untuk "primary key".

Dalam contoh model `Blog`, primary key adalah bidang `id`, jadi pernyataan ini adalah setara:

    >>> Blog.objects.get(id__exact=14) # Explicit form
    >>> Blog.objects.get(id=14) # __exact is implied
    >>> Blog.objects.get(pk=14) # pk implies id__exact

Penggunaan `pk` tidak terbatas pada permintaan `__exact` -- apapun istilah permintaan dapat dipadukan dengan `pk` untuk melakukan sebuah permintaan pada primary key pada model:

    # Get blogs entries with id 1, 4 and 7
    >>> Blog.objects.filter(pk__in=[1,4,7])

    # Get all blog entries with id > 14
    >>> Blog.objects.filter(pk__gt=14)

Pencarian `pk` juga bekerja liintas join. Sebagai contoh, tiga pernyataan ini adalah setara:

    >>> Entry.objects.filter(blog__id__exact=3) # Explicit form
    >>> Entry.objects.filter(blog__id=3)        # __exact is implied
    >>> Entry.objects.filter(blog__pk=3)        # __pk implies __id__exact

### Meloloskan tanda persen dan garis bawah dalam pernyataan `LIKE`

Pencarian bidang yang menyerupai pernyataan SQL `LIKE` (`iexact`, `contains`, `icontains`, `startswith`, `istartswith`, `endswith` dan `iendswith`) akan otomatis meloloskan dua karakter khusus digunakan dalam pernyataan `LIKE` -- tanda persen dan garis bawah. (Dalam sebuah pernyataan `Like`, tanda persen menandakan wildcard banyak-karakter dan garis bawah menandakan wildcard karakter-tunggal.)

Ini berarti hal-hal harus bekerja secara intuitif, jadi abstraksi tidak bocor. Sebagai contoh, untuk mengambil semua masukan yang mengandung tanda persen, cukup gunakan tanda persen sebagai katakter lain:

    >>> Entry.objects.filter(headline__contains='%')

Django menangani dari pengutipan untuk anda; menghasilkan SQL akan mencari sesuatu seperti ini:

    SELECT ... WHERE headline LIKE '%\%%';

Sama seperti garis bawah. Kedua tanda persen dan garis bawag ditangani untuk anda secara transparan.

### Cache dan `QuerySet`

Setiap `QuerySet` mengandung sebuah tembolok untuk meminimalkan akses basisdata. Pahami bagaimana dia bekerja akan mengizinkan anda menulis kode paling efisien.

Dalam `QuerySet` baru dibuat, cache kosong. Pertama kali sebuah `QuerySet` dinilai -- dan, karena itu, sebuah permintaan basisdata terjadi -- Django menyimpan hasil permintaan dalam cache `QuerySet` dan mengembalikan hasil yang telah secara jelas diminta (sebagai contoh, unsur selanjutnya, jika ada `QuerySet` sedang diulang). Penilaian selanjutnya dari `QuerySet` menggunakan hasil ter cache.

Jaga perilaku cache ini dalam pikiran, karena itu mungkin mengigit anda jika anda tidak menggunakan `QuerySet` anda dengan benar. Sebagai contoh, berikut akan membuat dua `QuerySet`, nilai mereka, dan lemparkan mereka:

    >>> print([e.headline for e in Entry.objects.all()])
    >>> print([e.pub_date for e in Entry.objects.all()])

Itu berarti permintaan absisdata sama akan dijalankan dua kali, berhasil menggandakan muatan basisdata anda. Juga, ada kemungkinan dua daftar mungkin tidak meneyrtakan rekaman basisdata sama, karena `Entry` telah ditambahkan atau dihapus dalam pembagian kedua diantara dua permintaan.

Untuk menghindari masalah ini, cukup simpan `QuerySet` dan gunakan kembali

    >>> queryset = Entry.objects.all()
    >>> print([p.headline for p in queryset]) # Evaluate the query set.
    >>> print([p.pub_date for p in queryset]) # Re-use the cache from the evaluation.

#### Ketika `QuerySet` tidak di cache

Queryset tidak selalu cache hasil mereka. Ketika menilai hanya bagian dari queryset, cache diperiksa, tetapi jika tidak dikumpulkan kemudian barang-barang dikembalikan oleh permintaan selanjutnya tidak di cache. Secara khusus, ini berarti bahwa limiting the queryset 1 menggunakan potongan senarai atau sebuah indeks tidak akan dikumpulkan cache.

Sebagi contoh, secara berulang mendapatkan indeks tertentu di queryset obyek akan meminta basisdata setiap waktu:

    >>> queryset = Entry.objects.all()
    >>> print(queryset[5]) # Queries the database
    >>> print(queryset[5]) # Queries the database again

Bagaimanapun, jika keseluruhan queryset sudah dinilai, tembolok akan diperiksa sebagai gantinya:

    >>> queryset = Entry.objects.all()
    >>> [entry for entry in queryset] # Queries the database
    >>> print(queryset[5]) # Uses cache
    >>> print(queryset[5]) # Uses cache

Ini adalah beberapa contoh dari tindakan lain yang akan menghasilkan keseluruhan queryset yang sedang dinilai dan karena itu dikumpulkan tembolok:

    >>> [entry for entry in queryset]
    >>> bool(queryset)
    >>> entry in queryset
    >>> list(queryset)

Catatan

Mencetak sederhana queryset tidak akan mengumpulkan tembolok. Ini dikarenakan panggilan pada `__repr__()` hanya mengembalikan potongan dari keseluruhan queryset.

## Pencarian rumit dengan obyek `Q`

Permintaan argumen katakunci -- dalam `filter()`, dll. -- adalah "AND" bersama-sama. Jika anda buth menjalankan permintaan lebih rumit (sebagai contoh, permintaan dengan pernyataan `OR`), anda dapat menggunakan `Q objects`.

`Q object` (`django.db.models.Q`) adalah sebuah obyek digunakan untuk membungkus koleksi dari argumen katakunci. Argumen katakunci ini ditentukan seperti dalam "Pencarian bidang" diatas.

Sebagai contoh, obyek `Q` ini membungkus permintaan `LIKE` tunggal:

    from django.db.models import Q
    Q(question__startswith='What')

Obyek `Q` dapat dipadukan menggunakan penghubung `&` dan `|`. Ketika sebuah penghubung digunakan pada dua obyek `Q`, itu menghasilkan obyek `Q` baru.

Sebagai contoh, pernyataan ini menghasilkan obyek `Q` tunggal yang mewakili "OR" atau dua permintaan `"question__startswith"`

    Q(question__startswith='Who') | Q(question__startswith='What')

Ini sama pada klausa SQL `WHERE` berikut:

    WHERE question LIKE 'Who%' OR question LIKE 'What%'

Anda dapat menyusun pernyataan dari kerumitan yang berubah-ubah dengan memadukan obyek `Q` dengan penghubung `&` and `|` dan gunakan pengelompokan yang disipkan. Juga, obyek `Q` dapat ditugaskan menggunakan penghubung `~`, mengizinkan perpaduan pencarian yang memadukan kedua permintaan normal dan meniadakan permintaan (`NOT`):

    Q(question__startswith='Who') | ~Q(pub_date__year=2005)

Setiap fungsi pencarian yang mengambil argumen-kata kunci (sebagai contoh `filter()`, `exclude()`, `get()`) dapat juga melewatkan satu atau lebih obyek `Q` sebagai argumen (tidak-dinamai) kedudukan. Jika anda menyediakan banyak argumen obyek `Q` pada fungsi pencarian, argumen akan di "AND"kan bersama-sama. Sebagai contoh:

    Poll.objects.get(
        Q(question__startswith='Who'),
        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
    )

... kurang lebih menterjemahkan ke dalam SQL:

    SELECT * from polls WHERE question LIKE 'Who%'
        AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')

Fungsi pencarian dapat mencampurkan penggunaan obyek `Q` dan argumen kata kunci. Semua argumen disediakan untuk fungsi pencarian (menjadi mereka argumen kata kunci atau obyek `Q`) di "AND"kan bersama-sama. Bagaimanapun, jika obyek `Q` disediakan, dia harus mendahului pengertian dari argumen kata kunci apapun. Sebagai contoh:

    Poll.objects.get(
        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
        question__startswith='Who',
    )

... akan menjadi permintaan sah, sama pada contoh sebelumnya; tetapi:

    # INVALID QUERY
    Poll.objects.get(
        question__startswith='Who',
        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
    )

... tidak akan menjadi sah.

lihat juga

OR lookups examples dalam satuan percobaan Django menampilkan beberapa kemungkinan penggunaan dari `Q`.

## Membandingkan obyek

Untuk membandingkan dua model instance, cukup gunakan penghubung perbandingan standar Python, tanda sama dengan ganda: `==`. Dibelakang layar, yang membandingkan nilai primary key dari dua model.

Menggunakan contoh `Entry` diatas, dua pernyataan berikut adalah setara:

    >>> some_entry == other_entry
    >>> some_entry.id == other_entry.id

Jika sebuah primary key model tidak memanggil `id`, tidak masalah. Perbandingan akan selalu menggunakan primary key, apapun itu memanggilnya. Sebagai contoh, jika sebuah primary key model dipanggil `name`, dua pernyataan ini adalah setara:

    >>> some_obj == other_obj
    >>> some_obj.name == other_obj.name

## menghapus obyek

Untuk menghapus metode, mudah, adalah bernama `delete()`. Metode ini segera menghapus obyek dan mengembalikan sejumlah obyek yang dihapus dan sebuah kamus dengan sejumlah penghapusan per jenis obyek. Contoh:

    >>> e.delete()
    (1, {'weblog.Entry': 1})

Anda dapat juga menghapus obyek dalam jumlah besar. Setiap `QuerySet` mempunyai sebuah `delete()` method, yang menghapus semua anggota dari `QuerySet` tersebut.

Sebagai contoh, ini menghapus semua obyek `Entry` dengan tahun `pub-date` dari 2005:

    >>> Entry.objects.filter(pub_date__year=2005).delete()
    (5, {'webapp.Entry': 5})

Ingat bahwa ini akan, ketika memungkinkan, akan dijalankan murni dalam SQL, dan juga cara `delete()` dari instance tidak akan perlu dipanggil selama pengolahan. Jika anda telah menyediakan cara `delete()` disesuaikan pada sebuah kelas model dan ingin memastikan bahwa dia dipanggil, anda akan butuh "secara manual" menghapus instance dari model tersebut (sebagai contoh, dengan perulangan terhadap `QuerySet` dan memanggil `delete()` pada setiap obyek secara tersendiri) daripada menggunakan dalam jumlah besar cara `delete()` dari sebuah `QuerySet`.

Ketika DJANGO menghapus sebuah obyek, secara awal dia meniru kebiasaan batasan SQL `ON DELETE CASCADE` -- dalam kata lain, obyek apapun yang mempunyai foreign key menunjuk pada obyek yang akan dihapus akan dihapus bersama dengannya. Sebagai contoh:

    b = Blog.objects.get(pk=1)
    # This will delete the Blog and all of its Entry objects.
    b.delete()

Kebiasaan turunan ini dapat di sesuaikan melalui argumen `on_delete` ke `ForeignKey`.

Catat bahwa `delete()` adalah hanya cara `QuerySet` yang tidak ditunjukkan pada `Manager` itu sendiri. Ini adalah mekanisme aman untuk mencegah anda dari kecelakaan permintaan `Entry.objects.delete()`, dan menghapus semua masukan. Jika anda ingin melakukan menghapus semua obyek, kemudian anda harus secara jelas meminta kumpulan permintaan lengkap:

    Entry.objects.all().delete()

## Menyalin instance model

Meskipun tidak ada metode siap-pakai untuk menyalin instance model, itu memungkinkan untuk dengan mudah membuat instance baru dengan semua nilai-nilai bidang disalin. Dalam kasus termudah, anda dapat cukup menyetel `pk` menjadi `None`. Menggunakan contoh blog kami:

    blog = Blog(name='My blog', tagline='Blogging is easy')
    blog.save() # blog.pk == 1

    blog.pk = None
    blog.save() # blog.pk == 2

Hal-hal dapat lebih rumit jika anda menggunakan warisan. Pertimbangkan subkelas dari `Blog`:

    class ThemeBlog(Blog):
        theme = models.CharField(max_length=200)

    django_blog = ThemeBlog(name='Django', tagline='Django is easy', theme='python')
    django_blog.save() # django_blog.pk == 3

Disebabkan oleh bagaimana warisan bekerja, anda harus menyetel kedua `pk` dan `id` menjadi None:

    django_blog.pk = None
    django_blog.id = None
    django_blog.save() # django_blog.pk == 4

Pengolahan ini tidak menyalin hubungan yang bukan bagian dari tabel basisdata model. Sebagai contoh, `Entry` mempunyai `ManyToManyField` terhadap `Author`. Setelah menggandakan sebuah masukan, anda harus menyetel hubungan many-to-many untuk masukan baru:

    entry = Entry.objects.all()[0] # some previous entry
    old_authors = entry.authors.all()
    entry.pk = None
    entry.save()
    entry.authors.set(old_authors)

Untuk `OneToOneField`, anda harus menggandakan obyek terkait dan memberikan itu ke bidang obyek baru untuk menghindari melanggar batasan untuk one-to-one. Sebagai contoh, menganggap `entry` sudah digandakan seperti diatas:

    detail = EntryDetail.objects.all()[0]
    detail.pk = None
    detail.entry = entry
    detail.save()

## Memperbaharui banyak obyek sekaligus

Terkadang anda ingin menyetel sebuah bidang ke nilai tertentu untuk semua obyek dalam `QuerySet`. Anda dapat melakukan ini dengan cara `update()`. Sebagai contoh:

    # Update all the headlines with pub_date in 2007.
    Entry.objects.filter(pub_date__year=2007).update(headline='Everything is the same')

Anda dapat hanya menyetel bidang-bidang bukan-hubungan dan bidang-bidang `ForeignKey` menggunakan metode ini. Untuk memperbaharui bidang-bidang `ForeignKey`, setel nilai baru ke instance model baru anda ingin tunjuk. Sebagai contoh:

    >>> b = Blog.objects.get(pk=1)

    # Change every Entry so that it belongs to this Blog.
    >>> Entry.objects.all().update(blog=b)

Metode `update()` diberlakukan segera dan mengembalikan sejumlah baris cocok oleh permintaan (yang mungkin tidak setara pada sejumlah baris diperbaharui jika baris sudah mempunyai nilai baru). Hanya batasan pada `QuerySet` sedang diperbaharui adalah itu dapat hanya diakses pada tabel basisdata: tabel utama model. Anda dapat menyaring pada bidang-bidang terkait, tetapi anda dapat hanya memperbaharui kolom dalam tabel utama model. Contoh:

    >>> b = Blog.objects.get(pk=1)

    # Update all the headlines belonging to this Blog.
    >>> Entry.objects.select_related().filter(blog=b).update(headline='Everything is the same')

Waspada bahwa metode `update()` dirubah secara langsung ke sebuah pernyataan SQL. Itu adalah tindakan pengumpulan untuk pembaharuan langsung. Itu tidak menjalankan metode `save()` apapun pada model-model anda, atau mengeluarkan sinyal `pre_save` atau `post_save` (yang akibat dari memanggil `save()`), atau menerima pilihan bidang `auto_now`. Jika anda ingin mentimpan setiap barang dalam `QuerySet` dan pastikan bahwa metode `save()` dipanggil pada setiap instance, anda tidak butuh fungsi khusus apapun untuk mengangani itu. Cukup putarkan terhadap mereka dan panggil `save()`:

    for item in my_queryset:
        item.save()

Panggilan untuk memperbaharui juga menggunakan `F expressions` untuk memperbaharui satu bidang berdasarkan pada nilai dari bidang lain dalam model. Ini adalah khususnya berguna untuk meningkatkan hitungan berdasarkan pada nilai saat ini mereka. Sebagai contoh, untuk menaikkan hitungan pingback untuk setiap masukan dalam blog:

    >>> Entry.objects.all().update(n_pingbacks=F('n_pingbacks') + 1)

Bagaimanapun, tidak seperti obyek `F()` dalam penyaringan dan tidak menyertakan klausa-klausa, anda tidak dapat memperkenalkan penggabungan ketika anda menggunakan obyek `F()` dalam sebuah pembaharuan -- anda hanya dapat mengacu bidang-bidang lokal ke model sedang diperbaharui. Jika anda berusaha memperkenalkan penggabungan dengan sebuah obyek `F()`, sebuah `FieldError` akan dimunculkan:

    # This will raise a FieldError
    >>> Entry.objects.update(headline=F('blog__name'))

## Obyek terkait

Ketika anda menentukan hubungan dalam sebuah model (yaitu, sebuah `ForeignKey`, `OneToOneField`, atau `ManyToManyField`), instance-instance dari model itu akan mempunyai API cocok untuk mengakses obyek terkait.

Menggunakan model-model diatas dari halaman ini, sebagai contoh, sebuah obyek `Entry` `c` dapat mendapatkan obyek `Blog` berhubungan dengan mengakses atribut `blog`: `e.blog`.

(Dibelakang layar, kegunaan ini diterapkan oleh descriptors Python. Ini tidak tidak masalah buat anda, tetapi kami menunjuk disini untuk keganjilan.)

Django juga membuat pengakses API untuk sisi "lain" dari hubungan -- tautan dari model terkait ke model yang menentukan hubungan. Sebagai contoh, obyek `Blog` `b` mempunyai akses ke daftar dari semua obyek `Entry` terkait melalui atribut `entry_set`: `b.entry_set.all()`.

Semua contoh dalam bagian ini menggunakan contoh model `Blog`, `Author` and `Entry` ditentukan pada atas dari halaman ini.

### Hubungan satu-ke-banyak

#### Meneruskan

Jika sebuah model mempunyai `ForeignKey`, instance dari model tersebut akan mempunyai akses ke obyek (asing) terkait melalui atribut sederhana dari model.

Contoh:

    >>> e = Entry.objects.get(id=2)
    >>> e.blog # Returns the related Blog object.

Anda daat mendapatkan dan menyetel melalui atribut foreign-key. Seperti anda mungkin harapkan, perubahan pada foreign key tidak disimpan ke basisdata sampai anda memanggil `save()`. Contoh:

    >>> e = Entry.objects.get(id=2)
    >>> e.blog = some_blog
    >>> e.save()

Jika sebuah bidang `ForeignKey` mempunyai `null=True` disetel (yaitu nilai `NULL`), anda dapat memberikan `None` untuk memindahkan hubungan. Contoh:

    >>> e = Entry.objects.get(id=2)
    >>> e.blog = None
    >>> e.save() # "UPDATE blog_entry SET blog_id = NULL ...;"

Akses mengirimkan ke hubungan one-to-many disimpan sementara pada kali pertama obyek terkait diakses. Akses selanjutnya ke foreign key pada instance obyek sama disimpan sementara. Contoh:

    >>> e = Entry.objects.get(id=2)
    >>> print(e.blog)  # Hits the database to retrieve the associated Blog.
    >>> print(e.blog)  # Doesn't hit the database; uses cached version.

Catat bahwa `select_related()` metode `QuerySet` berulang mengisi dimuka cache dari semua hubungan one-to-many sebelumnya. Contoh:

    >>> e = Entry.objects.select_related().get(id=2)
    >>> print(e.blog)  # Doesn't hit the database; uses cached version.
    >>> print(e.blog)  # Doesn't hit the database; uses cached version.

#### Mengikuti hubungan ""ke belakang"

Jika model mempunyai `ForeignKey`, instance-instance dari model foreign-key akan mempunyai akses ke `Manager` yang mengembalikan semua instance dari model pertama. Secara awalan, `Manager` ini dinamai `FOO_set`, dimana `FOO` adalah nama model sumber, huruf kecil. `Manager` ini mengembalikan `QuerySets`, yang dapat disaring dan dirubah seperti digambarkan dalam bagian "Mengambil obyek" diatas.

Contoh:

    >>> b = Blog.objects.get(id=1)
    >>> b.entry_set.all() # Returns all Entry objects related to Blog.

    # b.entry_set is a Manager that returns QuerySets.
    >>> b.entry_set.filter(headline__contains='Lennon')
    >>> b.entry_set.count()

Anda dapat menimpa nama `FOO_set` dengan mengatur parameter `related_name` dalam penentuan `ForeignKey` . Sebagai contoh, jika model `Entry` telah diubah pada `blog = ForeignKey(Blog, on_delete=models.CASCADE, related_name='entries')`, contoh kode diatas akan terlihat seperti ini:

    >>> b = Blog.objects.get(id=1)
    >>> b.entries.all() # Returns all Entry objects related to Blog.

    # b.entries is a Manager that returns QuerySets.
    >>> b.entries.filter(headline__contains='Lennon')
    >>> b.entries.count()

#### Menggunakan sebuah penyesuaian pengelola membalikkan

Secara awalan `RelatedManager` digunakan untuk hubungan balikan adalah sebuah subkelas dari default manager 1 untuk model itu. Jika anda ingin menentukan pengelola berbeda untuk permintaan yang diberikan anda dapat menggunakan sintaksis berikut:

    from django.db import models

    class Entry(models.Model):
        #...
        objects = models.Manager()  # Default Manager
        entries = EntryManager()    # Custom Manager

    b = Blog.objects.get(id=1)
    b.entry_set(manager='entries').all()

Jika `EntryManager` melakukan penyaringan awalan dalam metode `get_queryset()` nya, bahwa penyaring akan berlaku ke panggilan `all()`.

Tentu saja, menentukan pengelola balikan penyesuaian juga mengadakan anda memanggil metode penyesuaiannya:

    b.entry_set(manager='entries').is_published()

#### Cara tambahan untuk menangani obyek terkait

Sebagai tambahan pada metode `QuerySet` ditentukan dalam "Mengambil obyek" diatas, `ForeignKey` `Manager` mempunyai metode-metode tambahan digunakan untuk menangangi kumpulan dari obyek-obyek terkait. Sebuah ringkasan dari masing-masing dibawah, dan rincian lengkap dapat ditemukan dalam related objects reference 1.

`tambah(obj1, obj2, ...)`
  Menambahkan obyek model ditentukan ke kumpulan obyek terkait.
`buat(**kwargs)`
  Membuat obyek baru, menyimpannya dan menaruhnya dalam kumpulan obyek terkait. Mengembalikan obyek dibuat terbaru.
`pindahkan(obj1, obj2, ...)`
  Pindahkan obyek model ditentukan dari kumpulan obyek terkait.
`clear()`
  Pindahkan semua obyek dari kumpulan obyek terkait.
`set(objs)`
  Ganti kumpulan dari obyek terkait.

To assign the members of a related set, use the `set()` method with an iterable of object instances. For example, if `e1` and `e2` are `Entry` instances:

    b = Blog.objects.get(id=1)
    b.entry_set.set([e1, e2])

Jika metode `clear()` tersedia, apapun obyek pra-ada akan dipindahkan dari `entry_set` sebelum semua obyek dalam perulangan (dalam kasus ini, sebuah daftar) ditambahkan ke kumpulan. Jika metode `clear()` tidak tersedia, semua obyek dalam perulangan akan ditambahan tanpa memindahkan unsur-unsur apapun yang ada.

Setiap tindakan "reverse" digambarkan dalam bagian ini mempunyai pengaruh segera pada basisdata. Setiap penambahan, pembuatan dan penghapusan segera dan otomatis disimpan ke basisdata.

### Hubungan banyak-ke-banyak

Both ends of a many-to-many relationship get automatic API access to the other end. The API works similar to a "backward" one-to-many relationship, above.

One difference is in the attribute naming: The model that defines the `ManyToManyField` uses the attribute name of that field itself, whereas the "reverse" model uses the lowercased model name of the original model, plus `'_set'` (just like reverse one-to-many relationships).

Sebuah contoh membuatnya mudah untuk dipahami:

    e = Entry.objects.get(id=3)
    e.authors.all() # Returns all Author objects for this Entry.
    e.authors.count()
    e.authors.filter(name__contains='John')

    a = Author.objects.get(id=5)
    a.entry_set.all() # Returns all Entry objects for this Author.

Seeprti `ForeignKey`, `ManyToManyField` dapat menentukan `related_name`. Dalam contoh diatas, jika `ManyToManyField` di `Entry` telah menentukan `related_name='entries'`, kemudian setiap instance `Author` akan memiliki sebuah atribut `entries` daripada `entry_set`.

Another difference from one-to-many relationships is that in addition to model instances, the `add()`, `set()`, and `remove()` methods on many-to-many relationships accept primary key values. For example, if `e1` and `e2` are `Entry` instances, then these `set()` calls work identically:

    a = Author.objects.get(id=5)
    a.entry_set.set([e1, e2])
    a.entry_set.set([e1.pk, e2.pk])

### Hubungan satu-ke-satu

Hubungan one-to-one sangat mirip ke hubungan many-to-one. Jika anda menentukan `OneToOneField` di model anda, instance-instance dari model itu akan mempunyai akses ke obyek terkait melalui atribut sederhana dari model.

Sebagai contoh:

    class EntryDetail(models.Model):
        entry = models.OneToOneField(Entry, on_delete=models.CASCADE)
        details = models.TextField()

    ed = EntryDetail.objects.get(id=2)
    ed.entry # Returns the related Entry object.

Perbedaan datang dalam permintaan "reverse". Model terkait dalam hubungan one-to-one juga mempunyai akses ke obyek `Manager`, tetapi `Manager` itu mewakili obyek tunggal, daripada sebuah kumpulan obyek-obyek:

    e = Entry.objects.get(id=2)
    e.entrydetail # returns the related EntryDetail object

Jika tidak ada obyek diberikan ke hubungan ini, Django akan memunculkan pengecualian `DoesNotExist`.

Instance-instance dapat diberikan ke hubungan balikan dalam cara sama seperti anda akan memberikan meneruskan hubungan:

    e.entrydetail = ed

### Bagaimana hubungan kebelakang dimungkinkan?

Pemeta hubungan-obyek lainnya membutuhkan anda menentukan hubungan pada kedua sisi. Pengembang Django percaya ini adalah pelanggaran dari prinsip DRY (Don't Repeat Yourself), jadi Django hanya membutuhkan anda menentukan hubungan pada satu akhiran.

Tetapi bagaimana ini mungkin, memberikan itu kelas model yang tidak mengetahui mana kelas-kelas model lain terkait ke itu sampai kelas-kelas model lain tersebut dimuat?

Jawaban terletak di `app registry`. Ketika Django mulai, itu mengimpor setiap aplikasi terdaftar di `INSTALLED_APPS`, dan kemudian modul `models` didalam setiap aplikasi. Kapanpun sebuah kelas model dibuat, Django menambahkan hubungan-kebelakang ke setiap model terkait. Jika model terkait belum diimpor, Django menjaga jalur dari hubungan dan menambahkan mereka ketika model terkait akhirnya diimpor.

Untuk alasan ini, itu adalah khususnya penting bahwa semua model anda sedang gunakan ditentukan dalam aplikasi terdaftar dalam `INSTALLED_APPS`. Sebaliknya, hubungan kebelakang mungkin tidak bekerja dengan benar.

### Meminta terhadap obyek terkait

Permintaan melibatkan obyek-obyek terkait mengikuti aturan sama seperti permintaan melibatkan bidang-bidang nilai biasa. Ketika menentukan nilai untuk permintaan untuk pencocokan, anda mungkin menggunakan salah satu instance obyek itu sendiri, atau nilai primary key untuk obyek.

Sebagai contoh, jika anda mempunyai sebuah obyek Blog `b` dengan `id=5`, tiga permintaan berikut akan mirip:

    Entry.objects.filter(blog=b) # Query using object instance
    Entry.objects.filter(blog=b.id) # Query using id from instance
    Entry.objects.filter(blog=5) # Query using id directly

## Kembali ke mentah SQL

Jika anda menemukan anda sendiri butuh menulis permintaan SQL yang terlalu rumit untuk pemetaan-basisdata Django untuk ditangani, anda dapat kembali menulis SQL dengan tangan. Django mempunyai sepasang pilihan untuk menulis permintaan SQL mentah; lihat Melakukan permintaan SQL mentah.

Akhirnya, itu penting dicatat bahwa lapisan basisdata Django hanya antarmuka ke basisdata anda. Anda dapat mengakses basisdata anda melalui alat-alat lain, bahasa pemrograman atau kerangka basisdata; tidak ada spesifik-Django tentang basisdata anda.