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

Throughout this guide (and in the reference), we'll refer to the following
models, which comprise a blog application:

```python
from datetime import date

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(default=date.today)
    authors = models.ManyToManyField(Author)
    number_of_comments = models.IntegerField(default=0)
    number_of_pingbacks = models.IntegerField(default=0)
    rating = models.IntegerField(default=5)

    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/4.2/ref/models/instances/#django.db.models.Model.save) untuk menyimpan itu ke basisdata.

Dengan asumsi model tinggal di berkas `mysite/blog/models.py`, berikut contohnya:

```pycon
>>> 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/4.2/ref/models/instances/#django.db.models.Model.save).

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

> **See also**
>
> [`save()`](/id/4.2/ref/models/instances/#django.db.models.Model.save) mengambil sejumalh pilihan keuntungan tidak digambarkan disini. Lihat dokumentasi untuk [`save()`](/id/4.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/4.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/4.2/ref/models/instances/#django.db.models.Model.save).

Given a `Blog` instance `b5` that has already been saved to the database,
this example changes its name and updates its record in the database:

```pycon
>>> b5.name = "New name"
>>> b5.save()
```

Ini melakukan pernyataan SQL `UPDATE` dibelakang layar. Django tidak mengenai basisdata sampai anda secara jelas memanggil [`save()`](/id/4.2/ref/models/instances/#django.db.models.Model.save).

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

Updating a [`ForeignKey`](/id/4.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):

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

Updating a [`ManyToManyField`](/id/4.2/ref/models/fields/#django.db.models.ManyToManyField) works a little
differently -- use the
[`add()`](/id/4.2/ref/models/relations/#django.db.models.fields.related.RelatedManager.add) method on the field
to add a record to the relation. This example adds the `Author` instance
`joe` to the `entry` object:

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

To add multiple records to a [`ManyToManyField`](/id/4.2/ref/models/fields/#django.db.models.ManyToManyField) in one
go, include multiple arguments in the call to
[`add()`](/id/4.2/ref/models/relations/#django.db.models.fields.related.RelatedManager.add), like this:

```pycon
>>> 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/4.2/ref/models/querysets/#django.db.models.query.QuerySet) melalui [`Manager`](/id/4.2/topics/db/managers/#django.db.models.Manager) pada kelas model anda.

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

You get a [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) by using your model's
[`Manager`](/id/4.2/topics/db/managers/#django.db.models.Manager). Each model has at least one
[`Manager`](/id/4.2/topics/db/managers/#django.db.models.Manager), and it's called
[`objects`](/id/4.2/ref/models/class/#django.db.models.Model.objects) by default. Access it directly via the
model class, like so:

```pycon
>>> 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/4.2/topics/db/managers/#django.db.models.Manager) adalah sumber utama dari `QuerySets` untuk sebuah model. Sebagai contoh, `Blog.objects.all()` mengembalikan [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) yang mengandung semua obyek `Blog` dalam basisdata.

### Mengambil semua obyek

The simplest way to retrieve objects from a table is to get all of them. To do
this, use the [`all()`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet.all) method on a
[`Manager`](/id/4.2/topics/db/managers/#django.db.models.Manager):

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

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

### Mengambil obyek spesifik dengan menyaring

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

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

  Mengembalikan [`QuerySet`](/id/4.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/4.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/4.2/ref/models/querysets/#django.db.models.query.QuerySet) dari masukan blog dari tahun 2006, gunakan [`filter()`](/id/4.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

The result of refining a [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) is itself a
[`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet), so it's possible to chain
refinements together. For example:

```pycon
>>> 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/4.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/4.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/4.2/ref/models/querysets/#django.db.models.query.QuerySet), anda mendapatkan [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) merek-baru yaitu tidak ada cara mengikat ke [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) sebelumnya. Setiap penyaringan membuat [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) terpisah dan berbeda yang dapat disimpan, digunakan dan digunakan kembali.

Example:

```pycon
>>> 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/4.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/4.2/ref/models/querysets/#django.db.models.query.QuerySet) (`q1`) tidak terpengaruh dengan pengolahan penyaringan.

#### `QuerySet` adalah lazy

`QuerySets` are lazy -- the act of creating a
[`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) doesn't involve any database
activity. You can stack filters together all day long, and Django won't
actually run the query until the [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) is
*evaluated*. Take a look at this example:

```pycon
>>> 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/4.2/ref/models/querysets/#django.db.models.query.QuerySet) tidak diambil dari basisdata sampai anda "meminta" untuk mereka. Ketika anda melakukan, [`QuerySet`](/id/4.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/4.2/ref/models/querysets/#when-querysets-are-evaluated).

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

[`filter()`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet.filter) akan selalu memberikan anda [`QuerySet`](/id/4.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/4.2/ref/models/querysets/#django.db.models.query.QuerySet) mengandung unsur tunggal.

If you know there is only one object that matches your query, you can use the
[`get()`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet.get) method on a
[`Manager`](/id/4.2/topics/db/managers/#django.db.models.Manager) which returns the object directly:

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

Anda dapat menggunakan pernyataan permintaan apapun dengan [`get()`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet.get), seperti dengan [`filter()`](/id/4.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/4.2/ref/models/querysets/#django.db.models.query.QuerySet.get), dan menggunakan [`filter()`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet.filter) dengan potongan `[0]`. Jika tidak ada hasil yang cocok dengan permintaan, [`get()`](/id/4.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/4.2/ref/models/querysets/#django.db.models.query.QuerySet.get). Dalam kasus ini, itu akan memunculkan [`MultipleObjectsReturned`](/id/4.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/4.2/ref/models/querysets/#django.db.models.query.QuerySet.all), [`get()`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet.get), [`filter()`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet.filter) dan [`exclude()`](/id/4.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/4.2/ref/models/querysets/#queryset-api) untuk daftar lengkap dari semua ragam metode [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet).

### Membatasi `QuerySet`

Gunakan sub kumpulan dari sintaksis memotong-array Python untuk membatasi [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) anda pada nomor tertentu dari hasil. Ini adalah setara daro klausa `LIMIT` dan `OFFSET` SQL.

For example, this returns the first 5 objects (`LIMIT 5`):

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

This returns the sixth through tenth objects (`OFFSET 5 LIMIT 5`):

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

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

Generally, slicing a [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) returns a new
[`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) -- it doesn't evaluate the query. An
exception is if you use the "step" parameter of Python slice syntax. For
example, this would actually execute the query in order to return a list of
every *second* object of the first 10:

```pycon
>>> 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:

```pycon
>>> Entry.objects.order_by("headline")[0]
```

This is roughly equivalent to:

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

Basic lookups keyword arguments take the form `field__lookuptype=value`.
(That's a double-underscore). For example:

```pycon
>>> 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/4.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/4.2/ref/models/querysets/#std-fieldlookup-exact)**

  An "exact" match. For example:

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

  For example, the following two statements are equivalent:

  ```pycon
  >>> 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/4.2/ref/models/querysets/#std-fieldlookup-iexact)**

  A case-insensitive match. So, the query:

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

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

**[`contains`](/id/4.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/4.2/ref/models/querysets/#std-fieldlookup-icontains).

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

  Pencarian mulai-dengan dan berakhir-dengan, masing-masing. Ada juga versi kasus-tidak-peka dipanggil [`istartswith`](/id/4.2/ref/models/querysets/#std-fieldlookup-istartswith) dan [`iendswith`](/id/4.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.

This example retrieves all `Entry` objects with a `Blog` whose `name`
is `'Beatles Blog'`:

```pycon
>>> Entry.objects.filter(blog__name="Beatles Blog")
```

Jangkauan ini dapat sedalam anda sukai.

Itu bekerja kebelakang, juga. Selagi itu [`can be customized`](/id/4.2/ref/models/fields/#django.db.models.ForeignKey.related_query_name), secara awalan anda mengacu pada hubungan "reverse" dalam pencarian menggunakan nama huruf kecil dari model.

This example retrieves all `Blog` objects which have at least one `Entry`
whose `headline` contains `'Lennon'`:

```pycon
>>> 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/4.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

When spanning a [`ManyToManyField`](/id/4.2/ref/models/fields/#django.db.models.ManyToManyField) or a reverse
[`ForeignKey`](/id/4.2/ref/models/fields/#django.db.models.ForeignKey) (such as from `Blog` to `Entry`),
filtering on multiple attributes raises the question of whether to require each
attribute to coincide in the same related object. We might seek blogs that have
an entry from 2008 with *“Lennon”* in its headline, or we might seek blogs that
merely have any entry from 2008 as well as some newer or older entry with
*“Lennon”* in its headline.

To select all blogs containing at least one entry from 2008 having *"Lennon"*
in its headline (the same entry satisfying both conditions), we would write:

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

Otherwise, to perform a more permissive query selecting any blogs with merely
*some* entry with *"Lennon"* in its headline and *some* entry from 2008, we
would write:

```
Blog.objects.filter(entry__headline__contains="Lennon").filter(
    entry__pub_date__year=2008
)
```

Suppose there is only one blog that has both entries containing *"Lennon"* and
entries from 2008, but that none of the entries from 2008 contained *"Lennon"*.
The first query would not return any blogs, but the second query would return
that one blog. (This is because the entries selected by the second filter may
or may not be the same as the entries in the first filter. We are filtering the
`Blog` items with each filter statement, not the `Entry` items.) In short,
if each condition needs to match the same related object, then each should be
contained in a single [`filter()`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet.filter) call.

> **Note**
>
> As the second (more permissive) query chains multiple filters, it performs
> multiple joins to the primary model, potentially yielding duplicates.
>
> ```
> >>> from datetime import date
> >>> beatles = Blog.objects.create(name='Beatles Blog')
> >>> pop = Blog.objects.create(name='Pop Music Blog')
> >>> Entry.objects.create(
> ...     blog=beatles,
> ...     headline='New Lennon Biography',
> ...     pub_date=date(2008, 6, 1),
> ... )
> <Entry: New Lennon Biography>
> >>> Entry.objects.create(
> ...     blog=beatles,
> ...     headline='New Lennon Biography in Paperback',
> ...     pub_date=date(2009, 6, 1),
> ... )
> <Entry: New Lennon Biography in Paperback>
> >>> Entry.objects.create(
> ...     blog=pop,
> ...     headline='Best Albums of 2008',
> ...     pub_date=date(2008, 12, 15),
> ... )
> <Entry: Best Albums of 2008>
> >>> Entry.objects.create(
> ...     blog=pop,
> ...     headline='Lennon Would Have Loved Hip Hop',
> ...     pub_date=date(2020, 4, 1),
> ... )
> <Entry: Lennon Would Have Loved Hip Hop>
> >>> Blog.objects.filter(
> ...     entry__headline__contains='Lennon',
> ...     entry__pub_date__year=2008,
> ... )
> <QuerySet [<Blog: Beatles Blog>]>
> >>> Blog.objects.filter(
> ...     entry__headline__contains='Lennon',
> ... ).filter(
> ...     entry__pub_date__year=2008,
> ... )
> <QuerySet [<Blog: Beatles Blog>, <Blog: Beatles Blog>, <Blog: Pop Music Blog]>
> ```

> **Note**
>
> Perilaku dari [`filter()`](/id/4.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/4.2/ref/models/querysets/#django.db.models.query.QuerySet.exclude). Malahan, keadaan dalam panggilan [`exclude()`](/id/4.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/4.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/4.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.

For example, to find a list of all blog entries that have had more comments
than pingbacks, we construct an `F()` object to reference the pingback count,
and use that `F()` object in the query:

```pycon
>>> from django.db.models import F
>>> Entry.objects.filter(number_of_comments__gt=F("number_of_pingbacks"))
```

Django supports the use of addition, subtraction, multiplication,
division, modulo, and power arithmetic with `F()` objects, both with constants
and with other `F()` objects. To find all the blog entries with more than
*twice* as many comments as pingbacks, we modify the query:

```pycon
>>> Entry.objects.filter(number_of_comments__gt=F("number_of_pingbacks") * 2)
```

To find all the entries where the rating of the entry is less than the
sum of the pingback count and comment count, we would issue the
query:

```pycon
>>> Entry.objects.filter(rating__lt=F("number_of_comments") + F("number_of_pingbacks"))
```

You can also use the double underscore notation to span relationships in
an `F()` object. An `F()` object with a double underscore will introduce
any joins needed to access the related object. For example, to retrieve all
the entries where the author's name is the same as the blog name, we could
issue the query:

```pycon
>>> Entry.objects.filter(authors__name=F("blog__name"))
```

For date and date/time fields, you can add or subtract a
[`timedelta`](https://docs.python.org/3/library/datetime.html#datetime.timedelta) object. The following would return all entries
that were modified more than 3 days after they were published:

```pycon
>>> 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:

```pycon
>>> F("somefield").bitand(16)
```

> **Oracle**
>
> Oracle tidak mendukung tindakan bitwise XOR.

### Expressions can reference transforms

Django supports using transforms in expressions.

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

```pycon
>>> from django.db.models import F
>>> Entry.objects.filter(pub_date__year=F("mod_date__year"))
```

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

```pycon
>>> from django.db.models import Min
>>> 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:

```pycon
>>> from django.db.models import OuterRef, Subquery, Sum
>>> 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".

In the example `Blog` model, the primary key is the `id` field, so these
three statements are equivalent:

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

The use of `pk` isn't limited to `__exact` queries -- any query term
can be combined with `pk` to perform a query on the primary key of a model:

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

`pk` lookups also work across joins. For example, these three statements are
equivalent:

```pycon
>>> 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:

```pycon
>>> 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/4.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/4.2/ref/models/querysets/#django.db.models.query.QuerySet) baru dibuat, cache kosong. Pertama kali sebuah [`QuerySet`](/id/4.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/4.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/4.2/ref/models/querysets/#django.db.models.query.QuerySet) sedang diulang). Penilaian selanjutnya dari [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) menggunakan hasil ter cache.

Keep this caching behavior in mind, because it may bite you if you don't use
your [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet)s correctly. For example, the
following will create two [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet)s, evaluate
them, and throw them away:

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

To avoid this problem, save the [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) and
reuse it:

```pycon
>>> queryset = Entry.objects.all()
>>> print([p.headline for p in queryset])  # Evaluate the query set.
>>> print([p.pub_date for p in queryset])  # Reuse 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.

For example, repeatedly getting a certain index in a queryset object will query
the database each time:

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

However, if the entire queryset has already been evaluated, the cache will be
checked instead:

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

Here are some examples of other actions that will result in the entire queryset
being evaluated and therefore populate the cache:

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

## Asynchronous queries

> **New in Django 4.1**

If you are writing asynchronous views or code, you cannot use the ORM for
queries in quite the way we have described above, as you cannot call *blocking*
synchronous code from asynchronous code - it will block up the event loop
(or, more likely, Django will notice and raise a `SynchronousOnlyOperation`
to stop that from happening).

Fortunately, you can do many queries using Django's asynchronous query APIs.
Every method that might block - such as `get()` or `delete()` \- has an
asynchronous variant (`aget()` or `adelete()`), and when you iterate over
results, you can use asynchronous iteration (`async for`) instead.

### Query iteration

> **New in Django 4.1**

The default way of iterating over a query - with `for` \- will result in a
blocking database query behind the scenes as Django loads the results at
iteration time. To fix this, you can swap to `async for`:

```
async for entry in Authors.objects.filter(name__startswith="A"):
    ...
```

Be aware that you also can't do other things that might iterate over the
queryset, such as wrapping `list()` around it to force its evaluation (you
can use `async for` in a comprehension, if you want it).

Because `QuerySet` methods like `filter()` and `exclude()` do not
actually run the query - they set up the queryset to run when it's iterated
over - you can use those freely in asynchronous code. For a guide to which
methods can keep being used like this, and which have asynchronous versions,
read the next section.

### `QuerySet` and manager methods

> **New in Django 4.1**

Some methods on managers and querysets - like `get()` and `first()` \- force
execution of the queryset and are blocking. Some, like `filter()` and
`exclude()`, don't force execution and so are safe to run from asynchronous
code. But how are you supposed to tell the difference?

While you could poke around and see if there is an `a`-prefixed version of
the method (for example, we have `aget()` but not `afilter()`), there is a
more logical way - look up what kind of method it is in the
[QuerySet reference](/id/4.2/ref/models/querysets/).

In there, you'll find the methods on QuerySets grouped into two sections:

- *Methods that return new querysets*: These are the non-blocking ones,
  and don't have asynchronous versions. You're free to use these in any
  situation, though read the notes on `defer()` and `only()` before you use
  them.
- *Methods that do not return querysets*: These are the blocking ones, and
  have asynchronous versions - the asynchronous name for each is noted in its
  documentation, though our standard pattern is to add an `a` prefix.

Using this distinction, you can work out when you need to use asynchronous
versions, and when you don't. For example, here's a valid asynchronous query:

```
user = await User.objects.filter(username=my_input).afirst()
```

`filter()` returns a queryset, and so it's fine to keep chaining it inside an
asynchronous environment, whereas `first()` evaluates and returns a model
instance - thus, we change to `afirst()`, and use `await` at the front of
the whole expression in order to call it in an asynchronous-friendly way.

> **Note**
>
> If you forget to put the `await` part in, you may see errors like
> *"coroutine object has no attribute x"* or *"\<coroutine …\>"* strings in
> place of your model instances. If you ever see these, you are missing an
> `await` somewhere to turn that coroutine into a real value.

### Transaksi

> **New in Django 4.1**

Transactions are **not** currently supported with asynchronous queries and
updates. You will find that trying to use one raises
`SynchronousOnlyOperation`.

If you wish to use a transaction, we suggest you write your ORM code inside a
separate, synchronous function and then call that using `sync_to_async` \- see
[Dukungan asinkronus](/id/4.2/topics/async/) for more.

## Meminta `JSONField`

Lookups implementation is different in [`JSONField`](/id/4.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
```

### Menyimpan dan meminta untuk `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(None, JSONField())`](/id/4.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/4.2/ref/models/querysets/#std-fieldlookup-isnull):

```pycon
>>> Dog.objects.create(name="Max", data=None)  # SQL NULL.
<Dog: Max>
>>> Dog.objects.create(name="Archie", data=Value(None, JSONField()))  # JSON null.
<Dog: Archie>
>>> Dog.objects.filter(data=None)
<QuerySet [<Dog: Archie>]>
>>> Dog.objects.filter(data=Value(None, JSONField()))
<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**
>
> Menyimpan skalar JSON `null` tidak melanggar [`null=False`](/id/4.2/ref/models/fields/#django.db.models.Field.null).

> **Changed in Django 4.2**
>
> Support for expressing JSON `null` using `Value(None, JSONField())` was
> added.

> **Deprecated since Django 4.2**
>
> Ditinggalkan sejak versi 4.2: Passing `Value("null")` to express JSON `null` is deprecated.

### Key, index, and path transforms

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

```pycon
>>> 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>]>
```

Multiple keys can be chained together to form a path lookup:

```pycon
>>> 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:

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

To query for missing keys, use the `isnull` lookup:

```pycon
>>> 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/4.2/ref/models/querysets/#std-fieldlookup-exact) lookup.
> Key, index, and path transforms can also be chained with:
> [`icontains`](/id/4.2/ref/models/querysets/#std-fieldlookup-icontains), [`endswith`](/id/4.2/ref/models/querysets/#std-fieldlookup-endswith), [`iendswith`](/id/4.2/ref/models/querysets/#std-fieldlookup-iendswith),
> [`iexact`](/id/4.2/ref/models/querysets/#std-fieldlookup-iexact), [`regex`](/id/4.2/ref/models/querysets/#std-fieldlookup-regex), [`iregex`](/id/4.2/ref/models/querysets/#std-fieldlookup-iregex), [`startswith`](/id/4.2/ref/models/querysets/#std-fieldlookup-startswith),
> [`istartswith`](/id/4.2/ref/models/querysets/#std-fieldlookup-istartswith), [`lt`](/id/4.2/ref/models/querysets/#std-fieldlookup-lt), [`lte`](/id/4.2/ref/models/querysets/#std-fieldlookup-lte), [`gt`](/id/4.2/ref/models/querysets/#std-fieldlookup-gt), and
> [`gte`](/id/4.2/ref/models/querysets/#std-fieldlookup-gte), as well as with [Containment and key lookups](#containment-and-key-lookups).

#### `KT()` expressions

> **New in Django 4.2**

#### `class KT(lookup)`

Represents the text value of a key, index, or path transform of
[`JSONField`](/id/4.2/ref/models/fields/#django.db.models.JSONField). You can use the double underscore
notation in `lookup` to chain dictionary key and index transforms.

Sebagai contoh:

```pycon
>>> from django.db.models.fields.json import KT
>>> Dog.objects.create(
...     name="Shep",
...     data={
...         "owner": {"name": "Bob"},
...         "breed": ["collie", "lhasa apso"],
...     },
... )
<Dog: Shep>
>>> Dogs.objects.annotate(
...     first_breed=KT("data__breed__1"), owner_name=KT("data__owner__name")
... ).filter(first_breed__startswith="lhasa", owner_name="Bob")
<QuerySet [<Dog: Shep>]>
```

> **Note**
>
> Due to the way in which key-path queries work,
> [`exclude()`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet.exclude) and
> [`filter()`](/id/4.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.

> **Pengguna MariaDB dan Oracle**
>
> Using [`order_by()`](/id/4.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.

> **Pengguna Oracle**
>
> On Oracle Database, using `None` as the lookup value in an
> [`exclude()`](/id/4.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`.

> **Pengguna PostgreSQL**
>
> 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.

> **Pengguna SQLite**
>
> On SQLite, `"true"`, `"false"`, and `"null"` string values will
> always be interpreted as `True`, `False`, and JSON `null`
> respectively.

### Containment and key lookups

#### `contains`

The [`contains`](/id/4.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:

```pycon
>>> 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 dan SQLite**
>
> contains\`\`tidak didukung pada Oracle dan 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:

```pycon
>>> 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 dan SQLite**
>
> `contained_by` tidak didukung pada Oracle dan SQLite.

#### `has_key`

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

```pycon
>>> 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:

```pycon
>>> 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:

```pycon
>>> 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/4.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/4.2/ref/models/querysets/#django.db.models.Q).

[`Q object`](/id/4.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")
```

`Q` objects can be combined using the `&`, `|`, and `^` operators. When
an operator is used on two `Q` objects, it yields a new `Q` object.

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

```
Q(question__startswith="Who") | Q(question__startswith="What")
```

This is equivalent to the following SQL `WHERE` clause:

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

You can compose statements of arbitrary complexity by combining `Q` objects
with the `&`, `|`, and `^` operators and use parenthetical grouping.
Also, `Q` objects can be negated using the `~` operator, allowing for
combined lookups that combine both a normal query and a negated (`NOT`)
query:

```
Q(question__startswith="Who") | ~Q(pub_date__year=2005)
```

Setiap fungsi pencarian yang mengambil argumen-kata kunci (sebagai contoh [`filter()`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet.filter), [`exclude()`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet.exclude), [`get()`](/id/4.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**
>
> Contoh [OR lookups](https://github.com/django/django/blob/stable/4.2.x/tests/or_lookups/tests.py) di unit test Django menunjukkan beberapa kemungkinan penggunaan `Q`.

> **Changed in Django 4.1**
>
> Support for the `^` (`XOR`) operator was added.

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

Using the `Entry` example above, the following two statements are equivalent:

```pycon
>>> some_entry == other_entry
>>> some_entry.id == other_entry.id
```

If a model's primary key isn't called `id`, no problem. Comparisons will
always use the primary key, whatever it's called. For example, if a model's
primary key field is called `name`, these two statements are equivalent:

```pycon
>>> some_obj == other_obj
>>> some_obj.name == other_obj.name
```

## menghapus obyek

The delete method, conveniently, is named
[`delete()`](/id/4.2/ref/models/instances/#django.db.models.Model.delete). This method immediately deletes the
object and returns the number of objects deleted and a dictionary with
the number of deletions per object type. Example:

```pycon
>>> e.delete()
(1, {'blog.Entry': 1})
```

Anda dapat juga menghapus obyek dalam jumlah besar. Setiap [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) mempunyai sebuah [`delete()`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet.delete) method, yang menghapus semua anggota dari [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) tersebut.

For example, this deletes all `Entry` objects with a `pub_date` year of
2005:

```pycon
>>> 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/4.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/4.2/ref/models/querysets/#django.db.models.query.QuerySet.delete) dari sebuah [`QuerySet`](/id/4.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/4.2/ref/models/fields/#django.db.models.ForeignKey.on_delete) ke [`ForeignKey`](/id/4.2/ref/models/fields/#django.db.models.ForeignKey).

Catat bahwa [`delete()`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet.delete) adalah hanya cara [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) yang tidak ditunjukkan pada [`Manager`](/id/4.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/4.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/4.2/ref/models/querysets/#django.db.models.query.QuerySet). Anda dapat melakukan ini dengan cara [`update()`](/id/4.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")
```

You can only set non-relation fields and [`ForeignKey`](/id/4.2/ref/models/fields/#django.db.models.ForeignKey)
fields using this method. To update a non-relation field, provide the new value
as a constant. To update [`ForeignKey`](/id/4.2/ref/models/fields/#django.db.models.ForeignKey) fields, set the
new value to be the new model instance you want to point to. For example:

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

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

The `update()` method is applied instantly and returns the number of rows
matched by the query (which may not be equal to the number of rows updated if
some rows already have the new value). The only restriction on the
[`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) being updated is that it can only
access one database table: the model's main table. You can filter based on
related fields, but you can only update columns in the model's main
table. Example:

```pycon
>>> 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/4.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/4.2/ref/models/instances/#django.db.models.Model.save)), or honor the
[`auto_now`](/id/4.2/ref/models/fields/#django.db.models.DateField.auto_now) field option.
If you want to save every item in a [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet)
and make sure that the [`save()`](/id/4.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/4.2/ref/models/instances/#django.db.models.Model.save):

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

Calls to update can also use [`F expressions`](/id/4.2/ref/models/expressions/#django.db.models.F) to
update one field based on the value of another field in the model. This is
especially useful for incrementing counters based upon their current value. For
example, to increment the pingback count for every entry in the blog:

```pycon
>>> Entry.objects.update(number_of_pingbacks=F("number_of_pingbacks") + 1)
```

However, unlike `F()` objects in filter and exclude clauses, you can't
introduce joins when you use `F()` objects in an update -- you can only
reference fields local to the model being updated. If you attempt to introduce
a join with an `F()` object, a `FieldError` will be raised:

```pycon
# 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/4.2/ref/models/fields/#django.db.models.ForeignKey), [`OneToOneField`](/id/4.2/ref/models/fields/#django.db.models.OneToOneField), atau [`ManyToManyField`](/id/4.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/4.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.

Example:

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

You can get and set via a foreign-key attribute. As you may expect, changes to
the foreign key aren't saved to the database until you call
[`save()`](/id/4.2/ref/models/instances/#django.db.models.Model.save). Example:

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

If a [`ForeignKey`](/id/4.2/ref/models/fields/#django.db.models.ForeignKey) field has `null=True` set (i.e.,
it allows `NULL` values), you can assign `None` to remove the relation.
Example:

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

Forward access to one-to-many relationships is cached the first time the
related object is accessed. Subsequent accesses to the foreign key on the same
object instance are cached. Example:

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

Note that the [`select_related()`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet.select_related)
[`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) method recursively prepopulates the
cache of all one-to-many relationships ahead of time. Example:

```pycon
>>> 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/4.2/ref/models/fields/#django.db.models.ForeignKey), instance-instance dari model foreign-key akan mempunyai akses ke [`Manager`](/id/4.2/topics/db/managers/#django.db.models.Manager) yang mengembalikan semua instance dari model pertama. Secara awalan, [`Manager`](/id/4.2/topics/db/managers/#django.db.models.Manager) ini dinamai `FOO_set`, dimana `FOO` adalah nama model sumber, huruf kecil. [`Manager`](/id/4.2/topics/db/managers/#django.db.models.Manager) ini mengembalikan `QuerySets`, yang dapat disaring dan dirubah seperti digambarkan dalam bagian "Mengambil obyek" diatas.

Example:

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

You can override the `FOO_set` name by setting the
[`related_name`](/id/4.2/ref/models/fields/#django.db.models.ForeignKey.related_name) parameter in the
[`ForeignKey`](/id/4.2/ref/models/fields/#django.db.models.ForeignKey) definition. For example, if the `Entry`
model was altered to `blog = ForeignKey(Blog, on_delete=models.CASCADE,
related_name='entries')`, the above example code would look like this:

```pycon
>>> 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/4.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()
```

> **Interaction with prefetching**
>
> When calling [`prefetch_related()`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet.prefetch_related) with
> a reverse relation, the default manager will be used. If you want to
> prefetch related objects using a custom reverse manager, use
> [`Prefetch()`](/id/4.2/ref/models/querysets/#django.db.models.Prefetch). For example:
>
> ```
> from django.db.models import Prefetch
>
> prefetch_manager = Prefetch("entry_set", queryset=Entry.entries.all())
> Blog.objects.prefetch_related(prefetch_manager)
> ```

#### Cara tambahan untuk menangani obyek terkait

Sebagai tambahan pada metode [`QuerySet`](/id/4.2/ref/models/querysets/#django.db.models.query.QuerySet) ditentukan dalam "Mengambil obyek" diatas, [`ForeignKey`](/id/4.2/ref/models/fields/#django.db.models.ForeignKey) [`Manager`](/id/4.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])
```

If the `clear()` method is available, any preexisting objects will be
removed from the `entry_set` before all objects in the iterable (in this
case, a list) are added to the set. If the `clear()` method is *not*
available, all objects in the iterable will be added without removing any
existing elements.

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/4.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/4.2/ref/models/fields/#django.db.models.ForeignKey), [`ManyToManyField`](/id/4.2/ref/models/fields/#django.db.models.ManyToManyField) dapat menentukan [`related_name`](/id/4.2/ref/models/fields/#django.db.models.ManyToManyField.related_name). Dalam contoh diatas, jika [`ManyToManyField`](/id/4.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/4.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/4.2/topics/db/managers/#django.db.models.Manager), tetapi [`Manager`](/id/4.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/4.2/ref/applications/#django.apps.apps). Ketika Django mulai, itu mengimpor setiap aplikasi terdaftar di [`INSTALLED_APPS`](/id/4.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/4.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/4.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.
