我有如下所示的模型字段:
user=models.ForeignKey(CustomUser, null=True)
_corporate = models.CharField(max_length=10, null=True, db_column='corporate')
def set_corporate(self,value):
if self.user.corporateuser_set.all():
self._corporate = self.user.corporateuser_set.values_list('company', flat=True)
corporate= property(set_corporate)
不知何故,未评估set_corporate,因此_corporate字段未更新。
那么我应该怎么做才能使其正常工作呢?最好的方法是什么?
我有另一个与用户模型具有一对多关系的模型(CorporateUser),这只是为了澄清我的问题。
您在很多方面都做错了。
首先,在python中以这种方式使用属性:
class A:
@property
def foo(self):
return self._foo
@foo.setter
def foo(self, value):
self._foo = value
或者这样:
class A:
def get_foo(self):
return self._foo
def set_foo(self, value):
self._foo = value
foo = property(get_foo, set_foo)
注意如何将值传递给设置器。不应像您那样在此处进行计算。如果您需要自动更新公司价值,则不需要属性,则应覆盖模型.save()
方法或侦听其pre_save
信号并在那里更新字段。
其次,您不应有条件地设置在setter中。设置器应始终将属性设置为传递的值。像这样:
def set_corporate(self, value):
# If the list is empty then corporate becomes empty
self._corporate = \
self.user.corporateuser_set.values_list('company', flat=True)
通过违反此规则,您将引起悲伤:
obj.corporate = 'hi'
# obj.corporate is now 'hi'
obj.corporate = ''
# obj.corporate is still 'hi'. WTF?
第三,您不应分配list
给CharField
。这应该如何工作?它将使它字符串化。
第四,您甚至没有分配列表,而是分配了查询集,这更糟。
第五,您实际上在两行中两次执行了相同的数据库请求。检查是否为空然后赋值的有效方法是重用同一查询集:
corporates = self.user.corporateuser_set.values_list('company', flat=True)
if corporates:
# Stringify it explicitly and our way
self._corporate = ','.join(corporates)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句