Django Admin - 具有foreignkey字段的模型的自定义清理方法

时间:2012-11-26 18:19:17

标签: django-models django-forms django-admin django-1.4

考虑以下模型:

class Arena(models.Model):
  crowd_capacity = models.PositiveInteger()
  # more fields here

class Section(models.Model):
  name = models.CharField(max_length=10)
  crowd_capacity = models.PositiveInteger()
  arena = models.ForeignKey(Arena, related_name='sections')

admin.py:

class SectionInline(admin.StackedInline):
    model = Section
    fk_name = 'arena'
    extra = 1

class ArenaAdmin(admin.ModelAdmin):
    inlines = [
        SectionInline,
    ]

我想添加一个验证方法来检查所有section.crowd_capacity的总和是否超过总的arena.crowd_capacity。

起初我想用干净的方法编写一个自定义的SectionFormSet,但后来我还没有看到如何获得arena.crowd_capacity。

我还尝试向Arena添加干净的方法,它确实显示了一个很好的红色验证错误,但没有解决问题。在保存所有部分之后看起来像竞技场清洁方法运行,并且更改section.crowd_capacity和w.e部分该问题没有效果。

我试过的验证方法:

def clean(self):
        super(Arena, self).clean()
        capacity = 0
        for s in self.sections.all():
            capacity += s.crowd_capacity

        if capacity > self.crowd_capacity:
            raise ValidationError('The sum of all sections crowd capacity '
                                  'exceeds arena crowd capacity')

1 个答案:

答案 0 :(得分:4)

好的,我终于找到了办法。

为了澄清,我想验证所有部分的人群容量总和不超过总竞技场人群容量。

最终解决方案是(在admin.py中):

class SectionFormSet(forms.models.BaseInlineFormSet):
    def clean(self):
        if any(self.errors):
            return
        capacity = 0
        for f in self.forms:
            try:
                capacity += f.cleaned_data['crowd_capacity']
                if capacity > f.cleaned_data['arena'].crowd_capacity:
                    raise ValidationError('The sum of all sections crowd capacity '
                                              'exceeds arena crowd capacity')
            except KeyError:
                # in case of empty form
                pass


class SectionInline(admin.StackedInline):
    model = Section
    formset = SectionFormSet

class ArenaAdmin(admin.ModelAdmin):
    inlines = [
        SectionInline,
    ]

多数民众赞成,模特没有变化。像魅力一样工作:)