3

My site is actually a wagtail site, although I'm not sure if that makes a difference. It's a simple blog application with a blog page to view posts and a page to show each post.

I was following the instructions here to setup django-comments-xtd

The documentation says to implement the following code to get a comment count displayed on each post page.

{% get_comment_count for object as comment_count %}
<div class="text-center" style="padding-top:20px">
  <a href="{% url 'blog:post-list' %}">Back to the post list</a>
  &nbsp;&sdot;&nbsp;
  {{ comment_count }} comments have been posted.
</div>

I changed the actual link to be the following, as that is what it was in my site (built from another tutorial)

<p><a href="{{ page.get_parent.url }}">Return to blog</a></p>

I don't think changing the url like that would cause the problem, from what I can tell. I have made sure to load comments at the start of the file also.

The actual error is:

Error during template rendering

In template /home/jake/blog/blog/post_page.html, error at line 8
'str' object has no attribute '_meta'

Line 8 refers to this line:

{% get_comment_count for object as comment_count %}

Could someone explain this error in more detail?

Jake Rankin
  • 714
  • 6
  • 22
  • 1
    What is the `object`? I guess an empty string `''`. If you open Python and do `>>> ''._meta` you get an error `AttributeError: 'str' object has no attribute '_meta'`. Could it be that django-comments-xtd keeps the comment count per page? Eg: `{% get_comment_count for page as comment_count %}` – allcaps Jun 28 '18 at 22:11
  • changing object to page worked! This seems weird to me. Why would the documentation tell you to put in code that would return an error? Is it possible something to do with using wagtail? – Jake Rankin Jun 28 '18 at 22:37
  • 1
    Django templates allow variables to be undefined. Empty vars won't throw an error. This concept can be useful. When the context doesn't supply a variable, it will default to an empty string. In Django class based views and in most Django documentation `{{ object }}` or `obj` is used. Because `obj` can be any object (Pizzas, Cars, Questions). The default object in Wagtail is a Page object. The `page` variable name is well chosen. I guess the real problem is that you do not know the context: All the vars and their values that are used to fill the template. – allcaps Jun 28 '18 at 23:07
  • 1
    A Wagtail Page is both model and view. When a url is resolved Page.serve is called https://github.com/wagtail/wagtail/blob/master/wagtail/core/models.py#L715 That calls `get_context` it returns a dict. `{'page': self, 'self': self, 'request': request}`. See https://github.com/wagtail/wagtail/blob/master/wagtail/core/models.py#L702 . There is no `object` in the context! The django-comments-xtd developers just wrote Django code. You can comment on any object. You decided to use it in combination with Wagtail. So the object is a page. There is nothing wrong. – allcaps Jun 28 '18 at 23:28
  • 1
    Thank you for explaining! I am brand new to django and wagtail so learning both at the same time. If you make your comment an answer I would be happy to accept it, and I think it would be useful for any other beginners using django-comments-xtd with wagtail. – Jake Rankin Jun 28 '18 at 23:41

2 Answers2

5

Django django-comments-xtd stores comments on objects. In your case the object is a Wagtail page. Change:

{% get_comment_count for object as comment_count %}

To:

{% get_comment_count for page as comment_count %}

The object variable is an empty string ''. This is an demo of what happens somewhere in the django-comments-xtd code:

>>> ''._meta
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute '_meta'

A Wagtail Page is both model and view. When a url is resolved Page.serve is called. That calls get_context and returns a dict.

{'page': self, 'self': self, 'request': request}

The context - all variables and their values - is used to fill the template. There is no object in the context!

Django templates allow variables to be undefined. Empty vars won't throw an error. This concept can be useful. When the context doesn't supply a variable, it will default to an empty string.

When documentation shows example code and mentions an {{ object }} or obj, they mean 'an object'. Any object (Pizzas, Cars, Questions). Your object. The default object in Wagtail is a Page object. You should use the page variable.

allcaps
  • 10,945
  • 1
  • 33
  • 54
3

For reference purpose like mine, just use

{% get_comment_count for NameOfModel as comment_count %}

where NameOfModel is exactly the way you define the model in the views.py (I am using django).