जवाबों:
यह महसूस करने के लिए सावधान रहें कि दोनों के बीच कुछ अंतर हैं OneToOneField(SomeModel)
और ForeignKey(SomeModel, unique=True)
। जैसा कि द डिफिटिव गाइड टू जिंगो में कहा गया है :
OneToOneField
एक-से-एक संबंध। वैचारिक रूप से, यह एक के
ForeignKey
साथ समान हैunique=True
, लेकिन संबंध के "रिवर्स" पक्ष सीधे एक ही वस्तु को वापस कर देगा।
के विपरीत OneToOneField
"रिवर्स" संबंध, एक ForeignKey
संबंध रिटर्न एक "रिवर्स" QuerySet
।
उदाहरण के लिए, यदि हमारे पास निम्नलिखित दो मॉडल हैं (नीचे पूर्ण मॉडल कोड):
Car
मॉडल का उपयोग करता है OneToOneField(Engine)
Car2
मॉडल का उपयोग करता है ForeignKey(Engine2, unique=True)
python manage.py shell
निम्नलिखित को निष्पादित करने के भीतर से :
OneToOneField
उदाहरण>>> from testapp.models import Car, Engine
>>> c = Car.objects.get(name='Audi')
>>> e = Engine.objects.get(name='Diesel')
>>> e.car
<Car: Audi>
ForeignKey
unique=True
उदाहरण के साथ>>> from testapp.models import Car2, Engine2
>>> c2 = Car2.objects.get(name='Mazda')
>>> e2 = Engine2.objects.get(name='Wankel')
>>> e2.car2_set.all()
[<Car2: Mazda>]
from django.db import models
class Engine(models.Model):
name = models.CharField(max_length=25)
def __unicode__(self):
return self.name
class Car(models.Model):
name = models.CharField(max_length=25)
engine = models.OneToOneField(Engine)
def __unicode__(self):
return self.name
class Engine2(models.Model):
name = models.CharField(max_length=25)
def __unicode__(self):
return self.name
class Car2(models.Model):
name = models.CharField(max_length=25)
engine = models.ForeignKey(Engine2, unique=True, on_delete=models.CASCADE)
def __unicode__(self):
return self.name
e.car
भी काम करता है?
ForeignKey
के unique=True
बजाय एक के साथ उपयोग करना चाहेगा OneToOneField
? मैं अन्य प्रश्नों में देखता हूं कि Django भी चेतावनी देता है कि OneToOneField
आमतौर पर किसी के हितों की सर्वोत्तम सेवा करता है। रिवर्स में QuerySet
एक से अधिक तत्व कभी नहीं होंगे, है ना?
एक फॉरेनकेई एक-से-कई के लिए है, इसलिए एक कार ऑब्जेक्ट में कई पहिए हो सकते हैं, प्रत्येक व्हील कार के लिए फॉरेनके होने से संबंधित है। OneToOneField एक इंजन की तरह होगा, जहां कार ऑब्जेक्ट में एक और केवल एक ही हो सकता है।
नई चीजों को सीखने का सबसे अच्छा और सबसे प्रभावी तरीका वास्तविक दुनिया के व्यावहारिक उदाहरणों को देखना और उनका अध्ययन करना है। एक पल के लिए मान लीजिए कि आप django में एक ब्लॉग बनाना चाहते हैं, जहाँ पर समाचार लेख लिख और प्रकाशित कर सकते हैं। ऑनलाइन अखबार का मालिक अपने प्रत्येक पत्रकार को जितने चाहें उतने लेख प्रकाशित करने की अनुमति देना चाहता है, लेकिन अलग-अलग पत्रकार एक ही लेख पर काम नहीं करना चाहते हैं। इसका मतलब यह है कि जब पाठक एक लेख को पढ़ने और पढ़ने जाते हैं, तो वे लेख में केवल एक लेखक को ही देखेंगे।
उदाहरण के लिए: जॉन द्वारा अनुच्छेद, हैरी द्वारा अनुच्छेद, रिक द्वारा अनुच्छेद। आपको हैरी एंड रिक द्वारा अनुच्छेद नहीं दिया जा सकता है क्योंकि बॉस नहीं चाहता कि दो या दो से अधिक लेखक एक ही लेख पर काम करें।
हम इस 'समस्या' को django की मदद से कैसे हल कर सकते हैं? इस समस्या के समाधान की कुंजी django है ForeignKey
।
निम्नलिखित पूर्ण कोड है जिसका उपयोग हमारे बॉस के विचार को लागू करने के लिए किया जा सकता है।
from django.db import models
# Create your models here.
class Reporter(models.Model):
first_name = models.CharField(max_length=30)
def __unicode__(self):
return self.first_name
class Article(models.Model):
title = models.CharField(max_length=100)
reporter = models.ForeignKey(Reporter)
def __unicode__(self):
return self.title
भागो python manage.py syncdb
एसक्यूएल कोड निष्पादित करने और अपने डेटाबेस में अपने अनुप्रयोग के लिए टेबल बनाने के लिए। फिर python manage.py shell
एक अजगर खोल खोलने के लिए उपयोग करें।
रिपोर्टर ऑब्जेक्ट R1 बनाएँ।
In [49]: from thepub.models import Reporter, Article
In [50]: R1 = Reporter(first_name='Rick')
In [51]: R1.save()
लेख वस्तु बनाएँ A1।
In [5]: A1 = Article.objects.create(title='TDD In Django', reporter=R1)
In [6]: A1.save()
फिर रिपोर्टर का नाम पाने के लिए निम्नलिखित टुकड़े का उपयोग करें।
In [8]: A1.reporter.first_name
Out[8]: 'Rick'
अब निम्नलिखित पायथन कोड चलाकर रिपोर्टर ऑब्जेक्ट R2 बनाएं।
In [9]: R2 = Reporter.objects.create(first_name='Harry')
In [10]: R2.save()
अब अनुच्छेद ऑब्जेक्ट A1 में R2 को जोड़ने का प्रयास करें।
In [13]: A1.reporter.add(R2)
यह काम नहीं करता है और आपको यह कहते हुए एक एट्रीब्यूट मिलेगा कि 'रिपोर्टर' ऑब्जेक्ट में कोई विशेषता नहीं है 'ऐड'।
जैसा कि आप देख सकते हैं एक अनुच्छेद वस्तु एक से अधिक रिपोर्टर वस्तु से संबंधित नहीं हो सकती है।
R1 के बारे में क्या? क्या हम एक से अधिक आर्टिकल ऑब्जेक्ट को इसमें संलग्न कर सकते हैं?
In [14]: A2 = Article.objects.create(title='Python News', reporter=R1)
In [15]: R1.article_set.all()
Out[15]: [<Article: Python News>, <Article: TDD In Django>]
यह व्यावहारिक उदाहरण हमें दिखाता है कि django ForeignKey
का उपयोग कई रिश्तों को परिभाषित करने के लिए किया जाता है।
OneToOneField
एक-से-एक संबंध बनाने के लिए उपयोग किया जाता है।
हम reporter = models.OneToOneField(Reporter)
उपर्युक्त मॉडेलफ्रेम फाइल में उपयोग कर सकते हैं लेकिन यह हमारे उदाहरण में उपयोगी नहीं होगा क्योंकि एक लेखक एक लेख से अधिक पोस्ट नहीं कर सकेगा।
हर बार जब आप एक नया लेख पोस्ट करना चाहते हैं तो आपको एक नया रिपोर्टर ऑब्जेक्ट बनाना होगा। यह समय लगता है, है ना?
मैं अत्यधिक के साथ उदाहरण की कोशिश करने OneToOneField
और अंतर का एहसास करने की सलाह देता हूं । मुझे पूरा यकीन है कि इस उदाहरण के बाद आप पूरी तरह से django OneToOneField
और django के बीच का अंतर जान जाएंगे ForeignKey
।
OneToOneField (वन-टू-वन) का एहसास होता है, ऑब्जेक्ट ओरिएंटेशन में, रचना की धारणा, जबकि फॉरेनकेई (वन-टू-कई) एग्रिगेशन से संबंधित है।
Patient
और है Organ
। Patient
कई Organ
एस Organ
हो सकते हैं , लेकिन केवल एक का हो सकता है Patient
। जब Patient
हटाया जाता है, तो सभी Organ
को हटा दिया जाता है। वे एक के बिना मौजूद नहीं हो सकते Patient
।
इसके अलावा OneToOneField
कुंजी दोहराव से बचने के प्राथमिक कुंजी के रूप में इस्तेमाल किया जा करने के लिए उपयोगी है। एक में निहित / स्पष्ट ऑटोफिल्ड नहीं हो सकता है
models.AutoField(primary_key=True)
लेकिन OneToOneField
इसके बजाय प्राथमिक कुंजी के रूप में उपयोग करें ( UserProfile
उदाहरण के लिए मॉडल की कल्पना करें ):
user = models.OneToOneField(
User, null=False, primary_key=True, verbose_name='Member profile')
जब आप OneToOneField तक पहुँचते हैं, तो आपको उस क्षेत्र का मान प्राप्त होता है, जिसकी आपने जाँच की थी। इस उदाहरण में एक पुस्तक मॉडल का 'शीर्षक' फ़ील्ड OneToOneField है:
>>> from mysite.books.models import Book
>>> b = Book.objects.get(id=50)
>>> b.title
u'The Django Book'
जब आप किसी फॉरेनके का उपयोग करते हैं, तो आपको संबंधित मॉडल ऑब्जेक्ट मिलता है, जिसके बाद आप आगे के प्रश्नों के बारे में बता सकते हैं। इस उदाहरण में एक ही पुस्तक मॉडल का 'प्रकाशक' क्षेत्र एक विदेशी है (प्रकाशक वर्ग मॉडल परिभाषा से संबंधित है):
>>> b = Book.objects.get(id=50)
>>> b.publisher
<Publisher: Apress Publishing>
>>> b.publisher.website
u'http://www.apress.com/'
फॉरेनके खेतों के साथ प्रश्न दूसरे तरीके से भी काम करते हैं, लेकिन वे संबंध के गैर-सममित प्रकृति के कारण थोड़ा अलग हैं।
>>> p = Publisher.objects.get(name='Apress Publishing')
>>> p.book_set.all()
[<Book: The Django Book>, <Book: Dive Into Python>, ...]
पर्दे के पीछे, Book_set सिर्फ एक QuerySet है और किसी भी अन्य QuerySet की तरह फ़िल्टर और कटा हुआ हो सकता है। विशेषता नाम book_set निम्न केस मॉडल नाम को _set में जोड़कर बनाया गया है।
OneToOneField: यदि दूसरी तालिका के साथ संबंधित है
table2_col1 = models.OneToOneField(table1,on_delete=models.CASCADE, related_name='table1_id')
तालिका 2 में तालिका 1 के pk मान के अनुरूप केवल एक रिकॉर्ड होगा, अर्थात table2_col1 में तालिका के pk के बराबर अद्वितीय मूल्य होगा
table2_col1 == models.ForeignKey(table1, on_delete=models.CASCADE, related_name='table1_id')
तालिका 2 में तालिका 1 के पीके मान के अनुरूप एक से अधिक रिकॉर्ड हो सकते हैं।