---
title: "Membuat query"
version: 3.2
locale: id
source: https://docs.djangoproject.com/id/3.2/topics/db/queries/
canonical: https://djangodocs.dev/id/3.2/topics/db/queries/
---
# 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:

```python
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)
    number_of_comments = models.IntegerField()
    number_of_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()`](/id/3.2/ref/models/instances/#django.db.models.Model.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()`](/id/3.2/ref/models/instances/#django.db.models.Model.save).

Cara [`save()`](/id/3.2/ref/models/instances/#django.db.models.Model.save) tidak mempunyai nilai kembalian.

> **See also**
>
> [`save()`](/id/3.2/ref/models/instances/#django.db.models.Model.save) mengambil sejumalh pilihan keuntungan tidak digambarkan disini. Lihat dokumentasi untuk [`save()`](/id/3.2/ref/models/instances/#django.db.models.Model.save) untuk rincian lengkap.
>
> Untuk membuat dan menyimpan sebuah obyek dalam langkah tunggal, gunakan cara [`create()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.create).

## Menyimpan perubahan ke obyek

Untuk menyimpan perubahan ke sebuah obyek yang sudah ada di basisdata gunakan [`save()`](/id/3.2/ref/models/instances/#django.db.models.Model.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()`](/id/3.2/ref/models/instances/#django.db.models.Model.save).

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

Updating a [`ForeignKey`](/id/3.2/ref/models/fields/#django.db.models.ForeignKey) field works exactly the same
way as saving a normal field -- assign an object of the right type to the field
in question. This example updates the `blog` attribute of an `Entry`
instance `entry`, assuming appropriate instances of `Entry` and `Blog`
are already saved to the database (so we can retrieve them below):

```
>>> 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`](/id/3.2/ref/models/fields/#django.db.models.ManyToManyField) bekerja sedikit berbeda -- gunakan metode [`add()`](/id/3.2/ref/models/relations/#django.db.models.fields.related.RelatedManager.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`](/id/3.2/ref/models/fields/#django.db.models.ManyToManyField) dalam sekali pergi, sertakan banyak argumen dalam panggilan pada [`add()`](/id/3.2/ref/models/relations/#django.db.models.fields.related.RelatedManager.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`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) melalui [`Manager`](/id/3.2/topics/db/managers/#django.db.models.Manager) pada kelas model anda.

Sebuah [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.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`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) menyamakan pada pernyataan `SELECT`, dan penyaring membatasi klausa seperti `WHERE` atau `LIMIT`.

Anda mendapatkan [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) dengan menggunakan [`Manager`](/id/3.2/topics/db/managers/#django.db.models.Manager) model anda. Setiap model mempunyai setidaknya satu [`Manager`](/id/3.2/topics/db/managers/#django.db.models.Manager), dan itu memanggil [`objects`](/id/3.2/ref/models/class/#django.db.models.Model.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."
```

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

[`Manager`](/id/3.2/topics/db/managers/#django.db.models.Manager) adalah sumber utama dari `QuerySets` untuk sebuah model. Sebagai contoh, `Blog.objects.all()` mengembalikan [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.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()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.all) pada sebuah [`Manager`](/id/3.2/topics/db/managers/#django.db.models.Manager):

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

Metode [`all()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.all) mengembalikan semua [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) dari semua obyek dalam basisdata.

### Mengambil obyek spesifik dengan menyaring

[`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) dibalikkan oleh [`all()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.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`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) awalan, menambahkan kondisi penyaringan. Dua cara paling umum untuk menyaring [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) adalah:

**`filter(**kwargs)`**

  Mengembalikan [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) baru mengandung obyek-obyek yang cocok dari parameter pencarian yang diberikan.

**`exclude(**kwargs)`**

  Mengembalikan [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.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](#field-lookups) dibawah.

Sebagai contoh, untuk mendapatkan [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) dari masukan blog dari tahun 2006, gunakan [`filter()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.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`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) adalah itu sendiri [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.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`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) dari semua masukan dalam basisdata, tambah sebuah penyaring, kemudian sebuah pengecualian, kemudian penyaring lain. Hasil akhir adalah sebuah [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.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`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet), anda mendapatkan [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) merek-baru yaitu tidak ada cara mengikat ke [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) sebelumnya. Setiap penyaringan membuat [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.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`](/id/3.2/ref/models/querysets/#django.db.models.query.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`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) (`q1`) tidak terpengaruh dengan pengolahan penyaringan.

#### `QuerySet` adalah lazy

`QuerySets` adalah lazy -- tindakan dari membuat [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) tidak melibatkan aktifitas basisdata apapun. Anda dapat menumpuk penyaring bersama-sama sepanjang hari, dan Django tidak sebenarnya menjalankan permintaan sampai [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.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`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) tidak diambil dari basisdata sampai anda "meminta" untuk mereka. Ketika anda melakukan, [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) *dinilai* dengan mengakses basisdata. Untuk rincian lebih pada sebenarnya ketika penilaian mengambil tempat, lihat [Ketika QuerySet dinilai](/id/3.2/ref/models/querysets/#when-querysets-are-evaluated).

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

[`filter()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.filter) akan selalu memberikan anda [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet), bahkan jika hanya obyek tunggal yang cocok permintaan - dalam kasus ini, itu akan berupa [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.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`](/id/3.2/topics/db/managers/#django.db.models.Manager) yang mengembalikan obyek secara langsung:

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

Anda dapat menggunakan pernyataan permintaan apapun dengan [`get()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.get), seperti dengan [`filter()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.filter) \- kembali, lihat [Field lookups](#field-lookups) dibawah.

Catat bahwa ada perbedaan diantara menggunakan [`get()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.get), dan menggunakan [`filter()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.filter) dengan potongan `[0]`. Jika tidak ada hasil yang cocok dengan permintaan, [`get()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.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()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.get). Dalam kasus ini, itu akan memunculkan [`MultipleObjectsReturned`](/id/3.2/ref/exceptions/#django.core.exceptions.MultipleObjectsReturned), yang kembali adalah sebuah atribut dari kelas model itu sendiri.

### Cara `QuerySet` lain

Kebanyakan waktu anda akan gunakan [`all()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.all), [`get()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.get), [`filter()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.filter) dan [`exclude()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.exclude) ketika anda butuh mencari obyek-obyek dari basisdata. Bagaimanapun, itu jauh dari semua yang ada; lihat [QuerySet API Reference](/id/3.2/ref/models/querysets/#queryset-api) untuk daftar lengkap dari semua ragam metode [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet).

### Membatasi `QuerySet`

Gunakan sub kumpulan dari sintaksis memotong-array Python untuk membatasi [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.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`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) mengembalikan [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.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.

To retrieve a *single* object rather than a list
(e.g. `SELECT foo FROM bar LIMIT 1`), use an index instead of a slice. For
example, this returns the first `Entry` in the database, after ordering
entries alphabetically by headline:

```
>>> 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()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.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`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) metode metode [`filter()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.filter), [`exclude()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.exclude) dan [`get()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.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:

```sql
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](https://docs.python.org/3/tutorial/controlflow.html#tut-keywordargs) dalam tutorial Python resmi.

Bidang ditentukan dalam pencarian harus berupa nama dari bidang model. meskipun ada satu pengecualian, dalam kasus dari [`ForeignKey`](/id/3.2/ref/models/fields/#django.db.models.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`](/id/3.2/ref/models/querysets/#std-fieldlookup-exact)**

  Sebuah pencocokan "tepat". Sebagai contoh:

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

  Akan membangkitkan SQL bersama baris ini:

  ```sql
  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`](/id/3.2/ref/models/querysets/#std-fieldlookup-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`](/id/3.2/ref/models/querysets/#std-fieldlookup-contains)**

  Percobaan penahanan kasus-peka . Sebagai contoh:

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

  Kurang lebih menterjemahkan ke SQL ini:

  ```sql
  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`](/id/3.2/ref/models/querysets/#std-fieldlookup-icontains).

**[`startswith`](/id/3.2/ref/models/querysets/#std-fieldlookup-startswith), [`endswith`](/id/3.2/ref/models/querysets/#std-fieldlookup-endswith)**

  Pencarian mulai-dengan dan berakhir-dengan, masing-masing. Ada juga versi kasus-tidak-peka dipanggil [`istartswith`](/id/3.2/ref/models/querysets/#std-fieldlookup-istartswith) dan [`iendswith`](/id/3.2/ref/models/querysets/#std-fieldlookup-iendswith).

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

### Pencarian yang menjangkau hubungan

Django offers a powerful and intuitive way to "follow" relationships in
lookups, taking care of the SQL `JOIN`s for you automatically, behind the
scenes. To span a relationship, use the field name of related fields
across models, separated by double underscores, until you get to the field you
want.

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.

It works backwards, too. While it [`can be customized`](/id/3.2/ref/models/fields/#django.db.models.ForeignKey.related_query_name), by default you refer to a "reverse"
relationship in a lookup using the lowercase name of the 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`](/id/3.2/ref/models/querysets/#std-fieldlookup-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`](/id/3.2/ref/models/fields/#django.db.models.ManyToManyField) atau membalikkan [`ForeignKey`](/id/3.2/ref/models/fields/#django.db.models.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`](/id/3.2/ref/models/fields/#django.db.models.ManyToManyField). Sebagai contoh, jika sebuah `Entry` mempunyai [`ManyToManyField`](/id/3.2/ref/models/fields/#django.db.models.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()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.filter). Apapun didalam panggilan [`filter()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.filter) tunggal diberlakukan secara terus menerus untuk menyaring barang-barang mencocokkan semua lingkungan tersebut. Panggilan [`filter()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.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()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.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`.

> **Note**
>
> Perilaku dari [`filter()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.filter) untuk permintaan yang menjangkau hubungan banyak-nilai, seperti digambarkan diatas, tidak diterapkan setara untuk [`exclude()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.exclude). Malahan, keadaan dalam panggilan [`exclude()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.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()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.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`](/id/3.2/ref/models/expressions/#django.db.models.F) 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(number_of_comments__gt=F('number_of_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(number_of_comments__gt=F('number_of_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('number_of_comments') + F('number_of_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`](https://docs.python.org/3/library/datetime.html#datetime.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))
```

The `F()` objects support bitwise operations by `.bitand()`, `.bitor()`,
`.bitxor()`, `.bitrightshift()`, and `.bitleftshift()`. For example:

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

> **Oracle**
>
> Oracle doesn't support bitwise XOR operation.

> **Changed in Django 3.1**
>
> Support for `.bitxor()` was added.

### Expressions can reference transforms

> **New in Django 3.2**

Django supports using transforms in expressions.

For example, to find all `Entry` objects published in the same year as they
were last modified:

```
>>> Entry.objects.filter(pub_date__year=F('mod_date__year'))
```

To find the earliest year an entry was published, we can issue the query:

```
>>> Entry.objects.aggregate(first_published_year=Min('pub_date__year'))
```

This example finds the value of the highest rated entry and the total number
of comments on all entries for each year:

```
>>> Entry.objects.values('pub_date__year').annotate(
...     top_rating=Subquery(
...         Entry.objects.filter(
...             pub_date__year=OuterRef('pub_date__year'),
...         ).order_by('-rating').values('rating')[:1]
...     ),
...     total_comments=Sum('number_of_comments'),
... )
```

### 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.)

This means things should work intuitively, so the abstraction doesn't leak.
For example, to retrieve all the entries that contain a percent sign, use the
percent sign as any other character:

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

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

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

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

### Cache dan `QuerySet`

Setiap [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) mengandung sebuah tembolok untuk meminimalkan akses basisdata. Pahami bagaimana dia bekerja akan mengizinkan anda menulis kode paling efisien.

Dalam [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) baru dibuat, cache kosong. Pertama kali sebuah [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) dinilai -- dan, karena itu, sebuah permintaan basisdata terjadi -- Django menyimpan hasil permintaan dalam cache [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) dan mengembalikan hasil yang telah secara jelas diminta (sebagai contoh, unsur selanjutnya, jika ada [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) sedang diulang). Penilaian selanjutnya dari [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) menggunakan hasil ter cache.

Jaga perilaku cache ini dalam pikiran, karena itu mungkin mengigit anda jika anda tidak menggunakan [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) anda dengan benar. Sebagai contoh, berikut akan membuat dua [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.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 menghindati masalah, simpan [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) dan gunakan itu:

```
>>> 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)
```

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

## Meminta `JSONField`

Lookups implementation is different in [`JSONField`](/id/3.2/ref/models/fields/#django.db.models.JSONField),
mainly due to the existence of key transformations. To demonstrate, we will use
the following example model:

```
from django.db import models

class Dog(models.Model):
    name = models.CharField(max_length=200)
    data = models.JSONField(null=True)

    def __str__(self):
        return self.name
```

### Storing and querying for `None`

As with other fields, storing `None` as the field's value will store it as
SQL `NULL`. While not recommended, it is possible to store JSON scalar
`null` instead of SQL `NULL` by using [`Value('null')`](/id/3.2/ref/models/expressions/#django.db.models.Value).

Whichever of the values is stored, when retrieved from the database, the Python
representation of the JSON scalar `null` is the same as SQL `NULL`, i.e.
`None`. Therefore, it can be hard to distinguish between them.

This only applies to `None` as the top-level value of the field. If `None`
is inside a [`list`](https://docs.python.org/3/library/stdtypes.html#list) or [`dict`](https://docs.python.org/3/library/stdtypes.html#dict), it will always be interpreted
as JSON `null`.

When querying, `None` value will always be interpreted as JSON `null`. To
query for SQL `NULL`, use [`isnull`](/id/3.2/ref/models/querysets/#std-fieldlookup-isnull):

```
>>> Dog.objects.create(name='Max', data=None)  # SQL NULL.
<Dog: Max>
>>> Dog.objects.create(name='Archie', data=Value('null'))  # JSON null.
<Dog: Archie>
>>> Dog.objects.filter(data=None)
<QuerySet [<Dog: Archie>]>
>>> Dog.objects.filter(data=Value('null'))
<QuerySet [<Dog: Archie>]>
>>> Dog.objects.filter(data__isnull=True)
<QuerySet [<Dog: Max>]>
>>> Dog.objects.filter(data__isnull=False)
<QuerySet [<Dog: Archie>]>
```

Unless you are sure you wish to work with SQL `NULL` values, consider setting
`null=False` and providing a suitable default for empty values, such as
`default=dict`.

> **Note**
>
> Storing JSON scalar `null` does not violate [`null=False`](/id/3.2/ref/models/fields/#django.db.models.Field.null).

### Key, index, and path transforms

To query based on a given dictionary key, use that key as the lookup name:

```
>>> Dog.objects.create(name='Rufus', data={
...     'breed': 'labrador',
...     'owner': {
...         'name': 'Bob',
...         'other_pets': [{
...             'name': 'Fishy',
...         }],
...     },
... })
<Dog: Rufus>
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': None})
<Dog: Meg>
>>> Dog.objects.filter(data__breed='collie')
<QuerySet [<Dog: Meg>]>
```

Banyak kunci dapat diikat bersama untuk membentuk pencarian jalur:

```
>>> Dog.objects.filter(data__owner__name='Bob')
<QuerySet [<Dog: Rufus>]>
```

If the key is an integer, it will be interpreted as an index transform in an
array:

```
>>> Dog.objects.filter(data__owner__other_pets__0__name='Fishy')
<QuerySet [<Dog: Rufus>]>
```

If the key you wish to query by clashes with the name of another lookup, use
the [`contains`](#std-fieldlookup-jsonfield.contains) lookup instead.

Permintaan untuk kunci hilang, gunakan pencarian `isnull`:

```
>>> Dog.objects.create(name='Shep', data={'breed': 'collie'})
<Dog: Shep>
>>> Dog.objects.filter(data__owner__isnull=True)
<QuerySet [<Dog: Shep>]>
```

> **Note**
>
> The lookup examples given above implicitly use the [`exact`](/id/3.2/ref/models/querysets/#std-fieldlookup-exact) lookup.
> Key, index, and path transforms can also be chained with:
> [`icontains`](/id/3.2/ref/models/querysets/#std-fieldlookup-icontains), [`endswith`](/id/3.2/ref/models/querysets/#std-fieldlookup-endswith), [`iendswith`](/id/3.2/ref/models/querysets/#std-fieldlookup-iendswith),
> [`iexact`](/id/3.2/ref/models/querysets/#std-fieldlookup-iexact), [`regex`](/id/3.2/ref/models/querysets/#std-fieldlookup-regex), [`iregex`](/id/3.2/ref/models/querysets/#std-fieldlookup-iregex), [`startswith`](/id/3.2/ref/models/querysets/#std-fieldlookup-startswith),
> [`istartswith`](/id/3.2/ref/models/querysets/#std-fieldlookup-istartswith), [`lt`](/id/3.2/ref/models/querysets/#std-fieldlookup-lt), [`lte`](/id/3.2/ref/models/querysets/#std-fieldlookup-lte), [`gt`](/id/3.2/ref/models/querysets/#std-fieldlookup-gt), and
> [`gte`](/id/3.2/ref/models/querysets/#std-fieldlookup-gte), as well as with [Containment and key lookups](#containment-and-key-lookups).

> **Note**
>
> Due to the way in which key-path queries work,
> [`exclude()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.exclude) and
> [`filter()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.filter) are not guaranteed to
> produce exhaustive sets. If you want to include objects that do not have
> the path, add the `isnull` lookup.

> **Warning**
>
> Sejak string apapun dapat berupa kunci dalam obyek JSON, pencarian apapun selain dari mereka didaftarkan dibawah akan diterjemahkan sebagai pencarian kunci. Tidak ada kesalahan dimunculkan. Waspadalah untuk mengetik kesalahan, dan selalu memeriksa permintaan anda bekerja seperti anda hendaki.

> **MariaDB and Oracle users**
>
> Using [`order_by()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.order_by) on key, index, or
> path transforms will sort the objects using the string representation of
> the values. This is because MariaDB and Oracle Database do not provide a
> function that converts JSON values into their equivalent SQL values.

> **Oracle users**
>
> On Oracle Database, using `None` as the lookup value in an
> [`exclude()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.exclude) query will return objects
> that do not have `null` as the value at the given path, including objects
> that do not have the path. On other database backends, the query will
> return objects that have the path and the value is not `null`.

> **PostgreSQL users**
>
> On PostgreSQL, if only one key or index is used, the SQL operator `->` is
> used. If multiple operators are used then the `#>` operator is used.

### Containment and key lookups

#### `contains`

The [`contains`](/id/3.2/ref/models/querysets/#std-fieldlookup-contains) lookup is overridden on `JSONField`. The returned
objects are those where the given `dict` of key-value pairs are all
contained in the top-level of the field. For example:

```
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'})
<Dog: Rufus>
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
<Dog: Meg>
>>> Dog.objects.create(name='Fred', data={})
<Dog: Fred>
>>> Dog.objects.filter(data__contains={'owner': 'Bob'})
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>
>>> Dog.objects.filter(data__contains={'breed': 'collie'})
<QuerySet [<Dog: Meg>]>
```

> **Oracle and SQLite**
>
> `contains` is not supported on Oracle and SQLite.

#### `contained_by`

This is the inverse of the [`contains`](#std-fieldlookup-jsonfield.contains) lookup - the
objects returned will be those where the key-value pairs on the object are a
subset of those in the value passed. For example:

```
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'})
<Dog: Rufus>
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
<Dog: Meg>
>>> Dog.objects.create(name='Fred', data={})
<Dog: Fred>
>>> Dog.objects.filter(data__contained_by={'breed': 'collie', 'owner': 'Bob'})
<QuerySet [<Dog: Meg>, <Dog: Fred>]>
>>> Dog.objects.filter(data__contained_by={'breed': 'collie'})
<QuerySet [<Dog: Fred>]>
```

> **Oracle and SQLite**
>
> `contained_by` is not supported on Oracle and SQLite.

#### `has_key`

Returns objects where the given key is in the top-level of the data. For
example:

```
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
<Dog: Rufus>
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
<Dog: Meg>
>>> Dog.objects.filter(data__has_key='owner')
<QuerySet [<Dog: Meg>]>
```

#### `has_keys`

Returns objects where all of the given keys are in the top-level of the data.
For example:

```
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
<Dog: Rufus>
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
<Dog: Meg>
>>> Dog.objects.filter(data__has_keys=['breed', 'owner'])
<QuerySet [<Dog: Meg>]>
```

#### `has_any_keys`

Returns objects where any of the given keys are in the top-level of the data.
For example:

```
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
<Dog: Rufus>
>>> Dog.objects.create(name='Meg', data={'owner': 'Bob'})
<Dog: Meg>
>>> Dog.objects.filter(data__has_any_keys=['owner', 'breed'])
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>
```

## Pencarian rumit dengan obyek `Q`

Permintaan argumen katakunci -- dalam [`filter()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.filter), dll. -- adalah "AND" bersama-sama. Jika anda buth menjalankan permintaan lebih rumit (sebagai contoh, permintaan dengan pernyataan `OR`), anda dapat menggunakan [`Q objects`](/id/3.2/ref/models/querysets/#django.db.models.Q).

[`Q object`](/id/3.2/ref/models/querysets/#django.db.models.Q) (`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()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.filter), [`exclude()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.exclude), [`get()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.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 diterjemahkan kedalam SQL:

```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.

> **See also**
>
> The [OR lookups examples](https://github.com/django/django/blob/stable/3.2.x/tests/or_lookups/tests.py) in Django's
> unit tests show some possible uses of `Q`.

## Membandingkan obyek

To compare two model instances, use the standard Python comparison operator,
the double equals sign: `==`. Behind the scenes, that compares the primary
key values of two models.

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()`](/id/3.2/ref/models/instances/#django.db.models.Model.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`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) mempunyai sebuah [`delete()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.delete) method, yang menghapus semua anggota dari [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.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`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) dan memanggil `delete()` pada setiap obyek secara tersendiri) daripada menggunakan dalam jumlah besar cara [`delete()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.delete) dari sebuah [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.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`](/id/3.2/ref/models/fields/#django.db.models.ForeignKey.on_delete) ke [`ForeignKey`](/id/3.2/ref/models/fields/#django.db.models.ForeignKey).

Catat bahwa [`delete()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.delete) adalah hanya cara [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) yang tidak ditunjukkan pada [`Manager`](/id/3.2/topics/db/managers/#django.db.models.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

Although there is no built-in method for copying model instances, it is
possible to easily create new instance with all fields' values copied. In the
simplest case, you can set `pk` to `None` and
[`_state.adding`](/id/3.2/ref/models/instances/#django.db.models.Model._state) to `True`. Using our
blog example:

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

blog.pk = None
blog._state.adding = True
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
```

Due to how inheritance works, you have to set both `pk` and `id` to
`None`, and `_state.adding` to `True`:

```
django_blog.pk = None
django_blog.id = None
django_blog._state.adding = True
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._state.adding = True
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._state.adding = True
detail.entry = entry
detail.save()
```

## Memperbaharui banyak obyek sekaligus

Terkadang anda ingin menyetel sebuah bidang ke nilai tertentu untuk semua obyek dalam [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet). Anda dapat melakukan ini dengan cara [`update()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.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`](/id/3.2/ref/models/fields/#django.db.models.ForeignKey) menggunakan metode ini. Untuk memperbaharui bidang-bidang [`ForeignKey`](/id/3.2/ref/models/fields/#django.db.models.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`](/id/3.2/ref/models/querysets/#django.db.models.query.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.filter(blog=b).update(headline='Everything is the same')
```

Be aware that the `update()` method is converted directly to an SQL
statement. It is a bulk operation for direct updates. It doesn't run any
[`save()`](/id/3.2/ref/models/instances/#django.db.models.Model.save) methods on your models, or emit the
`pre_save` or `post_save` signals (which are a consequence of calling
[`save()`](/id/3.2/ref/models/instances/#django.db.models.Model.save)), or honor the
[`auto_now`](/id/3.2/ref/models/fields/#django.db.models.DateField.auto_now) field option.
If you want to save every item in a [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet)
and make sure that the [`save()`](/id/3.2/ref/models/instances/#django.db.models.Model.save) method is called on
each instance, you don't need any special function to handle that. Loop over
them and call [`save()`](/id/3.2/ref/models/instances/#django.db.models.Model.save):

```
for item in my_queryset:
    item.save()
```

Panggilan untuk memperbaharui juga menggunakan [`F expressions`](/id/3.2/ref/models/expressions/#django.db.models.F) 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(number_of_pingbacks=F('number_of_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`](/id/3.2/ref/models/fields/#django.db.models.ForeignKey), [`OneToOneField`](/id/3.2/ref/models/fields/#django.db.models.OneToOneField), atau [`ManyToManyField`](/id/3.2/ref/models/fields/#django.db.models.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`.

(Behind the scenes, this functionality is implemented by Python
[descriptors](https://docs.python.org/3/howto/descriptor.html). This shouldn't really matter to
you, but we point it out here for the curious.)

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

If a model has a [`ForeignKey`](/id/3.2/ref/models/fields/#django.db.models.ForeignKey), instances of that model
will have access to the related (foreign) object via an attribute of the 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()`](/id/3.2/ref/models/instances/#django.db.models.Model.save). Contoh:

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

Jika sebuah bidang [`ForeignKey`](/id/3.2/ref/models/fields/#django.db.models.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()`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet.select_related) metode [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.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`](/id/3.2/ref/models/fields/#django.db.models.ForeignKey), instance-instance dari model foreign-key akan mempunyai akses ke [`Manager`](/id/3.2/topics/db/managers/#django.db.models.Manager) yang mengembalikan semua instance dari model pertama. Secara awalan, [`Manager`](/id/3.2/topics/db/managers/#django.db.models.Manager) ini dinamai `FOO_set`, dimana `FOO` adalah nama model sumber, huruf kecil. [`Manager`](/id/3.2/topics/db/managers/#django.db.models.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`](/id/3.2/ref/models/fields/#django.db.models.ForeignKey.related_name) dalam penentuan [`ForeignKey`](/id/3.2/ref/models/fields/#django.db.models.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`](/id/3.2/ref/models/relations/#django.db.models.fields.related.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()`.

Specifying a custom reverse manager also enables you to call its custom
methods:

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

#### Cara tambahan untuk menangani obyek terkait

Sebagai tambahan pada metode [`QuerySet`](/id/3.2/ref/models/querysets/#django.db.models.query.QuerySet) ditentukan dalam "Mengambil obyek" diatas, [`ForeignKey`](/id/3.2/ref/models/fields/#django.db.models.ForeignKey) [`Manager`](/id/3.2/topics/db/managers/#django.db.models.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`](/id/3.2/ref/models/fields/#django.db.models.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`](/id/3.2/ref/models/fields/#django.db.models.ForeignKey), [`ManyToManyField`](/id/3.2/ref/models/fields/#django.db.models.ManyToManyField) dapat menentukan [`related_name`](/id/3.2/ref/models/fields/#django.db.models.ManyToManyField.related_name). Dalam contoh diatas, jika [`ManyToManyField`](/id/3.2/ref/models/fields/#django.db.models.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

One-to-one relationships are very similar to many-to-one relationships. If you
define a [`OneToOneField`](/id/3.2/ref/models/fields/#django.db.models.OneToOneField) on your model, instances of
that model will have access to the related object via an attribute of the
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`](/id/3.2/topics/db/managers/#django.db.models.Manager), tetapi [`Manager`](/id/3.2/topics/db/managers/#django.db.models.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`](/id/3.2/ref/applications/#django.apps.apps). Ketika Django mulai, itu mengimpor setiap aplikasi terdaftar di [`INSTALLED_APPS`](/id/3.2/ref/settings/#std-setting-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`](/id/3.2/ref/settings/#std-setting-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](/id/3.2/topics/db/sql/).

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.
