Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing objects to Detail View with filter (Django)

I am trying to pass query of comments (Comment model) to a DetailView of Post model using filter to get in DetailView only comments, related to particlural post.

Post model:

class Post(models.Model):
    title = models.CharField(max_length=300)
    content = models.TextField()
    date_posted = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

Comment model:

class Comment(models.Model):
    content = models.CharField(max_length=500, help_text='Не более 500 знаков')
    date_posted = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(on_delete=models.CASCADE)
    post_id = models.ForeignKey(on_delete=models.CASCADE)

Detail veiw:

class PostDetailView(DetailView):
    context_object_name = 'post'
    model = Post

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['comments'] = Comment.objects.filter(post_id = self.model.id)
        return context

And it returns TypeError:

int() argument must be a string, a bytes-like object or a number, not 'DeferredAttribute'

Could you please help with recommendation regarding how correctly use a filter to get in DetailView only comments, related to this Post? Thanks!

like image 259
Lex Izmaylov Avatar asked Sep 05 '25 02:09

Lex Izmaylov


1 Answers

Well here your self.model will return Post (a reference to the model class), not the post object.

You can access the object with self.object, as is specified in the documentation:

While this view is executing, self.object will contain the object that the view is operating upon.

class PostDetailView(DetailView):
    context_object_name = 'post'
    model = Post

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['comments'] = Comment.objects.filter(post_id=self.object)
        return context

You can also make use of the reversed relationship, like:

class PostDetailView(DetailView):
    context_object_name = 'post'
    model = Post

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['comments'] = self.object.comment_set.all()
        return context

Note: note that a ForeignKey field typically does not end with an _id suffix, Django will automatically add an extra field named fieldname_id, so here you have two fields, post_id, and post_id_id, which is quite strange.

like image 129
Willem Van Onsem Avatar answered Sep 07 '25 22:09

Willem Van Onsem