Django's "free comments" with wagtail?

1,031 views
Skip to first unread message

Kevin Cave

unread,
Jul 11, 2014, 12:43:56 AM7/11/14
to wag...@googlegroups.com
Greetings,

I've just tried enabling Django's Free Comments on your demo site, but alas, due to wagtail's own
site management logic, this won't work...

CommandError: One or more models did not validate:
comments.comment: 'site' has a relation with model <class 'django.contrib.sites.models.Site'>, which has either not been installed or is abstract.

I'd really like to have comments, especially for a blog section on a site I create. I'd be grateful for any pointers in achieving this.

Wagtail so far is looking like a fantastic CMS, by the way!

Regards,

Kevin.

Kevin Cave

unread,
Jul 14, 2014, 12:47:40 PM7/14/14
to wag...@googlegroups.com
Okay so, I've somewhat managed to integrate django_comments_xtd with the wagtaildemo site, here's how it's looking so far:



How I did this...

1) Install django_comments_xtd in my virtualenv.

2) Adjusted wagtaildemo's base.py as follows...

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    #'django.contrib.sites',  # Wagtail uses its own site management logic
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'south',
    'compressor',
    'taggit',
    'modelcluster',
    'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    'django.contrib.admindocs',
    'wagtail.wagtailcore',
    'wagtail.wagtailadmin',
    'wagtail.wagtaildocs',
    'wagtail.wagtailsnippets',
    'wagtail.wagtailusers',
    'wagtail.wagtailimages',
    'wagtail.wagtailembeds',
    'wagtail.wagtailsearch',
    'wagtail.wagtailredirects',
    'wagtail.wagtailforms',
    'django.contrib.sites',
    'django.contrib.comments',
    'django_comments_xtd',
    'demo',
)

COMMENTS_APP = "django_comments_xtd"
COMMENTS_XTD_MAX_THREAD_LEVEL = 8

As you can see, I've had to add django.contrib.sites (which was commented out in the wagtaildemo site), as django_comments_xtd needs django.contrib.comments (which needs .sites) - so far this doesn't appear to have affected wagtail at all.

3) Add the following in wagtaildemo/wagtaildemo/urls.py ...

    url(r'^comments/', include('django_comments_xtd.urls')),

4) To get the comments displaying, I incorporated some elements from the comments_xtd examples...

4a) In wagtaildemo/templates/demo/includes/blog_list_item.html...

{% load pageurl image_tags %}
{% load comments %}
{# Individual blog item in a list - used on blog index and home page #}
<a class="list-group-item" href="{% pageurl blog %}">
    <h4 class="list-group-item-heading">{{ blog.title }}</h4>
    <p><strong>{{ blog.date|date:"j F Y" }}</strong></p>
    {% get_comment_count for blog as comment_count %}
    <p>{{ comment_count }} comments have been posted.</p>
    {% if blog.search_description or blog.feed_image %}
        <p class="list-group-item-text">
            {% if blog.feed_image %}
                {% image blog.feed_image width-200 %}
            {% endif %}
            {% if blog.search_description %}
                {{ blog.search_description }}
            {% endif %}
        </p>
    {% endif %}
</a>

This enables the blog list in the wagtaildemo to show a summary of comments (if any) for blog post items...

4b) In wagtaildemo/demo/templates/demo/blog_page.html ...

{% extends "demo/base.html" %}
{% load pageurl %}
{% load comments %}

{% if self.date %}
    {% block heading %}
<div class="page-header" xmlns="http://www.w3.org/1999/html">
            <h2>{{ self.title }} {{ self.date|date:"j F Y" }}</h2>
</div>
    {% endblock %}
{% endif %}

{% block content %}
    {% include "demo/includes/carousel.html" with carousel_items=self.carousel_items.all only %}

    {% include "demo/includes/body.html" with body=self.body only %}

    {% get_comment_list for self as comment_list %}
    {% for comment in comment_list %}
        <div style="margin-left:{{ comment.level }}00px; border-left:5px solid #ddd">
            <dt id="c{{ comment.id }}" style="background-color: #ddd">
                <p>Posted by: {% if comment.url %}<a href="{{ comment.url }}" target="_new">{% endif %}{{ comment.name }}{% if comment.url %}</a>{% endif %} on {{ comment.submit_date }}{% if comment.allow_thread %}&nbsp;-&nbsp;<a href="{{ comment.get_reply_url }}">Reply</a>{% endif %}</p>
            </dt>
            <p>{{ comment.comment }}</p>
        </div>

    {% endfor %}

    {% render_comment_form for self %}

    {% with self.tags.all as tags %}
        {% if tags %}
            <div class="page-header"><h3>Tags</h3></div>
            {% for tag in tags %}
                <a href="{% pageurl self.blog_index %}?tag={{ tag }}"><button class="btn btn-primary" type="button">{{ tag }}</button></a>
            {% endfor %}
        {% endif %}
    {% endwith %}

    {% include "demo/includes/related_links.html" with related_links=self.related_links.all only %}
{% endblock %}


This displays the threaded comment list plus the comment post form at the bottom, as shown in the first screenshot in this post.

After that I performed a

manage.py syndb

and
  
manage.py migrate

then ran the demo site and the comments worked as seen.

Now the only thing I need to figure out is this error, after replying to a comment...

