Reputation: 83557
From the Django documentation for ManyToManyField
:
If you don’t want multiple associations between the same instances, add a UniqueConstraint including the from and to fields. Django’s automatically generated many-to-many tables include such a constraint.
How do I disable this constraint? Is the only way to provide an explicit through
table? Or is there a way to tell Django to not add the UniqueConstraint
to the generated many-to-many-table?
Upvotes: 1
Views: 1125
Reputation:
You can monkey patch django.db.models.fields.related.create_many_to_many_intermediary_model
, which creates the intermediary model and that's the closest you can get to it. It is called from the contribute_to_class
method on ManyToManyField. Of course, this is more work than specifying a through model, but if you have a use case where all (or most) of your intermediaries require no constraint, then this is worth looking into.
I don't see a supported way to override just this constraint.
And yes, you can subclass ManyToManyField and set the through model there through a utility function that is identical to the above mentioned, barring the constraint and then call super(). This would evade the constraint, because contribute_to_class doesn't call the above method when a through model is already set:
if not cls._meta.abstract:
if self.remote_field.through:
def resolve_through_model(_, model, field):
field.remote_field.through = model
lazy_related_operation(resolve_through_model, cls, self.remote_field.through, field=self)
elif not cls._meta.swapped:
self.remote_field.through = create_many_to_many_intermediary_model(self, cls)
Both methods have the same caveat: you need to manually synchronize your alternate utility with Django's upon Django upgrades, all for the purpose of removing one line:
'unique_together': (from_, to),
.
Upvotes: 1
Reputation: 1242
m2m tables are linked by an intermediary table which manages the relationships and has a unique_together
constraint. This table is automatically created but you can use your own table as the doc says with the through
argument. You can read about it in the docs. In your case you need disable the unique_together
constraint by defining your own intermediary table.
Other options are:
ManyToManyField
and override the contribute_to_class
method.ManyToManyField
directly as @Melvyn mentioned.Upvotes: 2