Django OneToOneField और ForeignKey के बीच क्या अंतर है?


जवाबों:


507

यह महसूस करने के लिए सावधान रहें कि दोनों के बीच कुछ अंतर हैं OneToOneField(SomeModel)और ForeignKey(SomeModel, unique=True)। जैसा कि द डिफिटिव गाइड टू जिंगो में कहा गया है :

OneToOneField

एक-से-एक संबंध। वैचारिक रूप से, यह एक के ForeignKeyसाथ समान है unique=True, लेकिन संबंध के "रिवर्स" पक्ष सीधे एक ही वस्तु को वापस कर देगा।

के विपरीत OneToOneField"रिवर्स" संबंध, एक ForeignKeyसंबंध रिटर्न एक "रिवर्स" QuerySet

उदाहरण

उदाहरण के लिए, यदि हमारे पास निम्नलिखित दो मॉडल हैं (नीचे पूर्ण मॉडल कोड):

  1. Car मॉडल का उपयोग करता है OneToOneField(Engine)
  2. 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>

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

5
@MarkPNeyer: जहां तक ​​मैं समझता हूं, OneToOne फील्ड बस इतना ही है: वन-टू-वन। यह होना ही नहीं है। इस उदाहरण को देखें : एक जगह के लिए एक रेस्तरां होना जरूरी नहीं है।
osa

21
यह उत्तर कहता है "कुछ अंतर हैं", और फिर एक अंतर को नाम देते हैं। क्या अन्य हैं?
क्रिस मार्टिन

6
मैं क्रिस जैसा ही सोच रहा हूं। क्या यह सिंटैक्टिक शुगर है, क्या डेटा के एक्सेस में कुछ अंतर्निहित अंतर है, प्रदर्शन अंतर के कारण?
कार्लोस

4
क्या कोई मूलभूत कारण है कि Django में ऐसा नियम नहीं हो सकता है कि यदि विदेशी कुंजी अद्वितीय है और अशक्त नहीं है, तो e.carभी काम करता है?
सिरो सेंटिल्ली 郝海东 i i i 法轮功 '

4
तो ... जब कोई एक ForeignKeyके unique=Trueबजाय एक के साथ उपयोग करना चाहेगा OneToOneField? मैं अन्य प्रश्नों में देखता हूं कि Django भी चेतावनी देता है कि OneToOneFieldआमतौर पर किसी के हितों की सर्वोत्तम सेवा करता है। रिवर्स में QuerySetएक से अधिक तत्व कभी नहीं होंगे, है ना?
एंडी

121

एक फॉरेनकेई एक-से-कई के लिए है, इसलिए एक कार ऑब्जेक्ट में कई पहिए हो सकते हैं, प्रत्येक व्हील कार के लिए फॉरेनके होने से संबंधित है। OneToOneField एक इंजन की तरह होगा, जहां कार ऑब्जेक्ट में एक और केवल एक ही हो सकता है।


4
धन्यवाद, डॉस OneToOneField (someModel) का मतलब है विदेशीके (SomeModel, अद्वितीय = सत्य)?
लालिमा

9
हां: 'A OneToOneField अनिवार्य रूप से एक विदेशी के समान है, इस अपवाद के साथ कि हमेशा इसके साथ एक "अद्वितीय" बाधा उत्पन्न होती है और रिवर्स रिलेशन हमेशा इंगित की गई वस्तु को लौटाता है (क्योंकि केवल एक ही होगा), बजाय एक लौटने के सूची।'
डैन ब्रिन

1
एक ही इंजन वाली कई कारों के बारे में क्या?
ओलेग बेलौसोव

3
@OlegTikhonov उनके पास एक ही इंजन डिजाइन की एक प्रति हो सकती है , लेकिन मैं एक उदाहरण देखना चाहूंगा जहां कई कारें समान भौतिक इंजन साझा कर रही हैं।
दान बृण

3
इस उत्तर में शर्तों के बारे में थोड़ा भ्रम है। फॉरेनके एक-से-एक नहीं है, बल्कि आधिकारिक django प्रलेखन के अनुसार कई-से-एक संबंध है: docs.djangoproject.com/en/2.0/ref/models/fields/…
Kutar Demireren

45

नई चीजों को सीखने का सबसे अच्छा और सबसे प्रभावी तरीका वास्तविक दुनिया के व्यावहारिक उदाहरणों को देखना और उनका अध्ययन करना है। एक पल के लिए मान लीजिए कि आप 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


यह मुझे पंसद है। OneToOne और ForeignKey के बीच मूलभूत अंतर एक से एक और कई संबंधों के लिए है। आप विदेशी का उपयोग कर सकते हैं और अद्वितीय = एक करने के लिए सच है, मैथ्यू के जवाब में सूक्ष्म अंतर बताया गया है।
फ्रैंकजु

13

OneToOneField (वन-टू-वन) का एहसास होता है, ऑब्जेक्ट ओरिएंटेशन में, रचना की धारणा, जबकि फॉरेनकेई (वन-टू-कई) एग्रिगेशन से संबंधित है।


3
अच्छा सादृश्य, लेकिन यह हमेशा ऐसा नहीं होता है। कुछ किनारे मामले हैं जो इस स्पष्टीकरण में फिट नहीं हैं। चलो उदाहरण के लिए हम वर्गों Patientऔर है OrganPatientकई Organएस Organहो सकते हैं , लेकिन केवल एक का हो सकता है Patient। जब Patientहटाया जाता है, तो सभी Organको हटा दिया जाता है। वे एक के बिना मौजूद नहीं हो सकते Patient
सेज़ार

4

इसके अलावा OneToOneFieldकुंजी दोहराव से बचने के प्राथमिक कुंजी के रूप में इस्तेमाल किया जा करने के लिए उपयोगी है। एक में निहित / स्पष्ट ऑटोफिल्ड नहीं हो सकता है

models.AutoField(primary_key=True)

लेकिन OneToOneFieldइसके बजाय प्राथमिक कुंजी के रूप में उपयोग करें ( UserProfileउदाहरण के लिए मॉडल की कल्पना करें ):

user = models.OneToOneField(
    User, null=False, primary_key=True, verbose_name='Member profile')

3

जब आप 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 में जोड़कर बनाया गया है।


1

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 के पीके मान के अनुरूप एक से अधिक रिकॉर्ड हो सकते हैं।


1

फॉरेनके आपको उप-वर्ग प्राप्त करने की अनुमति देता है यह एक और वर्ग की परिभाषा है लेकिन OneToOneFields ऐसा नहीं कर सकता है और यह कई चर के लिए अटैच नहीं है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.