在django admin master-detail界面中添加验证(用于详细记录)

时间:2015-11-08 06:31:34

标签: python django python-3.x

我有以下示例,我不知道如何为管理界面中的每一行设置验证错误:

  

请参阅forms.py

中该行的#addal validation错误

models.py:

from django.db import models
from django.core.exceptions import ValidationError

class Foo(models.Model):
   name = models.CharField("Name", blank=True, max_length=300)

class Bar(models.Model):
   name = models.CharField("Name", blank=True, max_length=300)
   foo = models.ForeignKey('Foo', verbose_name='Foo')

admin.py

from django.contrib import admin
from .models import *
from .forms import *

class BarInline(admin.TabularInline):
    model = Bar
    formset = BarInlineFormset

@admin.register(Foo)   
class FooAdmin(admin.ModelAdmin):
    model = Foo
    inlines = [BarInline,]

forms.py

from django.db import models
from django import forms
from django.core.exceptions import ValidationError

class BarInlineFormset(forms.models.BaseInlineFormSet):
    def clean(self):
        data = self.cleaned_data
        valid = True
        for item in data:
            if not item:
                break;
            if not item['name'].startswith('Bar'):
                valid = False
                # add validation error for that row

        if not valid:
            raise ValidationError('Form is not valid.')

        return data
  

P.S。我使用的是Django 1.8.x和Python 3.4

2 个答案:

答案 0 :(得分:1)

要向内联表单集添加验证,您可以创建自定义表单并将此表单指定给表单集,而不是创建自定义基本内联表单集:

class MyForm(forms.ModelForm):
    def clean(self):
        cleaned_data = super(MyForm, self).clean()
        for field in cleaned_data:
            # if some meaningful condition for field is met:
                # raise validation error
        return cleaned_data

    class Meta:
        model = ParentModel
        fields = ['fieldA', 'fieldB', ...]

BarInlineFormset = inlineformset_factory(ParentModel, Model, form=MyForm, extra=0, min_num=0)

不要忘记正确配置模型表单,尤其是元类以定义模型和字段。

参考:Django documentation: Model form FunctionsCreating forms from models

答案 1 :(得分:0)

我有一个简单的解决方案,工作完美:

admin.py

class BarInline(admin.TabularInline):
    model = Bar
    form = BarForm

@admin.register(Foo)   
class FooAdmin(admin.ModelAdmin):
    model = Foo
    inlines = [BarInline,]

forms.py

class BarForm(forms.models.ModelForm):
    class Meta:
        model = Bar
        fields = ('name',)

    def clean(self):
      data = self.cleaned_data     
      if not item['name'].startswith('Bar'):
         raise ValidationError('Item is not valid.')
  

所以我没有使用InlineFormSet而且我根本没有使用inlineformset_factory,这是一个完整的解决方案,不仅可以解决一些未经测试的搜索带来的碎片