我试图在此代码中为属性阈值设置默认值,阈值应该是当前级别* 50,这是模型
class Level (models.Model):
name = models.CharField(max_length=20,null=True, blank=True)
description = models.CharField(max_length=20, null=True, blank=True)
number = models.IntegerField(null=True, blank=True)
threshold = models.IntegerField(null=True, blank=True,default=50*number,editable=False)
我收到错误unsupported operand types for * : 'int' and 'IntegerField'
答案 0 :(得分:2)
您最好在保存对象时进行此类计算。所以覆盖Model.save
或更好的通用方法是编写自定义字段并覆盖pre_save
class DependentIntegerField(models.IntegerField):
def pre_save(self, model_instance, add):
if not add: # set the default only while adding model
return super(self, DependentIntegerField).pre_save(model_instance, add)
return model_instance.number*50
您可以进一步增强它并使DependentIntegerField
通用,以便您可以将callable传递给它并进行任何计算,并且您可以进行进一步的增强,例如在使用默认值之前检查用户是否设置了值,并使其更通用,以便您可以通过将字段类传递给工厂函数将任何字段作为依赖字段。 e.g。
from django.db import models
class_map = {}
def depends_field_pre_save(self, model_instance, add):
"""
if default is not callable or it is not a model add, lets skip our hook
"""
if not add or not callable(self.default):
super(self.__class__, self).__init__(self,*args, **kwargs)
value = self.default(model_instance)
setattr(model_instance, self.attname, value)
return value
def FieldDepends(field_class):
"""
return a dervied class from field_class which supports dependent default
"""
if field_class in class_map:
# we already created this class so return that
return class_map[field_class]
new_class = type('Depends'+field_class.__name__, (field_class,), {'pre_save':depends_field_pre_save })
class_map[field_class] = new_class
return new_class
并像这样使用
class DependentModel(models.Model):
def threshold_default(model_instance=None):
if model_instance is None:
return 10
return model_instance.number*10
number = models.IntegerField(null=True, blank=True, default=10)
threshold = FieldDepends(models.IntegerField)(null=True, blank=True, default=threshold_default,editable=False)
我在bitbucket上创建了一个带有测试用例的小型django项目djangodepends
答案 1 :(得分:1)
您可以将保存方法覆盖为计算。
https://docs.djangoproject.com/en/dev/topics/db/models/#overriding-predefined-model-methods
class Level (models.Model):
name = models.CharField(max_length=20,null=True, blank=True)
description = models.CharField(max_length=20, null=True, blank=True)
number = models.IntegerField(null=True, blank=True)
threshold = models.IntegerField(null=True, blank=True ,editable=False)
def save(self, *args, **kwargs):
try:
self.threshold = self.number * 50
except TypeError:
pass
super(Level, self).save(*args, **kwargs) # Call the "real" save() method.