Reputation: 883
I want a TabularInline field in Django admin to be required. How do I proceed? Here's my code:
admin.py
class SchoolInline(TabularInline):
model = School.labs.through
extra = 1
class LaboratoryAdmin(ModelAdmin):
inlines = [SchoolInline]
register(Lab, LaboratoryAdmin)
I simplified a lot the problem, but basically that's it. In result I get a drop-down list with all the schools. The problem is that this field isn't required, but I want it to be required. How can I do this the most simple way?
Upvotes: 1
Views: 2746
Reputation: 1987
forms.py
# One form required
from django.core.exceptions import ValidationError
from django.forms.models import BaseInlineFormSet
class AtLeastOneFormSet(BaseInlineFormSet):
def clean(self):
super(AtLeastOneFormSet, self).clean()
non_empty_forms = 0
for form in self:
if form.cleaned_data:
non_empty_forms += 1
if non_empty_forms - len(self.deleted_forms) < 1:
raise ValidationError("Please fill at least one form.")
forms.py
# First form not empty and can not be deleted
from django.forms.models import BaseInlineFormSet
class RequiredInlineFormSet(BaseInlineFormSet):
def _construct_form(self, i, **kwargs):
form = super(RequiredInlineFormSet, self)._construct_form(i, **kwargs)
if i < 1:
form.empty_permitted = False
return form
You also need to change the view and remove the delete
button for the first form as shown here:
https://docs.djangoproject.com/en/dev/topics/forms/formsets/#manually-rendered-can-delete-and-can-order
admin.py
from django.contrib.admin import TabularInline
class SchoolInline(TabularInline):
model = School.labs.through
extra = 1
formset = RequiredInlineFormSet # or AtLeastOneFormSet
Upvotes: 4