Hubungan banyak-ke-satuLink to this heading

Untuk menentukan hubungan many-to-one, gunakan ForeignKey:

Code
from django.db import models

class Reporter(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    email = models.EmailField()

    def __str__(self):              # __unicode__ on Python 2
        return "%s %s" % (self.first_name, self.last_name)

class Article(models.Model):
    headline = models.CharField(max_length=100)
    pub_date = models.DateField()
    reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)

    def __str__(self):              # __unicode__ on Python 2
        return self.headline

    class Meta:
        ordering = ('headline',)

Apa yang mengikuti adalah contoh-contoh dari tindakan yang dapat dilakukan menggunakan fasilitas API Python.

Buat sedikir Reporter:

Python console
>>> r = Reporter(first_name='John', last_name='Smith', email='john@example.com')
>>> r.save()

>>> r2 = Reporter(first_name='Paul', last_name='Jones', email='paul@example.com')
>>> r2.save()

Buat sebuah Artikel:

Python console
>>> from datetime import date
>>> a = Article(id=None, headline="This is a test", pub_date=date(2005, 7, 27), reporter=r)
>>> a.save()

>>> a.reporter.id
1

>>> a.reporter
<Reporter: John Smith>

Catat bahwa anda harus menyimpan sebuah obyek sebelum itu dapat diberikan ke hubungan foreign key. Sebagai contoh, membuat Article dengan Reporter tidak disimpan memunculkan ValueError:

Python console
>>> r3 = Reporter(first_name='John', last_name='Smith', email='john@example.com')
>>> Article.objects.create(headline="This is a test", pub_date=date(2005, 7, 27), reporter=r3)
Traceback (most recent call last):
...
ValueError: save() prohibited to prevent data loss due to unsaved related object 'reporter'.

Obyek artikel mempunyai akses ke obyek Reporter terkait:

Python console
>>> r = a.reporter

Pada Python 2, ini adalah string dari jenis str daripada string unicode karena itulah yang apa telah digunakan dalam pembuatan dari pelapor (dan kami belum menyegarkan data dari basisdata, yang selalu mengembalikan string unicode):

Python console
>>> r.first_name, r.last_name
('John', 'Smith')

Buat sebuah Article melalui obyek Reporter:

Python console
>>> new_article = r.article_set.create(headline="John's second story", pub_date=date(2005, 7, 29))
>>> new_article
<Article: John's second story>
>>> new_article.reporter
<Reporter: John Smith>
>>> new_article.reporter.id
1

Buat sebuah artikel, dan tambah itu ke kumpulan artikel:

Python console
>>> new_article2 = Article(headline="Paul's story", pub_date=date(2006, 1, 17))
>>> r.article_set.add(new_article2)
>>> new_article2.reporter
<Reporter: John Smith>
>>> new_article2.reporter.id
1
>>> r.article_set.all()
<QuerySet [<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>]>

Tambah artikel sama ke kumpulan artikel berbeda - periksa bahwa itu berpindah:

Python console
>>> r2.article_set.add(new_article2)
>>> new_article2.reporter.id
2
>>> new_article2.reporter
<Reporter: Paul Jones>

Menambahkan sebuah obyek dari jenis salah memunculkan TypeError:

Python console
>>> r.article_set.add(r2)
Traceback (most recent call last):
...
TypeError: 'Article' instance expected

