Django Nested Admin validation of nested inlines from parent forms

908 views Asked by At

What I'm trying to do is assert the start_date of the child form is after the start_date of the parent form.

For example, if I have the following models:

class Parent(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    starts_at = models.DateTimeField(blank=True, null=True)


class Child(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    parent = models.ForeignKey(Parent, on_delete=models.CASCADE, related_name='children')
    starts_at = models.DateTimeField(null=True, blank=True)

And admin forms setup like:

class ChildInline(nested_admin.NestedTabularInline):
    model = models.Child
    extra = 0


@admin.register(models.Parent)
class ParentAdmin(nested_admin.NestedModelAdmin):
    inlines = [ChildInline]

How would I validate the child based on the parent (or vice-versa)?

So far I've explored:

  1. Form.clean() - but this doesn't include the child/parent instances.
  2. Formset.clean() - but despite making formsets it appears that django-nested-admin ignores them and their clean methods are never used.

Has anyone found a solution for this kind of issue?

1

There are 1 answers

0
Darkstarone On BEST ANSWER

It appears you can still use the model.clean() method for form validation:

from django.core.exceptions import ValidationError


class Child(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    parent = models.ForeignKey(Parent, on_delete=models.CASCADE, related_name='children')
    starts_at = models.DateTimeField(null=True, blank=True)

    def clean(self):
        parent_start = self.parent.starts_at
        child_start = self.starts_at
        if parent_start and child_start < parent_start:
            raise ValidationError(f'This group cannot start before the season starts')

Which will make ValidationError appear on the Child form. Using the clean method on the Parent form is also possible, and would give the errors at that level.