Django F似乎不起作用? [英] Django F doesn't seem to work?

查看:73
本文介绍了Django F似乎不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗯,由于某种原因,即使在最简单的模型上,我似乎也无法正常运行F。在Django 1.9.x上。

Huh, for some reason I can't seem to get F working properly even on the simplest of models. Here on Django 1.9.x.

最简单的形式是TestAccount

In the simplest form, 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 / zh-CN / 1.9 / ref / models / instances /#updating-attributes-based-on-existing-fields 应该起作用...

But according to this: https://docs.djangoproject.com/en/1.9/ref/models/instances/#updating-attributes-based-on-existing-fields it should work...

我不知道F不会被排除在验证之外。

Why F isn't being excluded from validation I don't know. It should be, and Django should just create a query to update it.

推荐答案

这在纯Django中很好用。您遇到的问题是您有一个监听器(在 helium.internal.signals 中)到 pre_save 信号,尝试执行以下操作:

This works fine in pure Django. The problem in your case is that you have a listener (in helium.internal.signals) to the pre_save signal which tries to do this:

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

Model.full_clean 会为模型中的每个字段期望一堆值,但是在这种情况下,您的一个字段不是值,而是一个 CombinedExpression 尚未被评估,只有在Django写入数据库时​​才会被评估。这会导致错误。

Model.full_clean expects a bunch of values for each field in your model, but in this case one of your fields is not a value but a CombinedExpression which hasn't yet been evaluated, and will only get evaluated when Django writes to the database. This causes the error.

IMO,您需要执行自己的验证,以实现 full_clean 的逻辑并进行处理表达式,或者您需要从 full_clean 中排除包含表达式的字段。

IMO you either need to perform your own validation that implements the logic of full_clean and handles Expressions, or you need to exclude fields containing expressions from full_clean.

这篇关于Django F似乎不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