0

I have an app within my project called posts, where inside their in the models.py, I have two models: Post and Like.

I want to add a many-to-many-field on the post that references the Like model.

I have executed makemigrations and migrate, however I am getting this error:

NameError: name 'Like' is not defined

models.py:

class Post(models.Model):
    file = models.ImageField(upload_to='images/')
    summary = models.TextField(max_length=600)
    pub_date = models.DateTimeField(auto_now=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    likes = models.ManyToManyField(Like)

    def __str__(self):
        return self.user.username

    def summary_pretty(self):
        return self.summary[:50]

    def pub_date_pretty(self):
        return self.pub_date.strftime('%b %e %Y')

class Like(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    status = models.BooleanField(default=False)
Navid Zarepak
  • 4,148
  • 1
  • 12
  • 26
djangoninja
  • 143
  • 1
  • 1
  • 7
  • Use a string: `likes = models.ManyToManyField("Like")` – Daniel Roseman Aug 14 '19 at 17:52
  • However, your modelling is wrong. The many-to-many isn't to Like; Like is the *through* model in the m2m between Post and User. It should be: `like_users = models.ManyToManyField('User', through='Like', related_name='liked_posts')`. – Daniel Roseman Aug 14 '19 at 18:05
  • I'm not sure I understand why you're doing this. The `Like` model has the `post` field which is a `Post` model. So if you have a `Post` object and want to get the associated `Like`s all you need to do is `object.list_set.all()` – HenryM Aug 14 '19 at 18:15
  • Hey Daniel when I do this I get: posts.Like: (fields.E336) The model is used as an intermediate model by 'posts.Post.likes', but it does not have a foreign key to 'Post' or 'posts.User'. – djangoninja Aug 14 '19 at 18:43

2 Answers2

0

it says

NameError: name 'Like' is not defined

because you must move Like model above Post model it hasn't been defined yet in your code in that line (python code is interpreted)

and it's not a good thing to design database models like that based on:

Why should I avoid loops when designing relationships for a database?

so delete the Post foreign key in Like model and you can retrieve a like's post with reverse lookup you can find more about it in django official docs:

Lookups that span relationships

and also

Many-to-many relationships

Mohammad Moallemi
  • 628
  • 1
  • 5
  • 13
0

You're referencing the class Like before initiating it in your Python file. Hence "Like" is not defined.

likes = models.ManyToManyField(Like)

You need to delete "likes" from your Post class. That will fix the error.

As for your code, I think you're misunderstanding why we use Intermediary Tables. You don't need to reference Like in your Post class. You've already established that relationship in the Like Class:

post = models.ForeignKey(Post, on_delete=models.CASCADE)

Retrieving the users who have liked a post is as simple as writing a filter on the Likes table.

#views.py
from models import Post, Like
post_id = 1 
likes = Like.objects.filter(post=post_id)
Jon Hrovat
  • 585
  • 3
  • 19