1

I have a model where I need to validate that an m2m field and a regular field are exclusive. (i.e. you can only have one or the other, not both.)

class EventFrequency(models.Model):
    weekdays = models.CharField(...)
    dates = models.ManyToManyField(...)

Since one is an m2m, overriding the model save() doesn't work. (the model is saved, then m2m added)

I was able to throw the error successfully in the admin class by overriding save_related(), but it doesn't display in the admin form. It is just a regular server error.

class EventFrequencyAdmin(VersionAdmin, admin.ModelAdmin):
    model = EventFrequency
    filter_horizontal = ('dates',)

    def save_related(self, request, form, formsets, change):
        super(EventFrequencyAdmin, self).save_related(request, form, formsets, change)
        if form.instance.dates.exists() and form.instance.weekdays:
            raise ValidationError('Cannot select both dates and weekdays.')

I am able to catch the error in an attempt to show it to the user by overriding changeform_view(). It appears to work well except for the redirect. form_url has no value, and is therefore ''.

def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
        try:
            return super(EventFrequencyAdmin, self).changeform_view(request, object_id, form_url, extra_context)
        except ValidationError as e:
            print('************* caught error *************')
            self.message_user(request, e, level=messages.ERROR)
            return HttpResponseRedirect(form_url)

What am I doing wrong?

mhatch
  • 4,441
  • 6
  • 36
  • 62

1 Answers1

1

What about creating a pre-save signal and having your validation logic in there so that you can raise the validation error in that way?

https://docs.djangoproject.com/en/3.0/ref/signals/#pre-save

Another idea

What about specifying a custom ModelForm for the admin and overriding the clean on that form?

Custom validation in Django admin

Mike Sandford
  • 1,315
  • 10
  • 22
  • I prefer to avoid the signal if possible. I really only want this validation error raised on use in the admin form. I expect pre_save would not work with the m2m as well... I believe you would need m2m_changed. – mhatch Aug 11 '20 at 22:27