Django——实现最基础的评论功能(只有一级评论)
我对评论功能的理解:
————————(1)数据库建一个评论的表
————————(2)前端建一个提交评论的form表单
————————(3)表单提交评论内容后写入到数据库评论表中
————————(4)将评论表的数据取出来展示到前端评论列表中
1、项目目录结构

2、路由
(1)总路由:
from django.contrib import admin
from django.urls import path,include urlpatterns = [
path('admin/', admin.site.urls),
path('blog/',include('blog.urls'))
]
(2)app路由:
from django.urls import path,re_path
from blog import views urlpatterns = [
path('',views.index),
re_path('article_detail/(\d+)',views.article_detail) # 传入文章ID参数
]
3、模型
from django.db import models
from django.contrib.auth.models import User class Article(models.Model):
title = models.CharField(max_length=70,verbose_name='文章标题')
content = models.TextField(verbose_name='正文')
author = models.ForeignKey(to=User,on_delete=models.DO_NOTHING,verbose_name='作者')
created_time = models.DateTimeField(auto_now_add=True,verbose_name='发布时间') class Meta:
db_table = 'article'
verbose_name = '文章'
verbose_name_plural = verbose_name class Comment(models.Model):
article = models.ForeignKey(to=Article,on_delete=models.DO_NOTHING,verbose_name='文章')
content = models.TextField(verbose_name='评论内容')
author = models.ForeignKey(User,on_delete=models.DO_NOTHING,verbose_name='评论者')
post_time = models.DateTimeField(auto_now_add=True,verbose_name='评论时间') class Meta:
db_table = 'comment'
verbose_name = '评论'
verbose_name_plural = verbose_name
4、视图函数
from django.shortcuts import render,HttpResponse,redirect
from django.core.paginator import Paginator
from blog.models import Article
from blog.models import Comment def index(request):
all_article_list = Article.objects.all()
paginator = Paginator(all_article_list,10) #实例化分页器对象
page = int(request.GET.get('page',1)) #获取页码数
article_list_obj = paginator.page(page) #获取当前页的分页对象
article_list = article_list_obj.object_list #获取当前页的数据列表
context = {
'article_list': article_list,
'paginator': paginator,
'article_list_obj': article_list_obj
}
return render(request,'blog/index.html',context=context) def article_detail(request,article_id):
if request.method == 'GET':
article = Article.objects.get(id=article_id)
comment_list = Comment.objects.filter(article_id=article.id)
context = {
'article': article,
'request': request,
'comment_list': comment_list
}
return render(request,'blog/article_detail.html',context=context)
else:
c_id = article_id
c_author = request.user.id
c_content = request.POST.get('content')
Comment.objects.create(content=c_content,article_id=c_id,author_id=c_author)
return redirect('/blog/article_detail/{}/'.format(c_id))
5、模板HTML
(1)base.html
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.14/favicon.ico">
<link rel="canonical" href="https://getbootstrap.com/docs/3.4/examples/jumbotron/"> <title>{% block title %}{% endblock %}</title> <!-- Bootstrap core CSS -->
<link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.14/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.14/assets/css/ie10-viewport-bug-workaround.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.14/examples/jumbotron/jumbotron.css" rel="stylesheet">
<!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
<!--[if lt IE 9]><script src="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.14/assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<script src="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.14/assets/js/ie-emulation-modes-warning.js"></script>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head> <body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/blog/">博客首页</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<form class="navbar-form navbar-right">
<div class="form-group">
<input type="text" placeholder="Email" class="form-control">
</div>
<div class="form-group">
<input type="password" placeholder="Password" class="form-control">
</div>
<button type="submit" class="btn btn-success">登录</button>
</form>
</div><!--/.navbar-collapse -->
</div>
</nav>
<br> {% block content %} {% endblock %} </body>
</html>
(2)首页index.html
{% extends 'base.html' %}
{% block title %}
博客首页
{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="el-col-md-12">
<table class="table"> {# 文章列表 #}
<tr class="info">
<th>ID</th>
<th>标题</th>
<th>正文</th>
<th>正文</th>
<th>时间</th>
</tr>
{% for article in article_list %}
<tr class="active">
<td>{{ article.id }}</td>
<td><a href="/blog/article_detail/{{ article.id }}/">{{ article.title}}</a></td>
<td>{{ article.content|truncatechars:100}}</td>
<td>{{ article.created_time}}</td>
<td>{{ article.author.username}}</td>
</tr>
{% endfor %}
</table> {# 文章列表结束 #}
<div> {# 分页块 #}
<nav aria-label="Page navigation">
<ul class="pagination">
{% if article_list_obj.has_previous %}
<li>
<a href="/blog/?page={{ article_list_obj.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% endif %}
{% for number in paginator.page_range %}
<li><a href="/blog/?page={{ number }}">{{ number }}</a></li>
{% endfor %}
{% if article_list_obj.has_next %}
<li>
<a href="/blog/?page={{ article_list_obj.next_page_number }}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
{% endif %}
</ul>
</nav>
</div> {# 分页块结束 #}
</div>
</div>
</div>
{% endblock %}
(3)文章详情article_detail.html
{% extends 'base.html' %}
{% block title %}
文章详情
{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="panel panel-primary"> {# 文章详情区域 #}
<div class="panel-body">
{{ article.title }}
</div>
<div class="panel-body">
{{ article.content }}
</div>
<div class="panel-footer">{{ article.author }} {{ article.created_time }}</div>
</div> {# 文章详情区域结束 #}
<div>
<hr>
<h4><b>评论</b></h4>
<form action="" method="post">
<textarea class="form-control" rows="3" name="content"></textarea>
<br>
<button type="submit" class="btn btn-primary">提交</button>
</form>
<hr>
<div class="panel panel-danger">
<div class="panel-body">评论列表</div>
<div>
{% for comment in comment_list %}
<div> {{ comment.content }}</div>
<div> {{ comment.post_time }} & {{ comment.author.username }}</div>
<hr>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
6、效果


Django——实现最基础的评论功能(只有一级评论)的更多相关文章
- Django——实现评论功能(包括评论回复)
提示:(1)功能不全面,仅仅实现评论(2)样式简单 1.项目目录结构 2.模型 from django.db import models from django.contrib.auth.models ...
- Django使用forms来实现评论功能
貌似Django从版本1.6开始就放弃了对自带的comments的使用,具体原因未查,但是现在使用Django的内部的模块也可以实现评论功能,那就是借助于forms模块,下面是我的一个小例子. 环境准 ...
- [个人网站搭建]·Django增加评论功能(Python3)
[个人网站搭建]·Django增加评论功能 个人主页--> https://xiaosongshine.github.io/ 个人网站搭建github地址:https://github.com/ ...
- Django自带评论功能的基本使用
1. 模块安装 pip install django-contrib-comments 2. 注册APP INSTALLED_APP=( #..., 'django_comments', 'djang ...
- Django博客功能实现—文章评论的显示
功能:在打开文章之后,能在文章下面是显示文章的评论,有父级评论.思路:在文章详情的视图里面,获取这个文章的全部评论,得到显示列表,然后用模板显示出来.步骤:一,在views.py的文章详情中获取评论: ...
- 一步步搭建自己的博客 .NET版(2、评论功能)
前言 这次开发的博客主要功能或特点: 第一:可以兼容各终端,特别是手机端. 第二:到时会用到大量html5,炫啊. 第三:导入博客园的精华文章,并做分类.(不要封我) 第四:做 ...
- 《玩转Django2.0》读书笔记-Django建站基础
<玩转Django2.0>读书笔记-Django建站基础 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.网站的定义及组成 网站(Website)是指在因特网上根据一 ...
- Django实现文章按年月归档、点赞和评论、发送邮件
文章归档的实现 我们在创建文章时,会在数据库中存储文章创建的时间这样的字段,一般用的都是datetime类型,记录文章创建的年月日和时分秒,所以我们直接使用文章的创建时间分类是无法实现文章的按年月归档 ...
- React.js 小书 Lesson25 - 实战分析:评论功能(四)
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson25 转载请注明出处,保留原文链接和作者信息. (本文未审核) 目前为止,第二阶段知识已经基本 ...
随机推荐
- Maven国内仓库
由于国外的官方Maven仓库比较慢,所以寻找国内的代理仓库. 网上找了一些博客,内容都是一模一样,并且不贴代理官方的说明. 我在阿里云的Maven仓库找到了官方说明. 下面直接贴配置指南: 配置指南 ...
- Winform中生成自动控件
场景: 前几天项目需要模拟数据,但是实际设备还没有接上,就自己用Winform搭建了一个数据模拟器,生成数据给平台.这里又一个需求,就是从数据库中找出设备,然后自动生成控件,勾选就表示开启该设备,能上 ...
- SSH远程端口转发实战详解
问题 前段时间在外地没有在实验室,随身携带了一个笔记本电脑.但是笔记本性能不够,想用SSH远程连接实验室的电脑.问如何连接?现有以下设备 设备 IP 备注 系统 实验室电脑C1 192.168.0.2 ...
- Vue单点登录控件代码分享
这里提供一个Vue单点登录的demo给大家参考,希望对想了解的朋友有一些帮助. 具体的原理大家可以查看我的上篇文章 vue实现单点登录的N种方式 废话不多少直接上代码 这里分两套系统,一是登录系统的主 ...
- SuperEdge 高可用云边隧道有哪些特点?
作者 作者李腾飞,腾讯容器技术研发工程师,腾讯云TKE后台研发,SuperEdge核心开发成员. 背景 在边缘集群中,边缘端和云端为单向网络,云端无法主动连接边缘端,常见的解决方案是边缘端主动和云端( ...
- Unix 网络IO模型介绍
带着问题阅读 1.什么是同步异步.阻塞非阻塞 2.有几种IO模型,不同模型之间有什么区别 3.不同IO模型的应用场景都是什么 同步和异步.阻塞和非阻塞 同步和异步 广义上讲同步异步描述的是事件中发送方 ...
- JavaEE在线就业班2.0-(1)-《博学谷》
JavaEE在线就业班2.0学习笔记 1. Java概述 1.1 Java语言背景介绍(了解) 语言:人与人交流沟通的表达方式计算机语言:人与计算机之间进行信息交流沟通的一种特殊语言Java语言是美国 ...
- Python实现多种SSH连接与文件传输
Python实现SSH控制 使用Python进行基于口令认证的连接: 1 #加载paramiko包 2 import paramiko 3 #创建新的SSH对象 4 Client=paramiko.S ...
- jdk、jre环境变量配置
1 jdk和jre的区别: (jdk:Java 开发工具包) (jre:Java 的运行环境) 只需这么记就可以了,想深入了解得自行查询相关资料 2 jdk是包含jre的,所以只需下载jdk. 官方网 ...
- springboot整合javafx
原文(原码)参考地址: https://github.com/roskenet/springboot-javafx-support https://github.com/spartajet/javaf ...