Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#33832 closed New feature (invalid)

Support M2M validation using signals

Reported by: ldeluigi Owned by: nobody
Component: contrib.admin Version: 4.0
Severity: Normal Keywords: validation m2m signal manytomany
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

MyModel has one ManyToManyField that links to AnotherModel.

For validation purposes I need to check the model after m2m relationships have been set with custom logic based on the db (I can't check it before m2m fields are populated)

At the moment, I'm raising ValidationError inside a signal receiver:

@receiver(m2m_changed, sender=MyModel.relationship.through)
def validator_from_signal(sender, instance, action, reverse, model, **kwargs):
    if action == 'post_add':
        if reverse and not check_reverse(instance):
            msg = f'AnotherModel {instance.id} violates validation checks.'
            logging.error(msg)
            raise ValidationError(msg)
        elif not reverse and not check(instance):
            msg = f'MyModel {instance.id} violates validation checks.'
            logging.error(msg)
            raise ValidationError(msg)

It works, thanks to the transaction behaviour which in case of exception rollbacks everything, but if the user submits a wrong MyModel or AnotherModel (because of ManyToMany illegal relationships), in particular with the Admin Form, they get a 500 internal server error. Which isn't very user friendly...

I know this is the expected behaviour, but I'd like the Admin form to handle ValidationError(s) and/or IntegrityError(s) from signal as normal ValidationError. I can't implement this check inside the clean() method:

  1. because m2m fields are not populated on the database at that stage
  2. because it would only work for the admin form

What do you think?

Change History (2)

comment:1 by Mariusz Felisiak, 2 years ago

Component: Uncategorizedcontrib.admin
Resolution: invalid
Status: newclosed

Thanks for the ticket, however IntegrityErrors are not masked anywhere in the admin and they shouldn't be. Moreover, signals are the last resort and could probably be avoided in you case. Please see TicketClosingReasons/UseSupportChannels for ways to get help with Django usage, because it's a support request as it stands.

comment:2 by ldeluigi, 2 years ago

If someone stumbles upon this I managed to fix my issue with this:
https://forum.djangoproject.com/t/many-to-many-field-validation-in-django/14701/11

Last edited 2 years ago by ldeluigi (previous) (diff)
Note: See TracTickets for help on using tickets.
Back to Top