Create a forum application using django #14: Delete comment forum, Use and Display notifications
Repository
What Will I Learn?
- Delete comment forum
- Use and Display notifications
Requirements
- Basic Python
- Install Python 3
- Install Django
Resources
- Python - https://www.python.org/
- Django- https://www.djangoproject.com/
- Bootstrap 4 - https://getbootstrap.com/docs/4.0/getting-started/introduction/
Difficulty
Basic
Tutorial Content
In the previous tutorial, we made a comment system feature and we have made a comment edit feature. In this tutorial, I will still continue the features in the comments and not only start the comment feature, this time I will introduce flash message to add a user experience. For those of you who just followed this tutorial, I suggest you follow my previous tutorial in the curriculum section. We begin to continue this tutorial by making the deleted comment feature.
Delete comments on the forum
In the previous tutorial, we made the comment edit feature. Of course, we will also make the delete feature, with the Create, Read, Update and Delete (CRUD) we have also implemented the CRUD feature in our comment system. When we make a comment edit feature, we will start creating a URL that will be used to delete comments, For more details, we can see the code below:
forums/urls.py
from django.urls import path
from .views import (ForumCreate, ForumListView, ForumUserListView,
ForumDetailView, ForumUpdateView, ForumDeleteView,
CommentCreateView, CommentUpdateView, CommentDeleteView) // import all view classes that are in views.py
urlpatterns = [
path('', ForumListView.as_view(), name='forum-list'),
path('add/', ForumCreate.as_view(), name='forum-add'),
path('edit/<int:pk>', ForumUpdateView.as_view(), name='forum-edit'),
path('delete/<int:pk>', ForumDeleteView.as_view(), name='forum-delete'),
path('<slug:slug>/', ForumDetailView.as_view(), name='forum-detail'),
path('by/<username>/', ForumUserListView.as_view(), name='forum-by'),
path('add-comment/<int:pk>', CommentCreateView.as_view(), name='add-comment'), // URL for add Comment
path('edit-comment/<int:pk>', CommentUpdateView.as_view(), name='edit-comment'), // URL for edit Comment
path('delete-comment/<int:pk>', CommentDeleteView.as_view(), name='delete-comment'), // URL for delete Comment
]
The code above is all a collection of URLs that we use in our forum application. The URL we add is
'delete-comment/<int: pk>'
. We will use this URL to delete the comments we choose. Just like the edit URL. In this section, we will pass the parameter which is the primary key<int:pk>
.In the delete URL we will use the CommentDeleteView view class, This class comes from imported products that we have imported first at the top
from .views import CommentDeleteView
. then we will give the alias of this URL, that isname = 'delete-comment'
By using an alias, we will easily call it.
Create CommentDeleteView Class
We have used the CommentDeleteView class on the URL, but haven't created it, for that we can make in forums/views.py. In this class, we will delete the comments that are owned by the User who is logged in. for more details, we can see the code below:
forums/views.py
@method_decorator(login_required, name='dispatch')
class CommentDeleteView(OwnerProtectMixin, DeleteView):
model = Comment
success_url = '/forum'
In this class, I will use 2 (Login Protection and User protection). The protection we have made in the previous [tutorial]https://steemit.com/utopian-io/@duski.harahap/create-a-forum-application-using-django-6-crud-system-and-url-protection-redirect-system). You can follow the tutorial to find out more.
We will protect user data from other users using OwnerProtectMixin protection which we will pass as a parameter to the CommentDeleteView class
CommentDeleteView(OwnerProtectMixin, DeleteView):
to delete we can use the generic viewDeleteView
from DjangoThen we can define what model we will use
model = Comment
and after that we can define the URL used to redirectsuccess_url = '/forum'
.
Displays the delete comment interface
Then we will make an interface that the user will use to trigger the functions we have created before. I will put the delete comment interface in the forum_detail.html template. For more details, we can see the example below:
forums/forum_detail.html
{% for comment in object.comment_set.all %}
<p>
{{comment.desc}}
{% if request.user == comment.user %}
<a href="{% url 'edit-comment' comment.id %}">Edit</a>
<form method="post" action="{% url 'delete-comment' comment.id %}">
{% csrf_token %}
<input type="submit" name="Delete">
</form>
{% endif %}
<br><span style="font-size: 12px;"><i>by {{comment.user}}</i></span>
</p>
{% endfor %}
- I will use the post method to delete user comments. For that, we need to use
<form>
tag. We use the post method on the formmethod="post"
and the action we will take is to go to the URLdelete-comment / <int: pk>
. We can use alias to make it easier to call them like the following{% url delete-comment comment.id %}
and we will pass thecomment.id
as the primary key parameter that will be used to delete comments specifically.
After we have finished making all the systems, we can see the results as shown below:
We can see in the picture above we have successfully deleted the comments that are owned by the user.
Notification message
This second part we will use a flash message feature as a notification to the user. Before the other tutorials, we did not use notifications for every action we took. We will use a new function that will be used to create a flask message in Django. for more details, we can see the following example:
forums/views.py
from django.contrib.messages.views import SuccessMessageMixin // import the class messages
@method_decorator(login_required, name='dispatch')
class ForumCreate(SuccessMessageMixin, CreateView):
model = Forum
fields = ['title','desc']
success_message = 'Forum was successfully created' // The message
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
The first thing we do is we will import the notifications provided by Django. we can import it in
from django.contrib.messages.views
and create an alias that we will passclass ForumCreate(SuccessMessageMixin, CreateView)
to the function that uses this notification.And the model we will use is the Forum
model = Forum
. This function we will only pass the SuccessMessageMixin function to theForumCreate()
class. We use the ForumCreate function when I want to create a new forum.We can pass the contents of the message like the following
success_message = 'Forum was successfully created'
.
- Display the notification
Now in this section, we will display the notification on the base layout instead of the template that will be rendered. because we have to understand that the notifications we make will be used on a global template. which is not bound to a rendered template. For more details, we can see examples like the following:
templates/base.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<title>{% block title %} {% endblock %}</title>
</head>
<body>
<nav class="navbar navbar-expand-lg bg-primary navbar-dark">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
</li>
{% if user.is_authenticated %}
<li class="nav-item">
<a class="nav-link" href="{% url 'logout' %}">Logout</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">{{user}}</a>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link" href="{% url 'signup' %}">Register</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'login' %}">Login</a>
</li>
{% endif %}
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
(html comment removed: start display message )
{% if messages %}
<div class="card bg-success text-white">
{% for message in messages %}
<div class="card-body">{{message}}</div>
{% endfor %}
</div>
{% endif %}
{% block content %}
{% endblock %}
</body>
</html>
We will check whether there is a notification or not. We can check it on variable
{% if messages %}
. If there is a notification we will display it. Please note that the notification structure used is an array, so we can looping it to display it.to do a looping we can do it like this
{% for message in messages %}
and I will use a style from the bootstrap to improve the appearance of the notification. You can add your own styling.
We can see in the picture above we managed to display the notification that we have created in the ForumCreate class view
- Use notification on the delete forum
Then we will use notifications when we delete forums. the way is not much different, we will also still use the message function from Django. For more details, we can see in the example below:
forums/views.py
@method_decorator(login_required, name='dispatch')
class ForumDeleteView(SuccessMessageMixin, OwnerProtectMixin, DeleteView):
model = Forum
success_url = '/forum'
success_message = 'Forum was successfully deleted'
We will give the notification message as follows
success_message = 'Forum was successfully deleted'
.In this class we make a riderect to the URL /forums
success_url = '/forum'
Then we will display the message in the forum_list.html template. We will display the notification like this:
forums/forum_list.html
{% extends "base.html" %}
{% load humanize %}
{% block title %} List Forum{% endblock %}
{% block content %}
{% if messages %}
<div class="card bg-danger text-white">
{% for message in messages %}
<div class="card-body">{{message}}</div>
{% endfor %}
</div>
{% endif %}
<div class="jumbotron">
<h1>Forums</h1>
<ul>
{% for forum in object_list %}
<li><a href="{% url 'forum-detail' forum.slug %}"><b>{{forum.title}}</b></a> | <a href="{% url 'forum-by' forum.user %}">{{forum.user}}</a> | <span style="font-size: 12px;"><i>{{forum.created_at | naturaltime}}</i></span></li><br>
{% endfor %}
</ul>
</div>
{% endblock%}
We will use the framework bootstrap to improve the appearance of the notification. Here I will use
<div class = "card bg-danger text-white">
.In this section we will also loop for object messages
{% for message in messages %}
and if everything is done we can see the results like the following:
We have successfully made a notification when the forum was deleted. You can give your own style to improve the display of notifications, thanks for following this tutorial. may be useful.
Curriculum
- Forum app
django#1, django#2, django#3, django#4, django#5, django#6, django#7
Thank you for your contribution @duski.harahap.
After reviewing your contribution, we suggest you following points:
Your forum has been interesting with these new features.
Why in this tutorial did you not present GIFs to demonstrate the results? Using GIFs to show results looks better than putting image only.
Thank you for your work in developing this tutorial.
Looking forward to your upcoming tutorials.
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Chat with us on Discord.
[utopian-moderator]
Thank you for your review, @portugalcoin! Keep up the good work!
Congratulations @duski.harahap! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :
You can view your badges on your Steem Board and compare to others on the Steem Ranking
If you no longer want to receive notifications, reply to this comment with the word
STOP
To support your work, I also upvoted your post!
Vote for @Steemitboard as a witness to get one more award and increased upvotes!
Hi @duski.harahap!
Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server
Hey, @duski.harahap!
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!