#24731 closed New feature (needsinfo)
ManyToMany model clean validation of related fields
Reported by: | blah73 | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.8 |
Severity: | Normal | Keywords: | ManyToMany clean validation |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Suppose I have a model with a ManyToManyField similar to this one (the model Word has a language, too):
class Sentence(models.Model): words = models.ManyToManyField(Word) language = models.ForeignKey(Language) def clean(self): for word in self.words.all(): if word.language_id != self.language_id: raise ValidationError('One of the words has a false language')
When trying to add a new sentence (e.g. through django admin) I get 'Sentence' needs to have a value for field "sentence" before this many-to-many relationship can be used.
Apparently the only way to fix this is to put the validation logic in a forms.ModelForm and then add that form to the admin.ModelAdmin. This fixes the issue with the admin input but now my API is fragile. (Directly API access can add invalid data)
Is this part of a larger issue with Many to Many fields? Is there anything in progress that would alleviate this specific issue? I understand that the ManyToMany is pretty complex and this would likely require restructuring it. I'd like to help out if I possible... the current work around solution is kinda dangerous from a Django user perspective.
I borrowed this example from the following source:
http://stackoverflow.com/questions/7986510/django-manytomany-model-validation
and made a minimal example case in Django 1.8:
https://github.com/blah73/mmtest
Change History (6)
comment:1 by , 10 years ago
Resolution: | → needsinfo |
---|---|
Status: | new → closed |
comment:2 by , 10 years ago
Thanks for the link. Using m2m signals looks like it will work and I plan on implementing it. However it does add additional complexity compared to normal model validation. I'll make a post on the developers mailing list.
comment:3 by , 9 years ago
Hi everybody,
I also think this is an area for improvement in django.
I've posted on django-developers: https://groups.google.com/forum/#!topic/django-developers/pQ-8LmFhXFg
I quote the relevant bits:
I spent a few hours working on this issue, I consider myself fluent with django and it's quite shocking I had to put such an amount of effort just to validate many2many relationships before they are saved to the database.
IMHO it would be better if we could do one of these two (or even both) things:
- make this process easier in future django versions
- document the current best practice to solve this problem in current django to save people's time
What do people you think?
Here's my solution working with django 1.9:
https://github.com/openwisp/django-netjsonconfig/compare/4082988...dcdbbf4
What do you think of it? Can it be improved in some way?
Keep up the good work
Federico Capoano
comment:4 by , 7 years ago
This ticket was closed about 3 years ago. I just encountered this issue, and it's quite irritating. It definitely seems like something should be done about this. Can this be reopened?
comment:5 by , 7 years ago
As I said in comment one, if there is some consensus about how to proceed, the ticket may be reopened.
comment:6 by , 2 years ago
I'd put a catch for ValidationError or IntegrityError inside the save_form_data method that would catch signals that throw them, for example the m2m_changed 'post_add'
I'm not aware of any work or proposals that would make something like this possible. Since we'd need to make some decisions on an API, discussion should first happen on the DevelopersMailingList. I'll close this ticket until we have an action plan.
Possible solution using signals: http://schinckel.net/2012/02/06/pre-validating-many-to-many-fields./