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 转载请注明出处,保留原文链接和作者信息. (本文未审核) 目前为止,第二阶段知识已经基本 ...
随机推荐
- Jenkins远程命令执行漏洞(CVE-2018-1000861)
此漏洞没有回显,直接利用orange的exp执行命令反弹shell 工具地址https://github.com/orangetw/awesome-jenkins-rce-2019 web服务器下写1 ...
- C++面向对象 1(类-封装)
1 //类和对象 2 //C++ 面向对象 三大特性 : 封装 继承 多态 3 4 //设计一个圆类,求圆的周长 5 //圆周长 = 2*PI * 半径 6 7 #include <iostre ...
- Http Request Smuggling - Note
http请求走私漏洞 访问Burp靶场速度感人..都要哭了(如果没有账户的先创建账户) 基础补充 pipeline http1.1有了Pipeline,就不需要等待Server端的响应了.浏览器默认不 ...
- 关于TreeSet集合的理解
TreeSet 集合主要是实现了Collection集合的实现类,主要框架为: 1. Set接口的框架: |----Collection接口:单例集合,用来存储一个一个的对象 |----Set接口: ...
- Ubuntu安装ssh,及失败解决方案
网上有很多介绍在Ubuntu下开启SSH服务的文章,但大多数介绍的方法测试后都不太理想,均不能实现远程登录到Ubuntu上,最后分析原因是都没有真正开启ssh-server服务.最终成功的方法如下: ...
- View epub and mobi File on Linux
Calibre has stand-alone ebook viewer "ebook-viewer", start it in terminal: $ ebook-viewer ...
- vim编辑文件时[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:
出现这个问题是因为你上次编辑的时候在没有保存的情况下退出了(如:电脑关机等)也有可能是有其他人在和你同时进行编辑行为(不同会话中).这是因为在用vim编辑的时候,vim会在打开文件目录下 ...
- 大数的快速幂模 Python实现
要求 实现模幂算法,通过服务器的检验. 访问http://2**.207.12.156:9012/step_04服务器会给你10个问题,每个问题包含三个数(a,b,c),请给出a^b%c的值.返回值写 ...
- Spring-boot注入配置为java静态属性
配置文件 注入静态变量 注意 类上面有:@Component注解 使用注入的静态变量 成功
- new和delete关键字
new关键字创建出来的对象位于什么地方?很明显嘛,new关键字创建出来的对象一定位于堆空间,这种说法一定正确吗?本篇博客帮你揭开其神秘的面纱. 被忽略的事实new/delete的本质是C++预定义的操 ...