Only signed in users can comment — django-comments-xtd 3.0.0 documentation

# Only signed in users can comment

This page describes how to setup django-comments-xtd so that only registered users can write comments or flag them. That means mere visitors will be able to see the comments but won’t be able to send them. In order to do so a visitor must login first. The following instructions use the Django admin interface to login and logout users.

Table of Contents

- Simple example using only the backend

- Full featured example using backend and frontend code

## Simple example using only the backend

A simple site using django-comments-xtd can be represented by the Simple project.

### Customize the simple project

The Simple project is a basic example site that allows both, visitors and registered users, post comments to articles. It has been introduced in the Demo projects page: Simple project. The example loads a couple of articles to illustrate the functionality.

If you have already setup the Simple project, and have sent a few testing comments to see that visitors and registered users can comment, add the `COMMENTS_XTD_APP_MODEL_OPTIONS` entry at the bottom of the `settings.py` module to allow only registered users to post comments:

>     COMMENTS_XTD_APP_MODEL_OPTIONS = {
>         'default': {
>             'allow_flagging': False,
>             'allow_feedback': False,
>             'show_feedback': False,
>             'who_can_post': 'users'
>         }
>     }

Once the change is saved and Django has reloaded check that, as before, registered users can comment without issues, however visitors get the HTTP-400 page (Bad Request).

As a final step to customize the simple example site either edit `templates/comments/form.html` or `templates/articles/article_detail.html` to display a message inviting visitors to login or register instead of showing the post comment form.

As an example, here is a modified version of the `article_detail.html` template of the Simple project that displays a message with a link to the login page when the user is not authenticated:

>     [...]

>       {% if object.allow_comments %}
>         {% if user.is_authenticated %}
>           <div class="comment">
>             <h5 class="text-center">Post your comment</h5>
>             <div class="well my-4">
>               {% render_comment_form for object %}
>             </div>
>           </div>
>         {% else %}
>           <p class="text-center">
>             Only registered users can post comments. Please,
>             <a href="{% url 'admin:login' %}?next={{ object.get_absolute_url }}">login</a>.
>           </p>
>         {% endif %}
>       {% else %}
>         <h5 class="text-center">comments are disabled for this article</h5>
>       {% endif %}

>     [...]

## Full featured example using backend and frontend code

This section goes through the steps to customize a project that uses both, the backend and the frontend side of django-comments-xtd, to prevent that unregistered users can post comments.

We will use the Comp project.

The Comp project contains two very similar apps: articles and quotes. Both apps allow visitors and registered users to post nested comments. The main difference between articles and quotes in the Comp project is that the articles app uses the JavaScript plugin, while the quotes app uses merely the backend.

### Customize the quotes app

If you have already setup the Comp project, and have sent a few testing comments to see that visitors and registered users can comment, edit the `COMMENTS_XTD_APP_MODEL_OPTIONS` at the bottom of the `settings.py` and append the pair `'who_can_post': 'users'` to the quotes app dictionary:

>     COMMENTS_XTD_APP_MODEL_OPTIONS = {
>         'quotes.quote': {
>             'allow_flagging': True,
>             'allow_feedback': True,
>             'show_feedback': True,
>             'who_can_post': 'users'
>         }
>     }

Once changes are saved and Django has restarted see that registered users can comment without issues. However visitors get the HTTP-400 page (Bad Request).

One last customization is required to prevent the HTTP-400 Bad Request. We have to edit the `templates/quotes/quote_detail.html` file and be sure that the block that renders the comment form is not displayed when the user browsing the site is a mere visitor. The following changes will make it:

>     [...] around line 41...

>         {% if object.allow_comments %}
>           {% if object|can_receive_comments_from:user %}
>             <div class="card card-block mt-4 mb-5">
>               <div class="card-body">
>                 <h4 class="card-title text-center pb-3">Post your comment</h4>
>                 {% render_comment_form for object %}
>               </div>
>             </div>
>           {% else %}
>             <p class="mt-4 mb-5 text-center">
>               Only registered users can post comments. Please,
>               <a href="{% url 'admin:login' %}?next={{ object.get_absolute_url }}">login</a>.
>             </p>
>           {% endif %}
>         {% else %}
>           <h4 class="mt-4 mb-5 text-center text-secondary">
>             Comments are disabled for this quote.
>           </h4>
>         {% endif %}

>     [...]

Note

See that in the previous snippet we use the template filter `can_receive_comments_from`. Using this filter you could change the setting `'who_can_post'` to `'all'` in your `COMMENTS_XTD_APP_MODEL_OPTIONS` to allow mere visitors to post comments, and your template would do as expected without further changes.

If we rather had used `{% if user.is_authenticated %}` the template would have still to be changed to display the comment form to all, visitors and registered users.

After the template changes are saved, mere users will see a message inviting them to login. Also, the Reply link to send nested comments is already aware of the value of the `'who_can_post'` setting and will redirect you to login if you have not done so yet.

### Customize the articles app of the comp project

The articles app uses the JavaScript plugin. The only change required consist of adding the pair `'who_can_post': 'users'` to the `'articles.article'` dictionary entry of the `COMMENTS_XTD_APP_MODEL_OPTIONS`, as we did with the quotes app. That will make it work.

Run the site and check that as a mere visitor (logout first) you can not send comments to articles. Instead of the comment form there must be a message in blue saying that Only registered users can post comments. If you login and visit an article’s page the comment form will be visible again.

The message in blue is the default response hardcoded in the `commentbox.jsx` module of the JavaScript plugin. The commentbox module controls whether the user in the session can post comments or not. If the user can not post comments it defaults to display that message in blue.

Most of the times we will want to customize that message. We will achieve it by modifying both, the `base.html` and the `articles/article_detail.html`, and by creating a new template in the `comp/templates/django_comments_xtd` directory called `only_users_can_post.html`.

The changes in `templates/base.html` consist of adding a hidden block. We will put content in this hidden block in the `articles_detail.html`. Add the following HTML code before the script tags in the `base.html` in the `example/comp/templates` directory:

>     [...] around line 67, right before the first <script> tag...

>         <div style="display:none">
>           {% block hidden %}
>           {% endblock %}
>         </div>

>     [...]

Add the following code to `templates/articles/article_detail.html`:

>     [...] around line 46, right before the {% block extra_js %}...

>     {% block hidden %}
>       {% render_only_users_can_post_template object %}
>     {% endblock %}

And finally create the file `only_users_can_post.html` within the `comp/templates/django_comments_xtd` directory, with the following content in it:

>     <div id="only-users-can-post-{{ html_id_suffix }}">
>       <p class="text-center">Only registered users can post comments. Please,
>         <a href="{% url 'admin:login' %}?next={{ object.get_absolute_url }}">login</a>.
>       </p>
>     </div>

With all the changes already done, logout of the comp site and reload the article’s page. You should see the message with the login link.