How to have a many to many relation that enforces uniqueness when I use an intermediate model?
Asked Answered
F

4

7

I use intermediate model for "ManyToManyField using the through"
Normally,If I don't use intermediate field, the m2m relation will be unique and can't have the duplicated data.

After I use intermediate model. the relation between m2m can have same data. like this

|    |    ['0'] (
|    |    |    addToProfile => Array (0)
|    |    |    (
|    |    |    )
|    |    |    endDate =  NULL
|    |    |    feedType =  "N"
|    |    |    id =  1
|    |    |    info =  "Big Kuy No Fear"
|    |    |    likeMaker => Array (3)
|    |    |    (
|    |    |    |    ['0'] =  "/api/v2/user/2/"
|    |    |    |    ['1'] =  "/api/v2/user/2/"
|    |    |    |    ['2'] =  "/api/v2/user/2/"
|    |    |    )
|    |    |    like_count =  "3"

I am building a social network. So this is my feed object that has 3 like_counts . But the three of this like come from the same user "/api/v2/user/2/"

I try to add "unique=True" attribute at m2m field but django come up with the error because It doesn't grant the permission to add the "unique" attribute to m2m field at first. Can anyone help me?

Fluxmeter answered 7/2, 2013 at 14:36 Comment(5)
Try to clarify what you want, i can not understand it by reading your question.Enravish
I want to make m2m field to be unique for example a---x a---y a---z b---x b---x <----- something like this,I can't accept . because there are 2 b----xFluxmeter
Take a look at this: docs.djangoproject.com/en/dev/topics/db/examples/many_to_manyEnravish
@Enravish do you understand my question now.Fluxmeter
you din't see the link to the django documentation, did you? Why don't you create your own m2m table?Enravish
D
14

Try to use unique_together in your intermediate model.

class M2MModel(models.Model):
    field1 = models.ForeignKey(Model1)
    field2 = models.ForeignKey(Model2)

    class Meta:
        unique_together = ('field1', 'field2')
Decorticate answered 7/2, 2013 at 14:58 Comment(1)
I have the same problem and it also works for me, because I accept multiple intermediate objects with the same pair field1-field2, but what I want is to have only one instance in the many2many listShogun
M
4

unique_together doesn't work for M2M relationships. More info.

Mackenziemackerel answered 8/4, 2014 at 19:34 Comment(1)
That ticket is about a ManyToManyField being a part of a unique_together constraint, which is totally different to having a unique_together constraint on a through table. Not only is the latter perfectly possible, but the implicit through tables Django creates have exactly that constraint (which you can see by using \d+ (Postgres) or SHOW CREATE TABLE (MySQL) on one such table).Danica
P
1

I just finished a feature that quite similar with your requirement but my choice is to use another simple model as an intermediate model.

Here is my code.

class Vote(models.Model):
    class Meta:
        unique_together = ['content', 'by']

    content = models.ForeignKey(Content)
    by = models.ForeignKey(User)

In my case I don't see any benefit to implement ManyToManyField.

Update: I just found from here that Django is not going to make any built-in unique together for ManyToManyField. You have to implement your own validation to make it unique.

Potheen answered 7/2, 2013 at 18:21 Comment(0)
P
0

i use this approach:

class M2MModel(models.Model):
    field1 = models.ForeignKey(Model1)
    field2 = models.ForeignKey(Model2)

    class Meta:
        constraints = [
          models.UniqueConstraint(
            fields=["field1", "field2"],
            name="each_field2_is_unique_on_each_field1",
          )
        ]
Polyneuritis answered 19/5 at 13:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.