>>> r.article_set.all()
<QuerySet [<Article: John's second story>, <Article: This is a test>]>
>>> r2.article_set.all()
<QuerySet [<Article: Paul's story>]>

>>> r.article_set.count()
2

>>> r2.article_set.count()
1

Catat bahwa di contoh terakhir artikel telah dipindahkan dari John ke Paul.

Pengelola terkait mendukung pencarian bidang-bidang juga. API otomatis mengikuti hubungan sejauh anda butuhkan. Gunakan garis bawah ganda untuk memisahkan hubungan. Ini bekerja sebanyak tingkatan yang anda inginkan. Tidak ada batasan. Sebagai contoh:

Python console
>>> r.article_set.filter(headline__startswith='This')
<QuerySet [<Article: This is a test>]>

# Find all Articles for any Reporter whose first name is "John".
>>> Article.objects.filter(reporter__first_name='John')
<QuerySet [<Article: John's second story>, <Article: This is a test>]>

Benar-benar cocok tersirat disini:

Python console
>>> Article.objects.filter(reporter__first_name='John')
<QuerySet [<Article: John's second story>, <Article: This is a test>]>

Permintaan dua kali lebih bidang terkait. Ini menterjemahkan pada sebuah keadaan AND dalam klausa WHERE:

Python console
>>> Article.objects.filter(reporter__first_name='John', reporter__last_name='Smith')
<QuerySet [<Article: John's second story>, <Article: This is a test>]>

Untuk pencarian terkait anda dapat menyediakan sebuah nilai primary key atau lewatkan obyek terkait dengan tegas:

Python console
>>> Article.objects.filter(reporter__pk=1)
<QuerySet [<Article: John's second story>, <Article: This is a test>]>
>>> Article.objects.filter(reporter=1)
<QuerySet [<Article: John's second story>, <Article: This is a test>]>
>>> Article.objects.filter(reporter=r)
<QuerySet [<Article: John's second story>, <Article: This is a test>]>

>>> Article.objects.filter(reporter__in=[1,2]).distinct()
<QuerySet [<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>]>
>>> Article.objects.filter(reporter__in=[r,r2]).distinct()
<QuerySet [<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>]>

Anda dapat juga menggunakan queryset daripada daftar harfiah dari instance:

Python console
>>> Article.objects.filter(reporter__in=Reporter.objects.filter(first_name='John')).distinct()
<QuerySet [<Article: John's second story>, <Article: This is a test>]>

Meminta di arah berlawanan:

Python console
>>> Reporter.objects.filter(article__pk=1)
<QuerySet [<Reporter: John Smith>]>
>>> Reporter.objects.filter(article=1)
<QuerySet [<Reporter: John Smith>]>
>>> Reporter.objects.filter(article=a)
<QuerySet [<Reporter: John Smith>]>

>>> Reporter.objects.filter(article__headline__startswith='This')
<QuerySet [<Reporter: John Smith>, <Reporter: John Smith>, <Reporter: John Smith>]>
>>> Reporter.objects.filter(article__headline__startswith='This').distinct()
<QuerySet [<Reporter: John Smith>]>

Menghitung dalam arah berlawanan bekerja dalam hubungan dengan distinct():

Python console
>>> Reporter.objects.filter(article__headline__startswith='This').count()
3
>>> Reporter.objects.filter(article__headline__startswith='This').distinct().count()
1

Permintaan dapat berputar seperti lingkaran:

Python console
>>> Reporter.objects.filter(article__reporter__first_name__startswith='John')
<QuerySet [<Reporter: John Smith>, <Reporter: John Smith>, <Reporter: John Smith>, <Reporter: John Smith>]>
>>> Reporter.objects.filter(article__reporter__first_name__startswith='John').distinct()
<QuerySet [<Reporter: John Smith>]>
>>> Reporter.objects.filter(article__reporter=r).distinct()
<QuerySet [<Reporter: John Smith>]>

Jika anda menghapus sebuah reporter, artikel dia akan dihapus (menganggap bahwa ForeignKey telah ditentukan dengan django.db.models.ForeignKey.on_delete setel menjadi CASCADE, yang merupakan awalan):

Python console
>>> Article.objects.all()
<QuerySet [<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>]>
>>> Reporter.objects.order_by('first_name')
<QuerySet [<Reporter: John Smith>, <Reporter: Paul Jones>]>
>>> r2.delete()
>>> Article.objects.all()
<QuerySet [<Article: John's second story>, <Article: This is a test>]>
>>> Reporter.objects.order_by('first_name')
<QuerySet [<Reporter: John Smith>]>

Anda dapat menghapus menggunakan JOIN di permintaan:

Python console
>>> Reporter.objects.filter(article__headline__startswith='This').delete()
>>> Reporter.objects.all()
<QuerySet []>
>>> Article.objects.all()
<QuerySet []>