【问题标题】:Django Admin - Custom clean method for a model with foreignkey fieldDjango Admin - 具有外键字段的模型的自定义清理方法
【发布时间】:2012-11-26 18:19:17
【问题描述】:

考虑以下模型:

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 总数。

一开始我想用 clean 方法编写一个自定义的 SectionFormSet,但后来我没有看到如何获取 arena.crowd_capacity。

我还尝试向 Arena 添加 clean 方法,它确实显示了一个不错的红色验证错误,但无法解决问题。看起来 Arena clean 方法在保存所有部分后运行,并且更改 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')

【问题讨论】:

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


    【解决方案1】:

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

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

    最终解决方案是(在 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,
        ]
    

    就是这样,模型没有变化。像魅力一样工作:)

    【讨论】:

      猜你喜欢
      • 2011-06-12
      • 2016-04-16
      • 2015-06-13
      • 2014-12-20
      • 1970-01-01
      • 2015-09-17
      • 1970-01-01
      • 1970-01-01
      • 2016-07-24
      相关资源
      最近更新 更多