2012-02-16 19 views
36

मॉडल में किसी विदेशी कुंजी फ़ील्ड के लिए डिफ़ॉल्ट मान सेट करने का सबसे अच्छा तरीका क्या है? मान लीजिए मेरे पास दो मॉडल हैं, छात्र और परीक्षा जिसमें छात्र कुंजी के रूप में परीक्षा लेते हैं। मैं आदर्श रूप से इसके लिए डिफ़ॉल्ट मान कैसे निर्धारित करूं? यहां मेरे प्रयास का एक लॉग हैविदेशी कुंजी विशेषता के लिए डिफ़ॉल्ट मान सेट करना

class Student(models.Model): 
    .... 
    ..... 
    exam_taken = models.ForeignKey("Exam", default=1) 

काम करता है, लेकिन एक झटका है एक बेहतर तरीका है।

def get_exam(): 
    return Exam.objects.get(id=1) 

class Student(models.Model): 
    .... 
    ..... 
    exam_taken = models.ForeignKey("Exam", default=get_exam) 

here से, लेकिन टेबल के साथ विफल रहता है, जबकि सिंक करना त्रुटि मौजूद नहीं है।

किसी भी मदद की सराहना की जाएगी।

+0

कैसे करें: http://stackoverflow.com/questions/937954/how-do-you-specify-a-default-for-a-django-foreignkey-model-or-adminmodel-field –

+2

@TomIngram नहीं नहीं करना चाहिए! – balazs

+0

@NitzanTomer इसे AdminModelField के लिए। इसे पहले देखा था। – primpap

उत्तर

18

आपके दोनों उदाहरणों में, आप डिफ़ॉल्ट उदाहरण की आईडी को हार्ड-कोडिंग कर रहे हैं। यदि यह अपरिहार्य है, तो मैं बस स्थिर रखूंगा।

DEFAULT_EXAM_ID = 1 
class Student(models.Model): 
    ... 
    exam_taken = models.ForeignKey("Exam", default=DEFAULT_EXAM_ID) 

कम कोड, और निरंतर नामकरण इसे और अधिक पठनीय बनाता है।

+0

मैं निम्न त्रुटि हो: 'लेखन त्रुटि: अतिरिक्त तर्क नाम दिया जाना चाहिए _, मिल गया 'default'' कोड के साथ: 'category_id = db.column (db.Integer, db.ForeignKey (" category.id ", default = 1), primary_key = True)' क्या आप कृपया मदद कर सकते हैं? – ChickenFeet

+0

बीटीडब्ल्यू दो पीके हैं, इसलिए कुंजी अभी भी अद्वितीय होगी। – ChickenFeet

6

मैं प्राकृतिक कुंजी का उपयोग एक और अधिक प्राकृतिक दृष्टिकोण अपनाने के लिए:

<app>/models.py

from django.db import models 

class CountryManager(models.Manager): 
    """Enable fixtures using self.sigla instead of `id`""" 

    def get_by_natural_key(self, sigla): 
     return self.get(sigla=sigla) 

class Country(models.Model): 
    objects = CountryManager() 
    sigla = models.CharField(max_length=5, unique=True) 

    def __unicode__(self): 
     return u'%s' % self.sigla 

class City(models.Model): 
    nome = models.CharField(max_length=64, unique=True) 
    nation = models.ForeignKey(Country, default='IT') 
+2

मैंने Django 1.6 में यह कोशिश की लेकिन मुझे त्रुटि मिली, "आधार 10: 'आईटी' के साथ int() के लिए अमान्य शाब्दिक। (मेरी स्ट्रिंग अलग है, लेकिन आपको विचार मिलता है।) – Seth

+2

यह ठीक काम करता है, और लगता है अधिक पायथनिक: 'डिफ़ॉल्ट = लैम्ब्डा: Country.objects.filter (sigla =' IT ')। पहला() ' – Seth

+0

अजीब, मुझे यह पता चला है कि django 1.6 के साथ इसका परीक्षण किया गया है। गुगलिंग मुझे पता चला कि यह एक समस्या है, कोशिश करें:' def get_by_natural_key (स्वयं, सिग्ला): वापसी (self.get (sigla = sigla),) 'या 'डिफ़ॉल्ट = (' आईटी ',' के साथ भी। 'मैं बस अनुमान लगा रहा हूं;) – vault

2

आप इस पद्धति का उपयोग कर सकता:

class Other(models.Model): 
    DEFAULT_PK=1 
    name=models.CharField(max_length=1024) 

class FooModel(models.Model): 
    other=models.ForeignKey(Other, default=Other.DEFAULT_PK) 
बेशक

आप यकीन है कि वहाँ है कि होने की जरूरत है की तालिका में एक पंक्ति। यह सुनिश्चित करने के लिए आपको डेटामैपेशन का उपयोग करना चाहिए।

1

मेरे मामले में, मैं संबंधित मॉडल के किसी भी मौजूदा उदाहरण को डिफ़ॉल्ट सेट करना चाहता था। क्योंकि यह संभव है कि आईडी 1 साथ Exam हटा दिया गया है, मैं निम्नलिखित किया है:

class Student(models.Model): 
    exam_taken = models.ForeignKey("Exam", blank=True) 

    def save(self, *args, **kwargs): 
     try: 
      self.exam_taken 
     except: 
      self.exam_taken = Exam.objects.first() 
     super().save(*args, **kwargs) 

तो exam_taken मौजूद नहीं है, django.db.models.fields.related_descriptors.RelatedObjectDoesNotExist जब एक यह तक पहुँचने का प्रयास बढ़ा दी जाएगी।

संबंधित मुद्दे