2016-06-26 13 views
5

हू, किसी कारण से मैं मॉडल के सबसे सरल पर भी ठीक से काम नहीं कर पा रहा हूं। Django 1.9.x पर यहाँDjango F काम नहीं कर रहा है?

सरलतम रूप में, TestAccount

class TestAccount(models.Model): 
    decimal = models.DecimalField(max_digits=5, decimal_places=2) 
    integer = models.IntegerField() 



In [1]: ta = TestAccount() 

In [2]: ta.integer = 1 

In [3]: ta.decimal = 1 

In [4]: ta.save() 

In [5]: 

In [5]: 

In [5]: ta 
Out[5]: <TestAccount: TestAccount object> 

In [6]: ta.id 
Out[6]: 1L 

In [7]: from django.db.models.expressions import F 

In [8]: ta = TestAccount.objects.get(id=1) 

In [9]: ta.integer = F('integer') + 1 

In [10]: ta.save() 
--------------------------------------------------------------------------- 
ValidationError       Traceback (most recent call last) 
<ipython-input-10-6e9eda341b34> in <module>() 
----> 1 ta.save() 

/usr/lib/python2.7/site-packages/django/db/models/base.pyc in save(self, force_insert, force_update, using, update_fields) 
    706 
    707   self.save_base(using=using, force_insert=force_insert, 
--> 708      force_update=force_update, update_fields=update_fields) 
    709  save.alters_data = True 
    710 

/usr/lib/python2.7/site-packages/django/db/models/base.pyc in save_base(self, raw, force_insert, force_update, using, update_fields) 
    730   if not meta.auto_created: 
    731    signals.pre_save.send(sender=origin, instance=self, raw=raw, using=using, 
--> 732         update_fields=update_fields) 
    733   with transaction.atomic(using=using, savepoint=False): 
    734    if not raw: 

/usr/lib/python2.7/site-packages/django/dispatch/dispatcher.pyc in send(self, sender, **named) 
    190 
    191   for receiver in self._live_receivers(sender): 
--> 192    response = receiver(signal=self, sender=sender, **named) 
    193    responses.append((receiver, response)) 
    194   return responses 

/media/sf_helium/build/helium/internal/signals.pyc in validate_model(sender, **kwargs) 
    12 def validate_model(sender, **kwargs): 
    13  if 'raw' in kwargs and not kwargs['raw']: 
---> 14   kwargs['instance'].full_clean() 
    15 
    16 @receiver(pre_delete) 

/usr/lib/python2.7/site-packages/django/db/models/base.pyc in full_clean(self, exclude, validate_unique) 
    1142 
    1143   if errors: 
-> 1144    raise ValidationError(errors) 
    1145 
    1146  def clean_fields(self, exclude=None): 

ValidationError: {'integer': [u"'F(integer) + Value(1)' value must be an integer."]} 

लेकिन इस के अनुसार: https://docs.djangoproject.com/en/1.9/ref/models/instances/#updating-attributes-based-on-existing-fields यह काम करना चाहिए ...

क्यों एफ सत्यापन मैं नहीं जानता से बाहर रखा नहीं जा रहा है। यह होना चाहिए, और Django को इसे अद्यतन करने के लिए सिर्फ एक क्वेरी बनाना चाहिए।

उत्तर

5

यह शुद्ध Django में ठीक काम करता है। आपके मामले में समस्या pre_save संकेत जो ऐसा करने की कोशिश करता है करने के लिए आप एक श्रोता है (helium.internal.signals में) है:

def validate_model(sender, **kwargs): 
    if 'raw' in kwargs and not kwargs['raw']: 
     kwargs['instance'].full_clean() 

Model.full_clean अपने मॉडल में प्रत्येक क्षेत्र के लिए मूल्यों का एक समूह की उम्मीद है, लेकिन इस मामले में आपके फ़ील्ड का मूल्य नहीं है लेकिन CombinedExpression जिसका अभी तक मूल्यांकन नहीं किया गया है, और जब Django डेटाबेस को लिखता है तो केवल मूल्यांकन किया जाएगा। यह त्रुटि का कारण बनता है।

IMO आप या तो अपने स्वयं के सत्यापन कि full_clean के तर्क को लागू करता है और Expression रों हैंडल करने की आवश्यकता है, या आप full_clean से भाव युक्त क्षेत्रों को बाहर करने की जरूरत है।

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