I am following this example on how to set threaded comments with django_comments and django-mptt.
I have followed most of it and the posted comments are working in admin but I am getting this error 'Comment' object has no attribute '_mptt_meta'. I have tried using a different instances to reference with and tried different objects but I am not sure what the problem might be?
I have a comments app where I am running most of the code from in this example:
comments/models.py:
from django_comments.models import Comment
from mptt.models import MPTTModel, TreeForeignKey
class MPTTComment(MPTTModel, Comment):
""" Threaded comments - Add support for the parent comment store and MPTT traversal"""
# a link to comment that is being replied, if one exists
parent = TreeForeignKey('self', null=True, blank=True, related_name='children')
class MPTTMeta:
# comments on one level will be ordered by date of creation
order_insertion_by=['submit_date']
class Meta:
ordering=['tree_id', 'lft']
comments/forms.py:
from django import forms
from django.contrib.admin import widgets
from django_comments.forms import CommentForm
from .models import MPTTComment
class MPTTCommentForm(CommentForm):
parent = forms.ModelChoiceField(queryset=MPTTComment.objects.all(), required=False, widget=forms.HiddenInput)
def get_comment_model(self):
# Use our custom comment model instead of the built-in one.
return MPTTComment
def get_comment_create_data(self):
# Use the data of the superclass, and add in the parent field field
data = super(MPTTCommentForm, self).get_comment_create_data()
data['parent'] = self.cleaned_data['parent']
return data
comments/templates/comments/_comments.html
{% load comments %}
{% load mptt_tags %}
{% get_comment_list for object as comments %}
{% if comments %}
{% recursetree comments %}
<div {% if request.REQUEST.c|add:"0" == node.id %}id="newly_posted_comment"{% endif %}>
<a name="c{{ node.id }}"></a>
{{ node.comment }}
{{ node.user }}
{{ node.submit_date|timesince }} ago
<a href="{{ object.get_absolute_url }}#c{{ node.id }}">#</a>
{% render_comment_form for object %}
{# recursion! children of a given comment #}
{% if not node.is_leaf_node %}
{{ children }}
{% endif %}
</div>
{% endrecursetree %}
{% endif %}
{% render_comment_form for object %}
comments/templates/comments/form.html
{% load comments i18n %}
<div class="comment-form" id="comment-form-{{ node.id }}"
{% if node.id %}
style="display:none;"
{% endif %}
>
<form action="{% comment_form_target %}" method="post" id="comment-form-{{ node.id }}f">{% csrf_token %}
{{ form.object_pk }}
{{ form.content_type }}
{{ form.timestamp }}
{{ form.security_hash }}
{% if node.id %}
<input type="hidden" name="parent" id="parent_id" value="{{ node.id }}"
/>
{% endif %}
{{ form.comment }}
<input type="submit">
</form>
</div>
I have this tag setup in my posts/index.html template
{% extends 'posts/base.html' %}
{% block title %} Wiwik | What I Wish I Knew {% endblock %}
{% load django_markdown %}
{% block body %}
<div class="container-fluid">
<div class="main" id="show">
{% for post in all_posts %}
<div class="content">
<h1 class="fof"><a href="{% url 'posts:detail' post.id post.post_title|slugify %}"> {{ post.post_title}}</a> </h1>
<p><strong> Posted by </strong> <span class="idex"><a href="{% url 'posts:view_user' username=post.user.username user_id=post.user_id %}"><strong>{{ post.user.username }}</strong></a> <img src="{{ post.user.profile.avatar.url}}" class="post-thumb"/></span>
<span class="biography cursive"> {{ post.user.profile.bio }}</span> <br/><span class="topic"> {{post.category}}</span>
<br/>
<span class="tiny"> on {{post.post_date}} <br/>With {{post.upvote}} Recommendations</span> </p>
<a href="{% url 'posts:detail' post.id post.post_title|slugify %}">
{% if post.image %}
<img src="{{ post.image.url }}" class="img-responsive" id="mobi"/>
{% else %}
{% endif %}
</a>
<br/>
<div class="test">{{ post.post_body|markdown }} </div>
<br/>
<a href="/posts/{{post.id}}/{{post.post_title}}/upvote/" method="post"><button type="button" class="btn btn-info"> Vote Up| {{ post.upvote }}</button></a> |
<a href="/posts/{{post.id}}/{{post.post_title}}/down_vote/" method="post">Vote Down</a> |
<button class="blab" type="button" style="background:none;border:none;color: #337AB7">Comments {{ post.comments.count }}</button>
<br/>
<br/>
<div class="collapse" id="comm">
{% for comment in comment.comments.all reversed %}
{% if user.is_authenticated or comment.approved_comment %}
<h4 class="author"><strong>{{ comment.author_comments.username }}</strong><span class="tiny"><strong>{{ comment.created_at }}</strong></span></h4>
<div class="date">
{% if request.user.is_superuser %}
{% if not comment.approved_comment %}
<a class="btn btn-default" href="{% url 'posts:comment_remove' pk=comment.pk %}"><span class="glyphicon glyphicon-remove"></span></a>
<a class="btn btn-default" href="{% url 'posts:comment_approve' pk=comment.pk %}"><span class="glyphicon glyphicon-ok"></span></a>
{% endif %}
{% else %}
{% endif %}
</div>
<p><span class="text" id="new" >{{ comment.text|linebreaks }}</span></p>
<br/>
{% endif %}
{% endfor %}
</div>
<br/>
<br/>
<br/>
<br/>
{% if user.is_authenticated %}
<h3>Comment</h3>
<div id="commentary"> {% with post as object %}{% include "comments/_comments.html" %}{% endwith %}</div>
{% else %}
<a class="btn btn-primary" href="{% url 'posts:login_user' %}">Add comment</a>
<br/>
<p>Please login to post a comment.</p>
{% endif %}
</div>
{% endfor %}
<br/>
<br/>
<div class="hline"></div>
<p style="text-align: center;">WIWIK © 2016</p>
</div>
</div>
<div class="righto">
<span class="st_twitter_large" displayText="Tweet"></span>
<span class="st_facebook_large" displayText="Facebook">
</span>
<span class="st_linkedin_large" displayText="LinkedIn">
</span>
<span class="st_googleplus_large" displayText="Google+">
</span>
<span class="st_email_large" displayText="Email"></span>
<span class="st_sharethis_large" displayText="ShareThis">
</span>
</div>
<script>
$(document).ready(function(){
$(".blab").click(function(){
$(this).siblings('.collapse').collapse('show');
$(this).siblings('.collapse').collapse('hide');
});
});
</script>
{% endblock %}
Extended from posts/base.html below:
<!DOCTYPE html>
<html lang="en">
<head>
<title>{% block title %}Wiwik{% endblock %}</title>
{% load staticfiles %}
{% load comments %}
<meta name="viewport" content ="width=device-width,initial-scale=1,user-scalable=yes" url=#new />
<link rel="shortcut icon" type="image/png" href="{% static 'favicon.ico' %}"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<link href='https://fonts.googleapis.com/css?family=Satisfy|Lato|Belgrano|Amethysta|IM+Fell+Great+Primer+SC|Open+Sans|Lora' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="{% static 'posts/style.css' %}"/>
<script type="text/javascript">var switchTo5x=true;</script>
<script type="text/javascript" src="https://ws.sharethis.com/button/buttons.js"></script>
<script type="text/javascript" src="https://ss.sharethis.com/loader.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="{% static 'posts/js/main.js' %}"></script>
<script language="javascript" type="text/javascript" src="jquery-1.2.6.js"></script>
<script language="javascript" type="text/javascript" src="{% static 'posts/js/truncator.js' %}"></script>
<script language="javascript" type="text/javascript">
$(function() {
$('.test').truncate({max_length: 100});
});
</script>
{% block extrahead %}
{{ block.super }}
{% include "comments/_ajax_comments.html" %}
{% endblock %}
The content posts are in the posts app
posts/models.py
class Post(models.Model):
user = models.ForeignKey(User, default=1)
post_title = models.CharField(max_length=250)
post_body = models.TextField(max_length=20000)
category = models.ForeignKey(Categories, related_name='hats')
image = models.ImageField(default='static/wiwik.jpg', blank=True)
email = models.EmailField(default='')
post_date = models.DateTimeField(default=now)
upvote = models.IntegerField(default=0)
down_vote = models.IntegerField(default=0)
def get_absolute_url(self):
return reverse('posts:detail', args=(self,), kwargs={"post_id": self.post_id})
def __str__(self):
return self.post_title + ' - ' + self.post_body
def __unicode__(self):
return self.post_title
Here is my link to the stacktrace
Any help would be appreciated!