2

Concise question:
What are the advantages and disadvantages of Modeling a many-to-many relationship in Django (1.5) on an external table without using the through parameter?

Details:
Say, I have a custom User model UserProfile and I want to define a m2m relation to the same model, for example to implement a following relationship. I can define an external table (model) like so:

class Relationship(models.Model):
    """Relationship model"""
    from_user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='from_users')
    to_user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='to_users')
    created = models.DateTimeField(auto_now_add=True)
    is_blocked = models.BooleanField(default=False)
    objects = RelationshipManager()

In this case should I add a m2m field to the UserProfile model as showed below ? If yes, why? I could handle all the relationships between users only using the Relationship model, isn't it?

class UserProfile(AbstractBaseUser, PermissionsMixin):
    user_following = models.ManyToManyField('self', through=Relationship, symmetrical=False, related_name='followed')
Leonardo
  • 4,046
  • 5
  • 44
  • 85

2 Answers2

7

First of all, it's important to make the difference between conceptual data model (CDM) and physical data model (PDM) in databases.

Conceptually, if you want to link a UserProfile to another UserProfile, it seems that you need 2 entities.

But technically (physically), since you're creating a Many To Many relationship, your system absolutely need to create a third database to store relations between your 2 UserProfiles, otherwise it can't!

Note that if it was a OneToOne or OneToMany relation, technically, 2 tables would be enough (that explains why this keyword exists only with ManyToMany relations).

Now, understand that Django tries to make your life easier: it may be possible that you don't care about the "physical" layer. For example, if you just want to know which user is connected to which other users, with no additional information.

-> In that case, you don't care about the third table that is just a technical constraint to make your whole stuff work! The through keyword does not need to be used. In that case, you see only 2 models in Django, but there are 3 tables in database even you don't see it in Django.

But in some case (often actually), you could use this third table to add important information on the relation between your users. For example, if you want to store the date when the relation has been created, this third table is the perfect place.

-> This "technical" table becomes a "functional" table: you want to use it directly in your project because it now contains data you need in addition of the relations between your users! That's the time to use the through keyword to define this third table in your Django Project, and add the attributes (like assocation_date) to this model/table. Now you have 3 models in Django, and still 3 tables in your databases (with the additional attributes you added).

Another classical example

A Client can order 1->N Products. A Product can be ordered by 0->N clients. This is clearly a ManyToMany Relashionship.

If I want to store information about the order (like the total price, the date, etc.), I can set a through="Order" when defining the M2M relation between Clients and Products. Then, I define the Order model in Django, and bingo!

David Dahan
  • 10,576
  • 11
  • 64
  • 137
  • yes, ok I knew this, the question is: what if I use the external table already defining the M2M (Relationship) without linking it with a m2m field and the "through" parameter? Advantages/disadvantages? – Leonardo Jun 11 '14 at 07:41
  • I suppose you shouldn't do that. If you define yourself a table made for the relashiohship, you should tell to Django to use it. If you don't, how Django is supposed to know he has to use it to make the relation? To answer your question, I see no advantage (maybe there is, but tell me ^^), only disadvantages: all the Django mechanisms made for M2M won't work automatically. – David Dahan Jun 11 '14 at 10:56
0

Advantages of use "through" described by Jacob Kaplan-Moss: http://www.quora.com/Django-web-framework/How-do-you-query-with-a-condition-on-a-ManyToMany-model-in-Django

Miketsukami
  • 524
  • 4
  • 6