Re: [mezzanine-users] Extending ThreadedComments

114 views
Skip to first unread message

Stephen McDonald

unread,
Aug 18, 2012, 4:09:33 AM8/18/12
to mezzani...@googlegroups.com
Hey Vickram,

I'd actually planned for a while to do this, just haven't ever gotten around to it - specifically, having ratings against individual comments.

So there's also option 4) add this to Mezzanine directly, it'd be a welcome contribution :-)

On Sat, Aug 18, 2012 at 5:25 PM, Vickramaditya Dhawal <vdh...@gmail.com> wrote:
Hi,

I want to come up with a blog post page where a user can rate along with the comments in the same form. Subsequently, when a user sees the blogpost he will see individual ratings with comments. I've thought of a few possible solutions to achieve the functionality.

Disclaimer: Not only is this my django app, this is my first web app so please bear if my queries/solutions sound asinine.

1) I can add EXTRA_MODEL_FIELDS for ratings to the ThreadedComment model to store the ratings. 
But how will they be reflected in the ThreadedCommentForm without touching existing mezzanine code. I could not figure that out.
If I subclass ThreadedCommentForm to say RatingCommentsForm how will i create this while handling "def comment" where it explicitly creates a ThreadedCommentForm. If i change the url handler to handle it someplace else i would have to duplicate code just to store my extra fields.

2) I can make the commentratings field a separate form and handle it in a page processor. But then i would want the user to press "Submit" only once and i would have to manipulate things in javascript to submit both the forms together. Which In my opinion is not very clean.

3) I create a new subclassed blog post page all together with a RatingCommentsForm and handle everything separately. would again lead to lots of code duplication. With this i would also miss out on subsequent upgrades and bug fixes in mezzanine to the blogpost pages and related classes etc.

What could be a possible better solution to achieve the functionality?

Example of what i would like to achieve later - review writing page of trip advisor - which seems like a lot to me at the moment :)

Thanks for reading it!
-Vickram



--
Stephen McDonald
http://jupo.org

Vickramaditya Dhawal

unread,
Aug 19, 2012, 9:48:42 AM8/19/12
to mezzani...@googlegroups.com, st...@jupo.org
Hi Stephen,

I'm going to try doing that. 

As i am changing the existing models how do i update my database to see if my changes are reflecting ? can you point me to any tutorials ?

Will keep you guys posted!

Stephen McDonald

unread,
Aug 19, 2012, 11:46:15 AM8/19/12
to Vickramaditya Dhawal, mezzani...@googlegroups.com
Mezzanine uses a library called South to manage changes to the database:

Vickramaditya Dhawal

unread,
Aug 19, 2012, 5:01:16 PM8/19/12
to mezzani...@googlegroups.com, Vickramaditya Dhawal, st...@jupo.org
I did the following preliminary implementation:

1) Added 5 IntegerFields to ThreadedComment and 5 ChoiceFields to ThreadedCommentForm
2) Updated the comment.html and mezzanine.css to reflect changes somewhat properly
3) Updated blog/models.py and blog/admin.py to take in the names of upto 5 the rating parameters from the blogpost pages.

I've the following doubts:

Since this will restrict it to maximum of 5 rating parameters while commenting, I would actually want to take in CSV of parameters from the admin page and store that to make it more flexible.
If i do that I think i will run into problem of generating the ThreadedCommentForm (unposted) cleanly - it might turn hacky.
Also how do i handle the POST request while handling the comment as i'm unaware of the parameters to look for (i'm guessing there would be a way to get the corresponding blog post from which i can get the data - but i don't know that right away)

Looking for guidance to take it forward in the best way possible!

P.S. also i was thinking of adding an option of "allowing replies to comments" as with rated comments 1) replies might be unwanted 2) replies to comments if enabled should maybe not show ratings again. what do you think ?

Vickramaditya Dhawal

unread,
Aug 21, 2012, 2:50:40 PM8/21/12
to mezzani...@googlegroups.com, st...@jupo.org
Hi,

I've completed the implementation of permitting ratings with comments.

Here is a brief overview:

