I've added some validation to an inline in the django admin, which won't let the inline be saved if a field on the model instance doesn't exist. I don't want additional deadlines to be added if there isn't a deadline already:
class DeadlineInlineFormset(forms.models.BaseInlineFormSet):
def clean(self):
super(DeadlineInlineFormset, self).clean()
# make sure deadline is set
if not self.instance.deadline:
raise ValidationError(_("Doesn't validate"))
class DeadlineInline(admin.StackedInline):
model = AdditionalDeadline
formset = DeadlineInlineFormset
class GrantAdmin(admin.ModelAdmin):
...
inlines = [DeadlineInline]
...
This works fine but I'm struggling to unit test it. So far I have:
class GrantAdminTestCase(TestCase):
fixtures = [...]
def test_forms(self):
# create the form from a model instance.
# it should validate but it doesn't
g = Grant.objects.first()
form = GrantAdminForm(instance=g)
self.assertEqual(form.is_valid(), True)
# remove deadline and add additional deadlines
# It shouldn't be valid because deadline is None
g.deadline = None
g.additional_deadlines.add(
Deadline(deadline=datetime.now())
)
self.assertEqual(form.is_valid(), False)
The first assert fails even though the model instance is valid. The second assert passes but shouldn't because it now should be invalid. So something is definitely wrong.
I'm also not sure if this is the right way to do it at all. Would it be easier to put validation in the model? Or even in the form rather than the formset?
Edit: Quite a lot of this was wrong, I've changed a few things but it's still not working:
def test_forms(self):
g = Grant.objects.first()
form = GrantAdminForm(model_to_dict(g))
self.assertEqual(form.is_valid(), True)
DeadlineFormSet = inlineformset_factory(Grant, Deadline)
# should be invalid
g.deadline = None
g.additional_deadlines.add(Deadline(deadline=datetime.now()))
formset = DeadlineFormSet(instance=g)
self.assertEqual(formset.is_valid(), False)
# should be valid
g = Grant.objects.first()
formset = DeadlineFormSet(instance=g)
self.assertEqual(formset.is_valid(), True)
The first two assertions pass but the last doesn't.