I know this is due to django_comments_xtd expecting there to be a get_absolute_url() method, in order for comments_xtd to go back to the page url of that blog entry. I just need to figure out how to implement that ;)

Just thought I'd show my progress so far, as it might give others - and/or the wagtail author(s) a pointer towards implementing a commenting system.

I'm new to django and only a year-and-a-bit into python development, but I'm slowly but surely making progress in django & wagtail. I soldier on...  ;)

Regards

Kevin Cave




Kevin Cave

unread,
Jul 23, 2014, 7:34:24 AM7/23/14
to wag...@googlegroups.com
Okay I'm needing help! :)

I'm still stuck at trying to solve the error in my previous post regarding get_absolute_url()

Can anyone give me a pointer on how I'd need to alter the wagtaildemo site in order to have the site returning to that web page after a comment has been submitted?

Regards

Kevin Cave

unread,
Jul 23, 2014, 9:30:09 AM7/23/14
to wag...@googlegroups.com
Progress!

I implemented a get_absolute_url() function in models.py for the BlogPage class...

class BlogPage(Page):
    body
= RichTextField()
    tags
= ClusterTaggableManager(through=BlogPageTag, blank=True)
    date
= models.DateField("Post date")
    feed_image
= models.ForeignKey(
       
'wagtailimages.Image',
       
null=True,
        blank
=True,
        on_delete
=models.SET_NULL,
        related_name
='+'
   
)


    indexed_fields
= ('body', )


   
@property
   
def blog_index(self):
       
# Find closest ancestor which is a blog index
       
return self.get_ancestors().type(BlogIndexPage).last()


   
def get_absolute_url(self):
       
#print(self.full_url)
       
return 'http://localhost:8000'+self.url

Now, it's probably not fantastic to have 'http://localhost:8000' in there, but returning self.full_url at the moment results in an error because the result will be "http://localhost/blog-index/hello-world/" rather than "http://localhost:8000/blog-index/hello-world". 

It just occurred to me whilst typing this that I could probably check to see if DEBUG is defined and change the returned value to suit, though. I'll give that a test....

    def get_absolute_url(self):
       
#print(self.full_url)
       
if DEBUG:
           
return 'http://localhost:8000' + self.url
       
else:
           
return self.full_url


Yep that seems to work for now.


I now get the browser to return to the originating page after submitting a comment. And I now have a rudimentary comment system running on wagtaildemo. I have warm fuzzy happiness coursing through my veins at this modest success ;)

Matthew Westcott

unread,
Jul 23, 2014, 9:55:06 AM7/23/14
to wag...@googlegroups.com
I think defining get_absolute_url to just return self.url should be sufficient - I'm pretty sure Django doesn't require the domain to be included in the return value.

We should probably define that as standard on all pages within Wagtail, really...

Incidentally, you can fix the http://localhost/ versus http://localhost:8000/ thing by going to 'Sites' within /django-admin/ and setting the port number to 8000. (We try to avoid using full URLs within Wagtail wherever possible, so most of the time there's no need to fiddle with site settings - it's only really if you're running multiple domains on one Wagtail installation that it becomes an issue.)

Cheers,
- Matt

Kevin Cave

unread,
Jul 23, 2014, 10:54:41 AM7/23/14
to wag...@googlegroups.com
Hi Matt,

As you probably gathered, whilst I can write full GUI applications in Python and Qt, I'm no web developer and a Django noob trying his best to get over a VERY steep Django learning curve ;)

I am - very slowly - starting to pick up how this Django stuff works - honest :P

I think defining get_absolute_url to just return self.url should be sufficient - I'm pretty sure Django doesn't require the domain to be included in the return value.

I tried that - after I submit a comment, if I return self.url, I get redirected to example.comhttp://example.com/blog-index/hello-world/#c25 ) - and see below why that is as it's related...
 
We should probably define that as standard on all pages within Wagtail, really...


Yes I think you should just have get_absolute_url implemented in your Page model as standard - it could be overridden, probably, if the standard behaviour doesn't suit whomever.
 
Incidentally, you can fix the http://localhost/ versus http://localhost:8000/ thing by going to 'Sites' within /django-admin/ and setting the port number to 8000. (We try to avoid using full URLs within Wagtail wherever possible, so most of the time there's no need to fiddle with site settings - it's only really if you're running multiple domains on one Wagtail installation that it becomes an issue.)


*slaps forehead* Of course!  I now remember coming across the Sites bit in the Django admin interface. It never occurred to me that that was causing the "lack of :8000" issue!

Lol, so, I go to django-admin and view the Sites, and lo and behold what do I see but "example.com" rather than what I was expecting, which was "localhost" - I think you might have "example.com" in by default in the wagtaildemo - I certainly didn't put that there, and that totally threw me off for a while, it seems!

Changed the Site to "localhost:8000" and indeed all I need is;

    def get_absolute_url(self):
       
return self.url


Regards,

Kevin.

Kevin Cave

unread,
Jul 23, 2014, 7:03:05 PM7/23/14
to wag...@googlegroups.com
And to round off this adventure, I'd just like to add this final piece of info...

As has been rightly pointed out to me on Github, the "example.com" issue I encountered was basically caused by this;


Thought I'd mention it here, and also thank everyone who gave me the valuable information.

Regards

Kevin.
Reply all
Reply to author
Forward
0 new messages