模型属性django中的简单乘法?

时间:2012-05-17 17:31:44

标签: python django

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

2 个答案:

答案 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.