2011-01-06 14 views
5

मैं Django में एक मॉडल के लिए custom primary keys का उपयोग कर रहा हूं। (यह था, क्योंकि मैं डेटाबेस में मूल्यों का आयात किया गया था और वे पहले से ही पहचान पत्र संलग्न किया था, और यह मौजूदा मूल्यों को बचाने के लिये भावना बनाया है।)Django: कस्टम पीके ऑटो-वृद्धि करना?

class Transaction(models.Model): 
    id = models.IntegerField(primary_key=True) 
    transaction_type = models.IntegerField(choices=TRANSACTION_TYPES) 
    date_added = models.DateTimeField(auto_now_add=True) 

हालांकि, अब मैं करने के लिए मॉडल का नया उदाहरणों जोड़ना चाहते हैं डेटाबेस, और मैं एक अद्वितीय प्राथमिक कुंजी को स्वत: उत्पन्न करना चाहता हूं।

t = Transaction(transaction_type=0) 
t.save() 

देता है::

IntegrityError at /page 
(1048, "Column 'id' cannot be null") 

मैं कैसे एक अद्वितीय ID autogenerate नए मूल्यों के लिए निर्दिष्ट करने के लिए कर सकते हैं लेकिन अगर मैं उदाहरण बनाकर के समय आईडी का उल्लेख नहीं है, मैं कोई त्रुटि मिलती है , मौजूदा मूल्यों को आयात करने के तरीके को बदलने के बिना?

अद्यतन

मैं जो काम करने के लिए लगता है इस कस्टम विधि, लिखा है ...

class Transaction(models.Model): 
    def save(self, *args, **kwargs): 
     if not self.id: 
      i = Transaction.objects.all().order_by('-id')[0] 
      self.id = i.id+1 
     super(Transaction, self).save(*args, **kwargs) 
+0

मुझे उत्सुकता है - यदि आप थोक आयात कर रहे हैं तो django प्राथमिक कुंजी को संभालने की समस्या क्या थी? मेरे पास ऐसी स्थिति कभी नहीं थी जहां प्राथमिक कुंजी समस्या थी - जब तक कि आप एक उत्पादन/चल रहे सिस्टम पर आयात नहीं कर रहे हों। –

उत्तर

1

कैसे आप मौजूदा मूल्यों आयात कर रहे हैं? आपके लिए एक नया आईडी उत्पन्न करने के लिए अपने Transaction एस __init__ में कुछ लिखना तुच्छ होगा, लेकिन यह जानने के बिना कि आप अन्य मूल्यों को कैसे आयात कर रहे हैं, मैं निश्चित रूप से यह नहीं कह सकता कि यह आपके साथ काम करने के तरीके को बदल देगा या नहीं।

+0

यह सुनिश्चित नहीं है कि यह आपके प्रश्न का उत्तर देता है, लेकिन: एक CSV फ़ाइल से, एक कस्टम आयात स्क्रिप्ट का उपयोग करके, और CSV फ़ाइल में आईडी पर लेनदेन आईडी फ़ील्ड सेट करना। (इसके अलावा: मैं प्रत्यक्ष एसक्यूएल की बजाय Django वस्तुओं का उपयोग करके उन्हें आयात करता हूं।) क्या इससे मदद मिलती है? – AP257

+0

हां। अपने 'लेनदेन की '__init__' लिखने के बजाय,' सेव()' ओवरराइड करें ताकि यह पहली बार जांच सके कि उसके पास आईडी है, और फिर यदि यह आपके लिए एक नया उत्पन्न नहीं करता है (और फिर सामान्य रूप से सहेजता है)। – girasquid

+0

मुझे 'save()' ओवरराइड करने के लिए जाना है और ऊपर दिए गए अपडेट के रूप में जोड़ा गया है - कृपया आप मुझे बता सकते हैं कि यह बेहद समझदार दिखता है, और फिर मैं आपका जवाब स्वीकार करूंगा? धन्यवाद! – AP257

2

IntegerField के बजाय आप id कॉलम के लिए AutoField का उपयोग कर सकते हैं। निम्नलिखित आप के लिए काम करना चाहिए:

id = models.AutoField(primary_key=True) 

id अब स्वचालित रूप से वृद्धि होगी और संगामिति समस्या नहीं होगा के रूप में यह save विधि में आ सकती है।

2

मैं कोड के बहुत समान टुकड़ा का उपयोग कर समाप्त हो गया है, लेकिन यह थोड़े अधिक सामान्य बना दिया है:

def save(self, *args, **kwargs): 
    if self.id is None: 
     self.id = self.__class__.objects.all().order_by("-id")[0].id + 1 
    super(self.__class__, self).save(*args, **kwargs) 

इसे इस्तेमाल करता है self.__class__ तो आप कुछ भी बदलने के बिना किसी भी मॉडल वर्ग के लिए इस कोड को बस कॉपी कर सकते हैं।

0

आप अपने घोषित आईडी क्षेत्र निकालते हैं, तो Django स्वचालित रूप से इस समझेंगे:

id = models.AutoField(primary_key=True) 

Django 1.8 में, inspectdb स्वचालित रूप से auto_increment की पहचान करेगा और जब मॉडल जनित करने में AutoField का उपयोग करें।

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