0

I started to learn Django and I decided to create a blog to check my skills and train myself with an actual project. In my models.py there is two models :

class Article (models.Model):
    title = models.CharField(max_length = 100)
    author = models.CharField(max_length = 100)
    date = models.DateField(auto_now=True)
    content = models.TextField()
    is_draft = models.BooleanField(default = True)

    def __str__(self):
        return self.title

class Comment(models.Model):
    comment_author = models.CharField(max_length = 100)
    comment = models.TextField()
    article = models.ForeignKey(Article,on_delete=models.CASCADE)

    def __str__(self):
        return self.comment_author

I want to display all the title and content of every articles and the numbers of comment , to do so I used a ListView. views.py :

class ArticleListView (ListView):
    context_object_name = 'articles'
    model = models.Article
    # print(models.Article.objects.get(pk=1).models.Comment_set.all())

    def get_context_data(self,**kwargs):
         context = super().get_context_data(**kwargs)
         context['title'] = models.Comment.objects.get(pk=1) # I don't know how to change this value 
         context['id'] = self.model.id 
         return context 

article_list.html :

{% for article in articles %}
    <h2>{{ article.title }}</h2>
    <p>{{ article.content }}</p>
    <h5>Id of article is {{ id }}</h5>
    <h6>{{ title }}</h6>
    {% endfor %}

I wanted to use count() on Comment so I get the numbers of comments by post. To get the list of article's comments I thought that I need the pk for each article so I can find the number of comment but it doesn't work. Do you have any ideas how I can figure this out ?

Also when I try to get the id in get_context_data() [in views.py] I got something like <django.db.models.query_utils.DeferredAttribute object at 0x7fead2213fd0> instead of a numbers do you know a way to get an actual numbers ?

kowsik186
  • 27
  • 4

1 Answers1

1

You can get a list of all articles and their comments in the template without having to overwrite get_context_data(). You can pass a related_name to the ForeignKey relationship to specify it but if you don't Django creates one automatically for you. The automatically created default for you will be: comment_set. See here for the documentation.

article_list.html

{% for article in articles %}
    <h2>{{ article.title }}</h2>
    <p>{{ article.content }}</p>

    <p>Total comments: {{ article.comment_set.count }}</p>
    {% for comment in article.comment_set.all %}
        <p>{{ comment.author }}</p>
        <p>{{ comment.comment }}</p>
    {% endfor %} 
{% endfor %}

I would recommend setting a related_name though and then your model and template code will be:

article = models.ForeignKey(Article,on_delete=models.CASCADE, related_name="comments")

{% for comment in article.comments %}
{% endfor %}

Here is a related Stack Overflow post as well if you want to read more about it.

Dean Elliott
  • 1,245
  • 1
  • 8
  • 12