Django 2.1 - Many-to-one relationships

कई-से-एक रिश्ते




django

कई-से-एक रिश्ते

एक-से-एक संबंधों को परिभाषित करने के लिए, ForeignKey उपयोग करें:

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):
        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):
        return self.headline

    class Meta:
        ordering = ('headline',)

इस प्रकार के संचालन के उदाहरण हैं जो पायथन एपीआई सुविधाओं का उपयोग करके किए जा सकते हैं।

कुछ रिपोर्टर्स बनाएँ:

>>> r = Reporter(first_name='John', last_name='Smith', email='[email protected]')
>>> r.save()

>>> r2 = Reporter(first_name='Paul', last_name='Jones', email='[email protected]')
>>> r2.save()

एक लेख बनाएँ:

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

ध्यान दें कि आपको किसी विदेशी कुंजी संबंध को सौंपे जाने से पहले किसी ऑब्जेक्ट को सहेजना होगा। उदाहरण के लिए, बिना सहेजे Reporter साथ एक Article बनाने से मूल्य बढ़ जाता है:

>>> r3 = Reporter(first_name='John', last_name='Smith', email='[email protected]')
>>> 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'.

लेख वस्तुओं उनके संबंधित रिपोर्टर वस्तुओं के लिए उपयोग किया है:

>>> r = a.reporter

रिपोर्टर ऑब्जेक्ट के माध्यम से एक लेख बनाएँ:

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

एक नया लेख बनाएँ:

>>> new_article2 = Article.objects.create(headline="Paul's story", pub_date=date(2006, 1, 17), reporter=r)
>>> 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>]>

एक अलग लेख सेट में एक ही लेख जोड़ें - जांचें कि यह चलता है:

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

गलत प्रकार का ऑब्जेक्ट जोड़ना TypeError उठाता है:

>>> r.article_set.add(r2)
Traceback (most recent call last):
...
TypeError: 'Article' instance expected, got <Reporter: Paul Jones>

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

ध्यान दें कि अंतिम उदाहरण में लेख जॉन से पॉल में स्थानांतरित हो गया है।

संबंधित प्रबंधक फ़ील्ड लुकअप का भी समर्थन करते हैं। एपीआई स्वचालित रूप से रिश्तों का पालन करता है जहाँ तक आपको ज़रूरत है। रिश्तों को अलग करने के लिए डबल अंडरस्कोर का उपयोग करें। यह कई स्तरों पर काम करता है जितना आप चाहते हैं। कोई सीमा नहीं है। उदाहरण के लिए:

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

सटीक मिलान यहाँ निहित है:

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

संबंधित क्षेत्र में दो बार क्वेरी। यह WHERE क्लॉज में AND की स्थिति के लिए अनुवाद करता है:

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

संबंधित लुकअप के लिए आप प्राथमिक कुंजी मान की आपूर्ति कर सकते हैं या संबंधित वस्तु को स्पष्ट रूप से पास कर सकते हैं:

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

आप उदाहरणों की शाब्दिक सूची के बजाय किसी क्वेरी का उपयोग कर सकते हैं:

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

विपरीत दिशा में क्वेरी करना:

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

विपरीत दिशा में गिनती अलग के साथ मिलकर काम करती है ():

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

वृत्त में वृत्त जा सकते हैं:

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

यदि आप एक रिपोर्टर को हटाते हैं, तो उसके लेख हटा दिए जाएंगे (यह मानते हुए कि django.db.models.ForeignKey.on_delete को django.db.models.ForeignKey.on_delete साथ परिभाषित किया गया था, जो CASCADE सेट है, जो डिफ़ॉल्ट है):

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

आप क्वेरी में एक JOIN का उपयोग करके हटा सकते हैं:

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