1) Blog Post admin page was updated and a field was added to take input of the rating parameters as comma separated values. It also takes a value to permit replies to comments for the blog post. BlogPost model was suitably updated.
2) Field were added to ThreadedComments to store the parameters [and value] [as comma separated values] that were rated upon along with the comment.
3) A new method fields_for_comments was added to mezzanine_tags.py that will use a new template comment_form_fields.html to generate the html for the comment form.

I've committed the changes to my local branch "comments_with_ratings".

Can I please know the process to commit it further to master ?

Thanks,
Vickram

Stephen McDonald

unread,
Aug 21, 2012, 4:31:09 PM8/21/12
to mezzani...@googlegroups.com
Awesome Vickram!

The process goes:

- Create a fork of the project GitHub or Bitbucket, and send a pull request for your branch.
- Optionally post a link to the pull request back to the mailing list here to give people other than myself a chance to comment.
- Be prepared to make changes after feedback :-) 
- Once I'm happy with it, I'll merge it into the main repo.

I'd envisaged making use of the built-in ratings field, and it sounds like you might not have done that, but next step will be to get the code up in a pull request so we can move forward on it.

Vickramaditya Dhawal

unread,
Aug 22, 2012, 1:06:05 PM8/22/12
to mezzani...@googlegroups.com, st...@jupo.org
Hi All,

I've forked the repo and it is available at: https://github.com/vadhawal/mezzanine 
I've committed my changes there - please make time to take a look :)

I did not use the RatingField as i wanted to make the number of rating fields variable. I'm new to python and django - and i could not figure it out how do that exactly when i should also be able to update[add or delete fields] through the admin page.

So i did kind of a C Style implementation, where i store the parameters in a textfield as comma separated values. Again i was not sure how to maintain a list so i did that.

Though i'm not using a the Rating Field - I've taken care of the case where if mezzanine gets an invalid form [say: without comment] the rating fields should be restored for the user.

I would be more than happy to incorporate changes that your guys suggest.

Looking forward to the review :)

Thanks,
Vickram

Stephen McDonald

unread,
Aug 22, 2012, 4:56:29 PM8/22/12
to Vickramaditya Dhawal, mezzani...@googlegroups.com
Vickram I've left some comments against the code on the commit, but they're not very meaningful without the context of what the change tries to achieve as a whole, which I'm not able to grasp at a glance. 

Perhaps you could set up a pull request and describe in detail the changes so it's easier to get an overall picture of what you're trying to achieve, and we could start a discussion from there.

Overall, there seems to be some duplication of efforts - any changes for ratings should occur on the ratings field in mezzanine.generic so that they're available as a whole for anything that uses ratings. As I mentioned before, I'd envisaged simply adding a ratings field to the comment model - all the pieces are already there, so it should just be a matter of putting a ratings field onto the comment model, and ironing out any issues that crop up from that if there are any.

Stephen McDonald

unread,
Aug 22, 2012, 5:55:58 PM8/22/12
to Vickramaditya Dhawal, mezzani...@googlegroups.com
I've just added ratings to comments in the way I expected it to work. I thought it might need some massaging all over the place, but surprisingly it works perfectly. What it would need are some CSS tweaks - the comment styles end up butchering some of the rating styles. Here's the diff, you'll see only a few lines are needed:

diff -r b6c1e3cf3f6f mezzanine/generic/models.py
--- a/mezzanine/generic/models.py       Wed Aug 22 17:58:39 2012 +1000
+++ b/mezzanine/generic/models.py       Thu Aug 23 07:52:13 2012 +1000
@@ -5,6 +5,7 @@
 from django.template.defaultfilters import truncatewords_html
 from django.utils.translation import ugettext, ugettext_lazy as _
 
+from mezzanine.generic.fields import RatingField
 from mezzanine.generic.managers import CommentManager, KeywordManager
 from mezzanine.core.models import Slugged, Orderable
 from mezzanine.conf import settings
@@ -24,6 +25,7 @@
     by_author = models.BooleanField(_("By the blog author"), default=False)
     replied_to = models.ForeignKey("self", null=True, editable=False,
                                    related_name="comments")
