[Fixed]-Dependent multi object validation in django admin

1👍

Some hints on the problem:

You should not iterate over the full table when checking for overlapping rows. Just filter for the problematic rows… something like:

overlaps = TimeRangeClass.objects.filter(
    Q(start_time__gte=self.start_time, start_time__lt=self.end_time) | 
    Q(end_time__gt=self.start_time, end_time__lte=self.end_time)
)

overlaps is now a queryset that evaluates when you iterate over it and only returns the conflicting objects.

If you are using Django with postgres you should check out https://docs.djangoproject.com/es/1.9/ref/contrib/postgres/fields/#datetimerangefield.

Once you have the conflicting objects you should be able to change their start and end times within the function and save the changes. Model.save() will not automatically call the model.clean() method. But be aware, if you save an object from the Django admin it will call the model.clean() method before saving.

So something like that:

def clean():
    overlaps = TimeRangeClass.overlaps.for_trc(self)
    for trc_object in overlaps:
        fixed_object = fix_start_end(trc_object, self)
        fixed_object.save()

If you feel brave you should also read up on transactions to make the mutation of multiple objects in the database all succeed or all fail and nothing in between.

def clean():
    with transaction.atomic():
        # do your multi object magic here ...

Update on clarified question:

If you want to validate or pre/process data that comes from admin inlines you have to hook into the corresponding ModelAdmin method(s). There are multiple ways to approach this. I guess the easiest would be to override ModelAdmin.save_fromset. Here you have access to all the inlineforms before they have been saved.

👤Titusz

Leave a comment