Django - 使用内联formset捕获IntegrityError

时间:2013-10-02 08:46:58

标签: django django-admin

我正在使用django-nested-inlines为这三个模型提供管理中的嵌套内联:

class Venue(models.Model):
    name = models.CharField(max_length=100)

class VenueBookingSetting(models.Model):
    venue = models.ForeignKey(Venue)
    name = models.CharField(max_length=100, default='')
    use_date_range = models.BooleanField(default=False)
    use_valid_days = models.BooleanField(default=False)
    days_in_advance = models.SmallIntegerField(default=DEFAULT_DIA)
    max_covers = models.SmallIntegerField(default=0, blank=True)
    active = models.BooleanField(default=False)

class VenueValidBookingDays(models.Model):
    booking_setting = models.ForeignKey(VenueBookingSetting)
    sunday = models.BooleanField(default=True)
    monday = models.BooleanField(default=True)
    tuesday = models.BooleanField(default=True)
    wednesday = models.BooleanField(default=True)
    thursday = models.BooleanField(default=True)
    friday = models.BooleanField(default=True)
    saturday = models.BooleanField(default=True)

这是我的Venue管理员设置:

class VenueBookingValidDaysInline(NestedTabularInline):
    model = VenueBookingValidDays

class VenueBookingSettingInline(NestedTabularInline):
    model = VenueBookingSetting
    inlines = [VenueBookingValidDaysInline,]

class VenueAdmin(NestedModelAdmin):
    inlines = [VenueBookingSettingInline,]

我遇到的问题是如果在没有填写父预订设置的情况下添加预订天数,会在哪里发现IntegrityError?我的意思是我取消选中一些有效日期,但不要更改任何父预订设置项目。任何人都可以告诉我应该在哪里捕获该错误以显示验证消息,而不是让页面崩溃到500错误?

1 个答案:

答案 0 :(得分:0)

我已经解决了这个问题。我需要覆盖VenueBookingSettingInline

的formset clean方法
class VenueBookingSettingInlineFormset(BaseNestedInlineFormSet):
    def clean(self):
        '''
        Ensure that any newly added nested form has a prent which has been completed,
        otherwise an IntegrityError will be raised causing a 500 error
        '''
        if any(self.errors):
            # Don't bother validating the formset unless each form is valid on its own
            return
        for form in self.forms:
            # if this form is a new addition (i.e. it has changed but it has no
            # id) then we need to save it and add it to the nested forms
            for nested_formset in form.nested_formsets:
                for nested_form in nested_formset:
                    if (nested_form.has_changed() and nested_form.instance.id is None and
                                        not form.has_changed() and form.instance.id is None):
                        raise forms.ValidationError('Please ensure you add a %s when adding a %s'
                            % (form._meta.model.__name__, nested_form._meta.model.__name__))

class VenueBookingSettingInline(NestedTabularInline):
    model = VenueBookingSetting
    inlines = [VenueBookingValidDaysInline,]
    formset = VenueBookingSettingInlineFormset

如果有人有更好或更清洁的解决方案,请发布。