Django: कुछ मॉडल फ़ील्ड एक दूसरे के साथ क्यों टकराते हैं?


174

मैं एक ऐसी वस्तु बनाना चाहता हूं जिसमें 2 उपयोगकर्ता हों। उदाहरण के लिए:

class GameClaim(models.Model):
    target = models.ForeignKey(User)
    claimer = models.ForeignKey(User)
    isAccepted = models.BooleanField()

लेकिन सर्वर चलाते समय मुझे निम्न त्रुटियां हो रही हैं:

  • संबंधित फ़ील्ड 'User.gameclaim_set' के साथ फ़ील्ड 'लक्ष्य' क्लैश के लिए एक्सेसर। 'लक्ष्य' की परिभाषा से संबंधित_नाम तर्क जोड़ें।

  • संबंधित फ़ील्ड 'User.gameclaim_set' के साथ फ़ील्ड 'क्लेम करने वाले' के लिए एक्सेसर। 'दावेदार' की परिभाषा से संबंधित_नाम तर्क जोड़ें।

क्या आप कृपया बता सकते हैं कि मुझे त्रुटियाँ क्यों मिल रही हैं और उन्हें कैसे ठीक किया जाए?


ये त्रुटि संदेश वास्तव में अच्छे हैं। वे पहले ही समझाते हैं कि उन्हें कैसे ठीक किया जाए। और related_nameडॉक्यूमेंट में ** [[ प्रलेखन में **] ( docs.djangoproject.com/en/dev/ref/models/fields/#arguments ) पढ़कर समझाते हैं कि वे क्यों होते हैं।
लुत्ज प्रेपेल्ट

जवाबों:


294

आपके पास उपयोगकर्ता के लिए दो विदेशी कुंजी हैं। Django स्वचालित रूप से GameClaim के लिए वापस उपयोगकर्ता से एक रिवर्स संबंध बनाता है, जो आमतौर पर है gameclaim_set। हालाँकि, क्योंकि आपके पास दो एफके हैं, तो आपके पास दो gameclaim_setविशेषताएँ होंगी , जो स्पष्ट रूप से असंभव है। इसलिए आपको Django को यह बताने की आवश्यकता है कि रिवर्स रिलेशन के लिए किस नाम का उपयोग करना है।

related_nameFK परिभाषा में विशेषता का उपयोग करें । जैसे

class GameClaim(models.Model):
    target = models.ForeignKey(User, related_name='gameclaim_targets')
    claimer = models.ForeignKey(User, related_name='gameclaim_users')
    isAccepted = models.BooleanField()

49
अच्छा जवाब है, लेकिन मुझे नहीं लगता कि आप अशिष्टता से बचने में सफल रहे: पी "क्यों" स्पष्ट नहीं है जब तक कि आप इस बात से अवगत नहीं हैं कि आंतरिक रूप से कैसे काम करता है।
केनी

14
किसी के लिए सिर्फ रूपरेखा सीखना, यह स्पष्ट नहीं होगा।
jkyle

3
धन्यवाद, त्रुटि संदेश मेरे लिए भी स्पष्ट नहीं था, लेकिन रिवर्स रिलेशन के बारे में आपका स्पष्टीकरण बहुत मददगार था।
बर्बाद करना

1
सिर्फ इसलिए कि क्लैश एक अच्छा बैंड था, उन्हें विशेष रूप से वर्णनात्मक त्रुटि संदेश नहीं देता;)
शहर

7
यह भी उल्लेख किया जाना चाहिए कि यदि आपको सभी मॉडलों के लिए रिवर्स संबंधों का उपयोग करने की आवश्यकता नहीं है। कुछ मामलों में आप चाहते हैं कि मॉडल का संबंध एक तरह से हो। इस स्थिति में आप संबंधित_नाम = '+' का उपयोग करते हैं। यह Django को एक तरह से संबंध बनाने और रिवर्स संबंध को अनदेखा करने के लिए कहता है।
टॉमी स्ट्रैंड

8

Userमॉडल के लिए एक ही नाम के दो क्षेत्रों, बनाने के लिए कोशिश कर रहा है GameClaimsहै कि Userके रूप में target, और के लिए एक और GameClaimsहै कि उस राशि Userके रूप में claimer। यहाँ है पर डॉक्स हैंrelated_name , जो कि Django का तरीका है जिससे आप विशेषताओं के नाम सेट कर सकते हैं ताकि ऑटोगेनरेटेड लोग संघर्ष न करें।


7

ओपी एक सार आधार वर्ग का उपयोग नहीं कर रहा है ... लेकिन अगर आप हैं, तो आप पाएंगे कि FK में संबंधित_नाम कोडिंग मुश्किल है (उदाहरण के लिए ..., संबंधित_नाम = "myname") इन संघर्ष त्रुटियों की संख्या में परिणाम होगा - बेस क्लास से प्रत्येक को विरासत में मिला वर्ग। नीचे दिए गए लिंक में वर्कअराउंड है, जो सरल है, लेकिन निश्चित रूप से स्पष्ट नहीं है।

Django डॉक्स से ...

यदि आप किसी ForeignKey या ManyToManyField पर संबंधित_नाम विशेषता का उपयोग कर रहे हैं, तो आपको हमेशा फ़ील्ड के लिए एक अद्वितीय रिवर्स नाम निर्दिष्ट करना होगा। यह आम तौर पर अमूर्त आधार वर्गों में एक समस्या का कारण होगा, क्योंकि इस वर्ग के क्षेत्रों को प्रत्येक बार विशेषताओं (संबंधित_नाम सहित) के लिए बिल्कुल समान मूल्यों के साथ, प्रत्येक बच्चे वर्ग में शामिल किया जाता है।

अधिक जानकारी यहाँ


2

कभी-कभी आपको अतिरिक्त स्वरूपण का उपयोग करना पड़ता है related_name - वास्तव में, किसी भी समय जब विरासत का उपयोग किया जाता है।

class Value(models.Model):
    value = models.DecimalField(decimal_places=2, max_digits=5)
    animal = models.ForeignKey(
        Animal, related_name="%(app_label)s_%(class)s_related")

    class Meta:
        abstract = True

class Height(Value):
    pass

class Weigth(Value):
    pass

class Length(Value):
    pass

यहां कोई संघर्ष नहीं है, लेकिन संबंधित_नाम को एक बार परिभाषित किया गया है और Django अद्वितीय संबंध नाम बनाने के लिए ध्यान रखेगा।

तब मूल्य वर्ग के बच्चों में, आपकी पहुंच निम्न तक होगी:

herdboard_height_related
herdboard_lenght_related
herdboard_weight_related

0

मुझे यह कभी-कभार लगता है जब मैं एक django परियोजना के लिए एक आवेदन के रूप में एक सबमॉड्यूल जोड़ता हूं, उदाहरण के लिए निम्नलिखित गति:

myapp/
myapp/module/
myapp/module/models.py

यदि मैं निम्नलिखित INSTALLED_APPS में जोड़ता हूं:

'myapp',
'myapp.module',

Django दो बार myapp.mymodule model.py फ़ाइल संसाधित करता है और उपरोक्त त्रुटि फेंकता है। इसे INSTALLED_APPS सूची में मुख्य मॉड्यूल शामिल नहीं करके हल किया जा सकता है:

'myapp.module',

कारणों के myappबजाय myapp.moduleसभी डेटाबेस तालिकाओं को गलत नामों से बनाया जाना शामिल है, इसलिए ऐसा करने का सही तरीका प्रतीत होता है।

मैं इस समस्या का हल ढूंढते हुए इस पोस्ट पर आया, इसलिए लगा कि मैं इसे यहाँ रखूँगा :)


0

जॉर्डन के जवाब (टिप जॉर्डन के लिए धन्यवाद) को जोड़ने से यह तब भी हो सकता है यदि आप ऐप्स के ऊपर के स्तर को आयात करते हैं और फिर एप्लिकेशन आयात करते हैं जैसे

myproject/ apps/ foo_app/ bar_app/

इसलिए यदि आप ऐप्स, foo_app और bar_app आयात कर रहे हैं तो आपको यह समस्या आ सकती है। मेरे पास ऐप्स, foo_app और bar_app सभी सेटिंग्स में सूचीबद्ध हैं। INSTALLED_APPS

और आप वैसे भी ऐप्स आयात करने से बचना चाहते हैं, क्योंकि तब आपके पास एक ही ऐप 2 अलग-अलग नामस्थानों में स्थापित है

apps.foo_app तथा foo_app

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