Django Comment app. It can be associated with any given model.
Project description
django-comments-dab
Content:
Introduction
dab stands for Django-Ajax-Bootstrap
django-comments-dab is a commenting application for Django-powered websites.
It allows you to integrate commenting functionality with any model you have e.g. blogs, pictures, video etc…
List of actions the authenticated user can do:
Post a new comment.
Reply to an existing comment.
Edit a comment.
Delete a comment.
React to a comment. Available reactions are LIKE and DISLIKE # open PR if you would like to have more reactions
All actions are done by AJAX calls - JQuery 3.2.1
Bootstrap 4.1.1 is used in comment templates for responsive design.
Installation
Requirements:
django>=2.1
djangorestframework # only for the API Framework
Bootstrap 4.1.1
jQuery 3.2.1
Installation:
Installation is available via pip
$ pip install django-comments-dab
or via source on github
$ git clone https://github.com/radi85/Comment.git $ cd Comment $ python setup.py install
Migrations:
Migrate comment app:
$ python manage.py migrate comment
Setup
Step 1 - Connecting comment model with the target model
In your models.py add the field comments as a GenericRelation field to the required model.
PS: Please note that field name must be comments NOT comment.
E.g. Post model, as shown below:
from django.contrib.contenttypes.fields import GenericRelation
from comment.models import Comment
class Post(models.Model):
author = models.ForeignKey(User)
title = models.CharField(max_length=200)
body = models.TextField()
# the field name should be comments
comments = GenericRelation(Comment)
Usage
1. Basics usage:
include_static this tag will include required jquery and javascript file, if you already use jquery please make sure it is not the slim version which doesn’t support ajax. include_bootstrap tag is for bootstrap-4.1.1, if it’s already included in your project, get rid of this tag.
In your template (e.g. post_detail.) add the following template tags where obj is the instance of post model.
{% load comment_tags %} {# Loading the template tag #}
{% render_comments obj request %} {# Render all the comments belonging to a passed object #}
Include static files:
The comment app has three template tags for static files that the app requires. These tags need to be included in the end of your base template.
Case 1: You already have jQuery in your project then the following tags shall be included below jQuery file:
{% load comment_tags %} {# Loading the template tag #}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
{% include_static %} {# Include comment.js file only #}
{% include_bootstrap %} {# Include bootstrap-4.1.1 - remove this line if it is already used in your project #}
Case 2: You don’t have jQuery in your project then the following tags shall be included:
{% load comment_tags %} {# Loading the template tag #}
{% include_static_jquery %} {# Include mini jQuery 3.2.1 and required js file #}
{% include_bootstrap %} {# Include bootstrap 4.1.1 - remove this line if BS 4.1.1 is already used in your project #}
2. Advanced usage:
1. Pagination:
By default the comments will be paginated, 10 comments per page. To disabled the pagination pass comments_per_page=None To change the default number, pass comments_per_page=number to render_comments.
{% load comment_tags %} {# Loading the template tag #}
{% render_comments obj request comments_per_page=5 %} {# Include all the comments belonging to a certain object #}
{% include_bootstrap %} {# Include bootstrap 4.1.1 - remove this line if BS 4.1.1 is already used in your project #}
{% include_static %} {# Include jQuery 3.2.1 and required js file #}
2. Integrate user profile:
If you have a profile model for the user and you would like to show the profile image next to each comment, do the following steps:
- Add PROFILE_APP_NAME and PROFILE_MODEL_NAME variables to your settings.py file.
e.g if user profile app is called accounts and profile model is called UserProfile
settings.py:
PROFILE_APP_NAME = 'accounts'
PROFILE_MODEL_NAME = 'UserProfile' # letter case insensitive
Make sure that get_absolute_url method is defined in your profile model.
from django.urls import reverse
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
...
...
# this method must be defined for appropriate url mapping in comments section
def get_absolute_url(self):
return reverse('your_profile_url_name')
3. Enable flagging:
The comment can be reported by the users. This feature can be enabled by adding the COMMENT_FLAGS_ALLOWED to settings.py and its value must be greater than 0 (the default).
The comment that has been reported more than the COMMENT_FLAGS_ALLOWED value, will be hidden from the view. To keep displaying the flagged comments to all users add COMMENT_SHOW_FLAGGED=True to settings.py
The default report reasons are:
Spam | Exists only to promote a service.
Abusive | Intended at promoting hatred.
Something else. With a message info, this option will be always appended reasons list.
The reasons can be customized by adding COMMENT_FLAG_REASONS list of tuples to settings.py. E.g.
settings.py
COMMENT_FLAG_REASONS = [
(1, _('Spam | Exists only to promote a service')),
(2, _('Abusive | Intended at promoting hatred')),
(3, _('Racist | Sick mentality')),
(4, _('Whatever | Your reason')),
...
]
The flag model has currently 4 states: v1.6.7
UNFLAGGED
FLAGGED - this case only the comment will be hidden
REJECTED - flag reasons are rejected by the moderator
RESOLVED - the comment content has been changed and accepted by the moderator
Groups and Permissions:
For flagging purpose, the following groups and permissions will be created on the next migrate:
- permissions:
delete_comment (default)
delete_flagged_comment
- groups:
comment_admin => has both mentioned permissions (edit permission might be added in the future)
comment_moderator => has delete_flagged_comment permission
Comment admin can delete any comment and change the state of flagged comment.
Comment moderator can delete FLAGGED comment only and change their state.
PS: If the groups or the permissions don’t exist, just run migrate. ./manage.py migrate
Web API
django-comments-dab uses django-rest-framework to expose a Web API that provides developers with access to the same functionality offered through the web user interface.
There are 5 methods available to perform the following actions:
Post a new comment. (Authenticated)
Reply to an existing comment. (Authenticated)
Edit a comment you posted. (Authenticated)
Delete a comment you posted. (Authenticated)
React to a comment. (Authenticated)
Report a comment. (Authenticated) Flagging system should be enabled
Change the state of reported comment. (admin and moderator) Flagging system should be enabled v1.6.7
Retrieve the list of comments and associated replies to a given content type and object ID.
These actions are explained below.
Setup:
To integrate the comment API in your content type (e.g Post model), in serializers.py for the Post model add comments field as shown below:
from rest_framework import serializers
from comment.models import Comment
from comment.api.serializers import CommentSerializer
class PostSerializer(serializers.ModelSerializer):
comments = serializers.SerializerMethodField()
class Meta:
model = Post
fields = (
'id',
...
...
'comments'
)
def get_comments(self, obj):
comments_qs = Comment.objects.filter_parents_by_object(obj)
return CommentSerializer(comments_qs, many=True).data
By default all fields in profile model will be nested inside the user object in JSON response. This can only happen if the profile attributes are defined in your settings.py. In case you would like to serialize particular fields in the profile model you should explicitly declare the COMMENT_PROFILE_API_FIELDS tuple inside your settings.py:
PROFILE_APP_NAME = 'accounts'
PROFILE_MODEL_NAME = 'userprofile'
# the field names below must be similar to your profile model fields
COMMENT_PROFILE_API_FIELDS = ('display_name', 'birth_date', 'image')
Comment API actions:
1- Retrieve the list of comments and associated replies to a given content type and object ID:
This action can be performed by providing the url with data queries related to the content type.
Get request accepts 3 params:
type: is the model name of the content type that have comments associated with it.
id: is the id of an object of that model
For example if you are using axios to retrieve the comment list of second object (id=2) of a model (content type) called post. you can do the following:
$ curl -H "Content-Type: application/json" 'http://localhost:8000/api/comments/?type=MODEL_NAME&id=ID'
2- Create a comment or reply to an existing comment:
Authorization must be provided as a TOKEN or USERNAME:PASSWORD.
type: is the model name of the content type that have comments associated with it.
id: is the id of an object of that model
parent_id: is 0 or NOT PROVIDED for parent comments and for reply comments must be the id of parent comment
Example: posting a parent comment
$ curl -X POST -u USERNAME:PASSWORD -d "content=CONTENT" -H "Content-Type: application/json" "http://localhost:8000/api/comments/create/?type=MODEL_NAME&id=ID&parent_id=0"
3- Update a comment:
Authorization must be provided as a TOKEN or USERNAME:PASSWORD.
This action requires the comment.id that you want to update:
$ curl -X PUT -u USERNAME:PASSWORD -d "content=CONTENT" -H "Content-Type: application/json" "http://localhost:8000/api/comments/ID/
4- Delete a comment:
Authorization must be provided as a TOKEN or USERNAME:PASSWORD.
This action requires the comment.id that you want to delete:
$ curl -X DELETE -u USERNAME:PASSWORD -H "Content-Type: application/json" "http://localhost:8000/api/comments/ID/
5- React to a comment:
POST is the allowed method to perform a reaction on a comment.
Authorization must be provided as a TOKEN or USERNAME:PASSWORD.
This action requires the comment.id. and, reaction_type: one of like or dislike
$ curl -X POST -u USERNAME:PASSWORD -H "Content-Type: application/json" "http://localhost:8000/api/comments/ID/react/REACTION_TYPE/
PS: As in the UI, clicking the liked button will remove the reaction => unlike the comment. This behaviour is performed when repeating the same post request.
6- Report a comment
Flagging system must be enabled by adding the attribute COMMENT_FLAGS_ALLOWED to settings.py. See Enable Flagging
POST is the allowed method to report a comment.
Authorization must be provided as a TOKEN or USERNAME:PASSWORD.
This action requires the comment.id.
Set a flag:
payload = {
'reason': REASON, # number of the reason
'info': '' # this is required if the reason is 100 ``Something else``
}
$ curl -X POST -u USERNAME:PASSWORD -H "Content-Type: application/json" -d '{"reason":1, "info":""}' http://localhost:8000/api/comments/ID/flag/
Un-flag a comment:
To un-flag a FLAGGED comment, set reason value to 0 or remove the payload from the request.
$ curl -X POST -u USERNAME:PASSWORD http://localhost:8000/api/comments/ID/flag/
7- Change flagged comment state
POST is the allowed method to report a comment.
Authorization must be provided as a TOKEN or USERNAME:PASSWORD.
This action requires comment admin or moderator privilege.
payload = {
'state': 3 # accepted state is 3 (REJECTED) or 4 (RESOLVED) only
}
$ curl -X POST -u USERNAME:PASSWORD -H "Content-Type: application/json" -d '{"state":3}' http://localhost:8000/api/comments/ID/flag/state/change/
Repeating the same request and payload toggle the state to its original
Style Customization
1- Default blocks:
BS classes, pagination and some other template values can be now customized from within your templates directory as follows:
Create comment folder inside your templates directory.
Create new template file . with the same name of the default template you wish to override and put it in the right directory.
Templates tree:
templates └── comment ├── comments │ ├── apply_icon. │ ├── base. │ ├── cancel_icon. │ ├── child_comment. │ ├── comment_body. │ ├── comment_content. │ ├── comment_form. │ ├── comment_modal. │ ├── content. │ ├── create_comment. │ ├── delete_icon. │ ├── edit_icon. │ ├── pagination. │ ├── parent_comment. │ └── update_comment. ├── flags │ ├── flag_icon. │ ├── flag_modal. │ └── flags. └── reactions ├── dislike_icon. ├── like_icon. └── reactions.
for example to override the BS classes of submit buttons and pagination style do the following:
create templates/comment/comments/create_comment.
{% extends "comment/comments/create_comment." %} {% block submit_button_cls %} btn btn-primary btn-block btn-sm {% endblock submit_button_cls %} {# override pagination style: #} {% block pagination %} {% include 'comment/comments/pagination.' with active_btn='bg-danger' text_style='text-dark' li_cls='page-item rounded mx-1' %} {% endblock pagination %}
For full guide on the default templates and block tags name Read the Doc
2- CSS file:
To customize the default style of comments app , you can create a comment.css file inside your static/css directory.
The new created file will override the original file used in the app.
Example
$ git clone https://github.com/Radi85/Comment.git # or clone your forked repo
$ cd Comment
$ python3 -m virtualenv local_env # or any name. local_env is in .gitignore
$ source local_env/bin/activate
$ pip install -r test/example/requirements.txt
$ python test/example/manage.py runserver
Login with:
username: test
password: django-comments
The icons are picked from Feather. Many thanks for the good work.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Hashes for django-comments-dab-1.6.7.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5c76a95e9d01b7ffb12f634bf622a0d2dc93071deebd9f0b215473d95406613a |
|
MD5 | 13f84299a6103714ee0546017d33287d |
|
BLAKE2b-256 | 67750aca6839f6e7a499da9e1031e090fa6badb71308d42bf02ebac26c7ecf78 |
Comment Settings and urls:
your settings.py should look like the following:
In your urls.py: