Home > database >  related_name in many to many field
related_name in many to many field

Time:11-21

Below is my code.

class Thing(models.Model) :
    title = models.CharField(
            max_length=200,
            validators=[MinLengthValidator(2, "Title must be greater than 2 characters")]
    )
    text = models.TextField()
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
            related_name='fav_thing_owner')
    favorites = models.ManyToManyField(settings.AUTH_USER_MODEL,
        through='Fav', related_name='favorite_things')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    # Shows up in the admin list
    def __str__(self):
        return self.title

class Fav(models.Model) :

    thing = models.ForeignKey(Thing, on_delete=models.CASCADE)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
        related_name='favs_users')

    # https://docs.djangoproject.com/en/3.0/ref/models/options/#unique-together
    class Meta:
        unique_together = ('thing', 'user')

    def __str__(self) :
        return '%s likes %s'%(self.user.username, self.thing.title[:10])

But I got confused related_name in ManytoMayFied.

for example, in my code I can get user's Thing(my model name) using user.fav_thing_owner.

But in ManyToManyField, I have two related_name(favorite_things, favs_users).

user.favorite_things and user.favs_users get same object..?

CodePudding user response:

user.favorite_things and user.favs_users get same object..?

No, user.favorite_thing.all() will get you a queryset of Thing objects, whereas user.favs_user.all() will get you a queryset of related Fav objects.

The Fav objects that you get with user.favs_user.all() will thus point to the Thing objects that you get by user.favorite_thing.all(). If your Fav objects contains more data, for example the timestamp when you made that Thing your favorite, it thus can be sometimes useful to fetch the Fav objects instead and then thus enumerate over the .things that these Fav objects refer to.

The related_name=…s look a bit odd. Typically it is the name to fetch the relation in reverse. Perhaps it is better to rename the favs_user to favorites or something.

  • Related