如何自动查找少数字段的总和并将其保存在DJANGO的另一个字段中?

时间:2013-04-04 13:26:14

标签: django django-models django-forms

class EmployeeRating(models.Model):
    rating_1 = models.IntegerField(default = 0)
    rating_2 = models.IntegerField(default = 0)
    rating_3 = models.IntegerField(default = 0)
    rating_4 = models.IntegerField(default = 0)
    rating_4 = models.IntegerField(default = 0)
    total = models.IntegerField(default = 0)

使用模型表格获取值,自动将值分配给“总计”。

2 个答案:

答案 0 :(得分:1)

class EmployeeRatingForm(forms.ModelForm):
    class Meta:
        model = EmployeeRating

    def __init__(self, *args, **kwargs):
        super(EmployeeRatingForm, self).__init__(*args, **kwargs)
        self.fields['total'].widget = forms.HiddenInput()

    def save(self, commit=True):
        rating = super(EmployeeRatingForm, self).save(commit=False)
        rating1 = self.cleaned_data['rating_1']
        rating2 = self.cleaned_data['rating_2']
        rating3 = self.cleaned_data['rating_3']
        rating4 = self.cleaned_data['rating_4']

        rating.total = rating1 + rating2 + rating3 + rating4
        rating.save()

答案 1 :(得分:1)

1。不要重复自己

在模型中包含一个包含同一模型中其他一些字段总数的字段似乎是一个坏主意。更新一个而不是另一个更容易,使字段不一致。

所以我的建议是删除total字段并在需要时进行计算。

您可以将方法添加到用Python计算的EmployeeRating模型中:

class EmployeeRating(models.Model):
    # ...

    @property
    def total_rating(self):
        return self.rating_1 + self.rating_2 + self.rating_3 + self.rating_4

如果您需要查询总数,可以使用extra()

EmployeeRating.objects.extra(
    where = ['rating_1 + rating_2 + rating_3 + rating_4 > 10'])

2。规范化!

这很尴尬的原因是你的模型不是fully normalized。如果您对EmployeeRating记录附加了多个评级,则实现它们的自然方式是使用单独的表。如果你这样做,你的模型将如下所示:

class EmployeeRating(models.Model):
    # ... other fields, e.g. foreign key to Employee model.

class Rating(models.Model):
    employee_rating = models.ForeignKey(EmployeeRating, related_name='ratings')
    rating = models.IntegerField()
    # ... other fields, e.g. who performed the evaluation, or when it was done.

然后,当您需要获得总数时,您可以使用annotate()

from django.db.models import Sum
EmployeeRating.objects.annotate(total_rating = Sum('ratings__rating'))