1

I am using Django's comments framework to manage comments in my website. I have custom comment model and form that extends Django's, as following:

Model:

class FTComment(Comment):
    upvotes = models.PositiveSmallIntegerField()
    downvotes = models.PositiveSmallIntegerField()

Form:

class FTCommentForm(CommentForm):
    captcha = ReCaptchaField(required=True)

    def get_comment_create_data(self):
        # Use the data of the superclass, and remove extra fields
        return dict(
            content_type = ContentType.objects.get_for_model(self.target_object),
            object_pk    = force_unicode(self.target_object._get_pk_val()),
            comment      = self.cleaned_data["comment"],
            submit_date  = datetime.datetime.now(),
            site_id      = settings.SITE_ID,
            is_public    = True,
            is_removed   = False,
        )

FTCommentForm.base_fields.pop('url')
FTCommentForm.base_fields.pop('email')
FTCommentForm.base_fields.pop('name')

The comment form works fine, and browsing the database data in the SQLite Database Browser I can find it there:

SQLite Database Browser

So, why can't I get the list of comments? Is there something I'm missing? Here's the template:

{% load i18n %}
{% load comments %}

<link rel="stylesheet" type="text/css" href="/static/css/comment.css" />

<p>
    <strong>{% trans "Comments" %}</strong>
</p>

<div class="comment_box">
    {% if user.is_authenticated %}
        {% render_comment_form for obj %}
    {% else %}
        <p>Please <a href="/login">log in</a> to leave a comment.</p>
    {% endif %}

    {% get_comment_count for obj as count %}
    <p>Count: {{ count }}</p>
    {% get_comment_list for obj as comments %}
    {% for comment in comments %}
        {{ comment.comment }}
    {% endfor %}
</div>

count returns 0, although there are 2 comments for this object in the database, and the for loop renders nothing.

A help with this would be hugely appreciated.

Edit: View added

Here's the view of this case in particular:

def show_detail(request, img_id):
    img = get_object_or_404(Image, pk=img_id)
    img.views += 1
    img.save()

    try:
        referer = Referer()
        referer.referer_url = request.META['HTTP_REFERER']
        referer.object = img
        referer.save()
    except KeyError:
        pass

    return render(request, "img/show_detail.html", {'img': img})

Edit 2:

I'm sorry, I should have explained. The templates which renders the comments is in a different file so it can be used by other pages/templates. The reference to the object is passed like this: {% include "comment/main.html" with obj=img %} to this template.

Bruno Finger
  • 2,105
  • 3
  • 27
  • 47

3 Answers3

0

It seems that the obj that you are referring to in {% get_comment_list for obj as comments %} is not in your template context.

If your comments are on the Image model, then you should change all your references to obj in your template code, to img, because that is the key you are giving it in your template context (from return render(request, "img/show_detail.html", {'img': img})).

Pierre Drescher
  • 776
  • 5
  • 10
  • I'm sorry, I should have explained. The templates which renders the comments is in a different file so it can be used by other pages/templates. The reference to the object is passed like this: `{% include "comment/main.html" with obj=img %}` to this template. – Bruno Finger Mar 07 '14 at 22:43
0

You need to include the comments template tag {% load_comments %} in you template. Then you can access the comments context.

Drewness
  • 5,004
  • 4
  • 32
  • 50
0

The problem is that my custom form wasn't referencing my custom model, but Django's stock model, AND, the tag get_comment_list as well as get_comment_count was referencing my custom model, as defined in my comments app __init__.py:

def get_model():
    return FTComment

def get_form():
    return FTCommentForm

So, the form was saving the comment as a Django comment object, but the template tag was trying to fetch my custom comment object, which was empty in the database.

The solution was to define a get_comment_model method in the custom form as explained in the Django's documentation.

The final form of the form, with the added fields upvotes and downvotes from the custom model is like this:

# -*- coding: utf-8 -*-

from captcha.fields import ReCaptchaField
import datetime
from django.conf import settings
from django.contrib.comments.forms import CommentForm
from django.contrib.contenttypes.models import ContentType
from django.utils.encoding import force_unicode

from fingertools.comment.models import FTComment


class FTCommentForm(CommentForm):
    captcha = ReCaptchaField(required=True)
    
    def get_comment_model(self):
        return FTComment
    
    def get_comment_create_data(self):
        # Use the data of the superclass, and remove extra fields
        return dict(
            content_type = ContentType.objects.get_for_model(self.target_object),
            object_pk    = force_unicode(self.target_object._get_pk_val()),
            comment      = self.cleaned_data["comment"],
            submit_date  = datetime.datetime.now(),
            site_id      = settings.SITE_ID,
            is_public    = True,
            is_removed   = False,
            upvotes      = 0,
            downvotes    = 0,
        )
    
FTCommentForm.base_fields.pop('url')
FTCommentForm.base_fields.pop('email')
FTCommentForm.base_fields.pop('name')
Nimantha
  • 6,405
  • 6
  • 28
  • 69
Bruno Finger
  • 2,105
  • 3
  • 27
  • 47