Django模型字段从其他字段计算

时间:2015-06-05 02:22:42

标签: python django django-models django-admin

此处还有其他一些问题,但没有一个问题有帮助。

我希望yield字段由yield = starts / finishes字段计算。我想使用Highcharts来绘制它。

但是,当我通过管理员门户添加对象时 - 它设置yield = 0并且不会计算。

models.py:

class wYield(models.Model):
    starts = models.PositiveIntegerField(default=0)
    finishes = models.PositiveIntegerField(default=0)


## ONE: i've tried the below:
    yield_num = model.FloatField()
    def save(self, *args, **kwargs):
        if self.starts > 0:
             self.yield = self.finishes / self.starts 
        else:
             self.yield = 0
        super(wYield, self).save(*args, **kwargs)

## TWO: i've tried this but then I don't know how to see it in the Admin view:
    def _set_yield(self):
        if self.starts > 0:
             x = self.finishes / self.starts 
        else:
             x = 0
        return x
    yield_num = property(_set_yield)

 ## THREE: I think this works the same as TWO
    @property
    def yield_num(self):
        if self.starts > 0:
             return self.finishes / self.starts
        else:
             return 0

admin.py:

from .models import wYield

class wYieldAdmin(admin.ModelAdmin):
    list_display = ('starts', 'finishes', 'yield_num')

admin.site.register(wYield, wYieldAdmin)

3 个答案:

答案 0 :(得分:2)

想出来(在AbhiP的帮助下!)Python int类型转换是罪魁祸首。有愚蠢的问题!

下面是有效的,并允许我不保存计算字段(但显示它并使其像模型中的字段一样):

@property
    def yield_num(self):
        if self.starts > 0:
              #needed the float() to cast it out of an int
             return self.finishes / float(self.starts)
        else:
             return 0

答案 1 :(得分:1)

也许你不必每次都把它保存在数据库上,因为它可以动态计算;否则你就是在浪费空间。更不用说db值的重复性了。

此外,如果明天你的yield逻辑发生了变化,你就可以完全自由地对你的lambda表达进行修改。这是一个例子:

Class wYieldAdmin(admin.ModelAdmin):
    yield = lambda self: (self.finishes / self.starts) if self.starts > 0 else 0
    yield.short_description = 'Yield'
    list_display = ('starts', 'finishes', 'yield')

答案 2 :(得分:0)

Class wYieldAdmin(admin.ModelAdmin):
yield = lambda self: (self.finishes / self.starts) if self.starts > 0 else 0
yield.short_description = 'You have a big head'
list_display = ('starts', 'finishes', 'yield')