1

我正在尝试在此代码中设置属性阈值的默认值,阈值应为当前级别*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'

4

2 回答 2

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 传递给它并进行任何计算,并且您可以进行进一步的增强,例如在使用默认值之前检查用户是否设置了该值,并使其更通用以便您可以通过将字段类传递给工厂函数来将任何字段设为依赖字段。例如

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)

我创建了一个小型 django 项目djangodepends on bitbucket 和测试用例

于 2012-05-17T17:35:02.980 回答
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.
于 2012-05-17T17:35:20.947 回答