+    rating = RatingField(verbose_name=_("Rating"))
 
     objects = CommentManager()
 
diff -r b6c1e3cf3f6f mezzanine/generic/templates/generic/includes/comment.html
--- a/mezzanine/generic/templates/generic/includes/comment.html Wed Aug 22 17:58:39 2012 +1000
+++ b/mezzanine/generic/templates/generic/includes/comment.html Thu Aug 23 07:52:13 2012 +1000
@@ -1,4 +1,4 @@
-{% load i18n mezzanine_tags comment_tags %}
+{% load i18n mezzanine_tags comment_tags rating_tags %}
 
 <ul class="unstyled">
     {% for comment in comments_for_thread %}
@@ -65,6 +65,7 @@
 
         {% endif %}
         {% endeditable %}
+        {% rating_for comment %}
         {% comment_thread comment %}
     </li>
     {% endfor %}

Stephen McDonald

unread,
Aug 22, 2012, 6:00:03 PM8/22/12
to Vickramaditya Dhawal, mezzani...@googlegroups.com
Guess we'd also need a COMMENTS_HAVE_RATINGS setting, which just hides the rating tag in the comment template if False.

Vickramaditya Dhawal

unread,
Aug 23, 2012, 1:32:39 PM8/23/12
to mezzani...@googlegroups.com, Vickramaditya Dhawal, st...@jupo.org
Hi Stephen,

I've replied to your comments. Before you read them here is a brief summary that will help understand my changes.

1) I did not use the RatingField in the ThreadedCommentForm for the following reasons:
   a) How do i set the Label for the RatingField dynamically for each blogpost.
   b) How do i make the number of RatingFields dynamic for each blogpost not restricted by an upper limit.

The way you have done it restricts the blog post admin to
1) have only rating field for a comment with fixed label: 'Rating'.
2) Even replies to the comments will get the rating field.

Do go through my comments on github which should probably make things a lot more clear.

On Thursday, 23 August 2012 03:

Stephen McDonald

unread,
Aug 23, 2012, 5:17:21 PM8/23/12
to mezzani...@googlegroups.com, Vickramaditya Dhawal
Thanks a lot Vickram for explaining that, it makes a lot more sense now.

I still think we should make whatever changes are required to the underlying rating model/field in mezzanine.generic, so whatever we do is available in a generic way rather than just for blog posts. That's a good use case you've got for being able to have different types of ratings with different labels. Need to think a bit more about how we can provide this feature in a generic way.

My initial thought is that this can be customized at the template level - we might be able to pass a custom template name to the rating template tag, and then the labels and values for the rating field could be customized there based on the given context (eg a blog post, or a product). 

It seems to me like types of ratings would be consistent across the same types of content - for example products would always have the same rating options, which might be different from the rating options for products, which would be the same for all products. Then it wouldn't make sense for a user to have to enter the same options for every blog post created. Having these applied at the template level would mean that we can define them in one spot per type of content. It would also mean we don't complicate the data model - ratings are still simply integers under the hood, and the customisation occurs visually at the template level where it belongs.

Perhaps we don't even need a custom template - we just need the ability to pass in a list of strings to the rating tag, eg:

{% rating "good,bad,ugly" %}

Anyone else have any thoughts on this?

Vickramaditya Dhawal

unread,
Aug 26, 2012, 2:28:42 AM8/26/12
to mezzani...@googlegroups.com, Vickramaditya Dhawal, st...@jupo.org
Hi Stephen,

Actually that is what i attempted. I'm storing "good,bad,ugly" as rating parameters in the blogpost which are laid out within the comment form. Whatever user rates is stored as ratedparameters "good,bad" and ratedvalues "3,1" within the comment - which are shown as a part of the comment.

If you would prefer to wrap ratedparamters and ratedvalues into a class[Custom Rating Field] i can do that. I guess further i can create a template to layout this Custom Rating Field.

How does that sound ?

- Vickram
Reply all
Reply to author
Forward
0 new messages