Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What side should a django 'many-to-many' relationship reside on

Lets say I have a recipe website with two basic models, 'User' and 'Recipe'

class User(models.Model):
    username= models.CharField()
    email = models.CharField()

class Recipe(models.Model):
    name = models.CharField()
    description = models.CharField()

I would like to add the functionality so that users can 'favorite' a recipe.

In this case, I need to use a many-to-many relationship. My question is, how do I decide which model to add the relationship to?

For example, each user could have a list of 'favorite' recipes:

class User(models.Model):
    favorites = models.ManyToManyField(Recipe)

Alternatively, each recipe could have a list of users who Favorited the recipe:

class Recipe(models.Model):
    user_favorites = models.ManyToManyField(User)

What is considered the best practice? Is either one better for query performance?

like image 836
corycorycory Avatar asked Jul 16 '17 23:07

corycorycory


People also ask

How does Django handle many-to-many relationship?

Behind the scenes, Django creates an intermediary join table to represent the many-to-many relationship. By default, this table name is generated using the name of the many-to-many field and the name of the table for the model that contains it.

How fetch data from many-to-many field in Django?

A ManyToManyField in Django is a field that allows multiple objects to be stored. This is useful and applicable for things such as shopping carts, where a user can buy multiple products. To add an item to a ManyToManyField, we can use the add() function.

How do you use many-to-many fields?

A ManyToMany field is used when a model needs to reference multiple instances of another model. Use cases include: A user needs to assign multiple categories to a blog post. A user wants to add multiple blog posts to a publication.

What is through in Django models?

The through attribute/field is the way you customize the intermediary table, the one that Django creates itself, that one is what the through field is changing.


1 Answers

It makes no difference from the database point of view, as pointed out in the comments.

But I have had two arguments where it did matter to me.

  • First (maybe less important), the built-in admin treats the two models differently by default. The model on which you define the relationship gets a widget for choosing the related objects. And a '+' for conveniently adding new objects of the related type.
  • secondly, you have to import one of the models in the file of the other one, if they are in different files. This matters if you want to write a reusable app that does not depend on anything outside. It mattered to me also because:
    I once (well, not just once actually :)) broke my app/database/etc such, that I decided to start a new project and copy the code there. In this case you have to comment out some settings.INSTALLED_APPS to test step for step that everything works. Here it is important not to have circular includes (to include a commented-out app raises an error). So I try to import the "most basic" into the others, and not the other way round.

This not a simple answer to your question, but two points which I consider. Maybe some more experienced users can correct me if it's wrong in some sense.

like image 74
Ilja Avatar answered Oct 16 '22 11:10

Ilja