In the previous article, we implemented the functions of displaying articles and creating articles respectively.
In this article we implement the function of deleting articles.
Simple function implementation
Deleting articles is very simple in terms of function implementation. The view function is as follows:
# 删文章
def article_delete(request, id):
# 根据 id 获取需要删除的文章
article = Article.objects.get(id=id)
# 调用.delete()方法删除文章
article.delete()
# 完成删除后返回文章列表
return redirect("list")
- Similar to querying articles, because you need to know which article should be deleted, you must pass in the id of the article;
- Then call the .delete() function to delete the entry of this article in the database;
- Return to the article list after successful deletion.
Then modify the routing configuration document
urlpatterns = [
path('admin/', admin.site.urls),
path('hello/', views.hello),
re_path(r'^$', views.article_list),
path('list/', views.article_list, name='list'), # 展示文章
path('detail/<int:id>/', views.article_detail, name='detail'), # 文章详情
path('create/', views.article_create, name='create'), # 写文章
# 增加生删除文章
path('delete/<int:id>/', views.article_delete, name='delete'),
]
Finally, modify the template and detail.html
add a button to delete articles on the details page.
<!-- 文章详情 -->
<div class="container">
<!-- <div class="row">-->
<!-- 标题及作者 -->
<h1 class="col-12 mt-4 mb-4">{
{ article.title }}</h1>
<div class="col-12 alert alert-primary">
<div class="col-12">
<a>作者:{
{ article.author }}</a>
 
<a>{
{ article.created|date:'Y-m-d H:i:s' }}</a>
 
<a href="{% url "delete" article.id %}">删除文章</a> #增加此项
</div>
</div>
<!-- 文章正文 -->
<div class="col-12">
<p>{
{ article.body }}</p>
</div>
</div>
After running the server, you can see that a delete article button has been added.
Remove pop-up confirmation function
The above implements a simple function, but there is a hidden danger, that is, if you accidentally click the delete button, you may not even have the chance to regret it.
Generally, for actions involving direct data clearing, a pop-up window confirmation action is required, and the database data can be directly deleted only after a second confirmation.
To achieve this function we can use Bootstrap's modal component.
A modal is a subform that overlays a parent form. Typically, the purpose is to display content from a separate source that can have some interaction without leaving the parent form. Subforms can provide information interaction, etc.
Delete the article code in detail.html
the newly added line before and make the following modifications:
<a href="#" data-bs-toggle="modal" data-bs-target="#myModal">删除文章</a>
A modal box effect has been added. Clicking this link will pop up myModal
a modal box named.
Then we implement myModal
the function of deleting articles in the modal box.
<!-- 模态框 -->
<div class="modal fade" id="myModal">
<div class="modal-dialog modal-dialog-centered modal-sm">
<div class="modal-content">
<!-- 模态框头部 -->
<div class="modal-header">
<h4 class="modal-title">确认删除</h4>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<!-- 模态框主体 -->
<div class="modal-body">
确认删除文章?
</div>
<!-- 模态框底部 -->
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" onclick="confirm_delete()">
确定
</button>
</div>
</div>
</div>
</div>
<script>
// 删除文章的函数
function confirm_delete() {
location.href = '{% url "delete" article.id %}'
}
</script>
Here we actually implement two functions.
- A modal box named myModal is implemented, and two buttons are added to the modal box: Cancel and Confirm. Clicking Confirm will call the JS function
confirm_delete()
to delete the article. - I wrote a function
confirm_delete()
that will call Django's delete articleurl:delete
to implement the deletion function.
safe way
You may think that the function of deleting articles is not difficult to implement, but please note that the above method has hidden dangers . To continue the discussion in depth, we have to mention cross-site request forgery attacks , also known as CSRF attacks (Cross-site request forgery).
CSRF attack
You can understand a CSRF attack as: the attacker steals your identity and sends malicious requests in your name. Let’s take deleting articles as an example:
- The user logged into blog website A , and the browser recorded the session and maintained the logged-in status;
- The user accidentally opened the evil attack website B without logging out ;
- Attacking website B implants malicious code into the page and silently sends a request to delete the article to blog website A. At this time, the browser mistakenly thinks that the user is operating, and successfully performs the deletion operation.
Due to the browser's same-origin policy, a CSRF attacker cannot obtain the actual content of your login data, but can trick the browser into attaching the correct login data to the malicious request. Don’t underestimate the power of CSRF attacks: if your bank account has such security holes, hackers can transfer all your deposits without anyone noticing.
So how to prevent the risk of CSRF attacks here? There is a method, that is, use the POST method when deleting an article, and verify the csrf token.
CSRF token
We mentioned earlier that csrf_token must be added when submitting a form in Django. This is the CSRF token. The process of preventing CSRF attacks is as follows:
- When a user visits a Django site, there is an implicit field csrf_token in the form fed back to the user by Django. This value is randomly generated on the server side and is different every time;
- Before the backend processes the POST request, Django will verify whether the csrf_token in the requested cookie is consistent with the csrf_token in the form. If they are consistent, the request is legitimate. Otherwise, the request may come from a CSRF attack and 403 Server Forbidden Access will be returned.
Since the attacker cannot obtain the user's cookie content (just relies on the browser to forward it), it is usually impossible to construct the correct csrf_token, thus preventing such attacks.
Use Form to send Post request
To send a Post request in Django, you can specify the request method in the Form.
First, add a hidden Form below the delete article button code:
<a href="#" data-bs-toggle="modal" data-bs-target="#myModal">删除文章</a>
<!-- 新增一个隐藏的表单 -->
<form
style="display:none;"
id="safe_delete"
action="{% url "delete" article.id %}"
method="POST"
>
{% csrf_token %}
<button type="submit">发送</button>
</form>
Next we modify our confirm_delete()
function.
<script>
// 删除文章的函数
function confirm_delete() {
document.getElementById("safe_delete").submit();
}
</script>
Finally, we transform the view function:
# 删文章
def article_delete(request, id):
print(request.method)
if request.method == 'POST':
# 根据 id 获取需要删除的文章
article = Article.objects.get(id=id)
# 调用.delete()方法删除文章
article.delete()
return redirect("list")
else:
return HttpResponse("仅允许post请求")
Previously, our function was to directly call the URL to request Django's view deletion function.
Now after our transformation, the code process for deleting articles is as follows:
- When clicking the delete article link, a modal box pops up
- After clicking the confirmation button of the modal box, find the hidden Form through the JS function code and submit the form.
- The form initiates a POST request and carries the csrf token (Django verifies all POST requests through middleware by default
csrf
), thus avoiding csrf attacks.
Conclusion
In this article, we learned how to implement the function of deleting articles, and also used Bootstrap's modal pop-up box to perform secondary verification of deleted articles.
When it comes to the deletion function, in order to increase data security, we briefly introduced Django's csrf
token protection mechanism, and enabled Django's crsf
verification mechanism by using a hidden form and sending a Post request.
The deletion function actually has an important verification: user verification, which we have not covered yet. We will arrange to add it later when adding user module functions.
In the next article, you will learn how to update an article.