Django+Bootstrap+Mysql 搭建个人博客(六)
6.1.comments插件
(1)安装
pip install django-contrib-comments
(02)settings
INSTALLED_APPS = [ 'django.contrib.sites', 'django_comments', ]
SITE_ID =1
(3)website/url
url(r'^comments/', include('django_comments.urls')),
(4)修改源码
django_comments/abstracts.py第36行
原代码
site = models.ForeignKey(Site, on_delete=models.CASCADE)
修改后
site = models.ForeignKey(Site,default=None,blank=True,null=True,on_delete=models.CASCADE)
(5)修改源码
django_comments/abstracts.py第52行
修改和增加了几个字段
class CommentAbstractModel(BaseCommentAbstractModel): """ A user comment about some object. """ # Who posted this comment? If ``user`` is set then it was an authenticated # user; otherwise at least user_name should have been set and the comment # was posted by a non-authenticated user. user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('user'), blank=True, null=True, related_name="%(class)s_comments", on_delete=models.SET_NULL) # Explicit `max_length` to apply both to Django 1.7 and 1.8+. user_email = models.EmailField(_("user's email address"), max_length=254, blank=True,null=True,default='xxx@xxx.com') user_url = models.URLField(_("user's URL"), blank=True,null=True,default='https://xxx.xxx.xxx.xxx') user_name = models.CharField(_("user's name"), max_length=50, blank=True) user_img = models.ImageField(upload_to="user_images", blank=True,null=True,verbose_name="用户图像") comment_title = models.CharField(max_length=256,default="无标题", blank=True,null=True,verbose_name="评论标题") parent_comment = models.ForeignKey('self',default=None, blank=True,null=True,related_name="child_comment",on_delete=models.CASCADE) level = models.PositiveIntegerField(default=0, blank=True,null=True,verbose_name='评论层级') comment = models.TextField(_('comment'), max_length=COMMENT_MAX_LENGTH) . . . .
(6)修改源码
django_comments/admin.py第29和37行
_('Content'), {'fields': ('user', 'user_name', 'user_email', 'user_url', 'comment','comment_title','parent_comment')}
list_display = ('comment_title','name', 'content_type', 'object_pk', 'ip_address', 'submit_date', 'is_public', 'is_removed')
(7)修改源码
django_comments/forms.py第97行表单
class CommentDetailsForm(CommentSecurityForm): """ Handles the specific details of the comment (name, comment, etc.). """ # name = forms.CharField(label=pgettext_lazy("Person name", "Name"), max_length=50) # email = forms.EmailField(label=_("Email address")) # url = forms.URLField(label=_("URL"), required=False) # Translators: 'Comment' is a noun here. comment = forms.CharField(label=_('Comment'), widget=forms.Textarea, max_length=COMMENT_MAX_LENGTH) comment_title = forms.CharField(max_length=256,label=_('标题')) parent_id = forms.IntegerField(min_value=-1,label=_('父评论的id')) level = forms.IntegerField(min_value=0,label=_('层级'),) . . . def get_comment_create_data(self, site_id=None): """ Returns the dict of data to be used to create a comment. Subclasses in custom comment apps that override get_comment_model can override this method to add extra fields onto a custom comment model. """ parent_id = self.cleaned_data['parent_id'] if parent_id <= 0: parent = None _level = self.cleaned_data['level'] else: parent = get_model().objects.get(id=parent_id) _level = self.cleaned_data['level'] + 4 # 4是缩进 return dict( content_type=ContentType.objects.get_for_model(self.target_object), object_pk=force_text(self.target_object._get_pk_val()), # user_name=self.cleaned_data["name"], # user_email=self.cleaned_data["email"], # user_url=self.cleaned_data["url"], comment_title = self.cleaned_data['comment_title'], parent_comment = parent, level = _level, comment=self.cleaned_data["comment"], submit_date=timezone.now(), site_id=site_id or getattr(settings, "SITE_ID", None), is_public=True, is_removed=False, )
(8)修改源码
django_comments/views/comments.py第97行表单
52行
# 添加 if not request.session.get('login', None) and not user_is_authenticated: return redirect("/")
116行
# if user_is_authenticated: # comment.user = request.user #添加 if request.session.get('login',None): comment.user_name = request.session['screen_name'] comment.user_img = request.session['profile_image_url']
以上都修改完后
python manage.py makemigtations python manage.py migrate
6.2.评论表单
detail.html
<div class="row"> <hr /> {% get_comment_form for entry as form %} {% get_comment_count for entry as comment_count %} <h3 >评论总数: {{ comment_count }}</h3> <hr /> </div> <div class="row"> <form class="form-horizontal" action="{% comment_form_target %}" method="post"> {% csrf_token %} <div class="form-group"> <label for="input_title" class="pull-left control-label">评论标题:</label> <div class="col-sm-6"> <input class="form-control" name="comment_title" id="input_title" placeholder="请输入标题" required /> </div> </div> <div class="form-group"> <label for="input_comment" class="pull-left control-label">评论内容:</label> <div class="col-sm-6"> <textarea style="resize:none;" class="form-control" rows=6 name="comment" id="input_comment" placeholder="在此输入评论" required></textarea> </div> </div> <span style="display: none;">{{ form.honeypot }}</span> {{ form.content_type }} {{ form.object_pk }} {{ form.timestamp }} {{ form.security_hash }} <input type="hidden" name="next" value="{% url 'blog:blog_detail' entry.id %}" /> <input name="parent_id" type="hidden" value="-1" /> <input name=" /> <div class="form-group col-sm-7"> <div class="pull-left" style="margin-left: 68px;"> <button type="reset" class="btn btn-default"><span class="glyphicon glyphicon-repeat"></span> 重置</button> </div> <div class="pull-right" style="margin-right: 12px;"> <button type="submit" class="btn btn-success" id="id_submit"><span class="glyphicon glyphicon-send"></span> 评论</button> </div> </div> </form> </div>
效果:
现在测试评论,可以添加成功,但是还不能显示
6.3.显示评论
(1)views.py
from django_comments.models import Comment def detail(request,blog_id): # entry = models.Entry.objects.get(id=blog_id) entry = get_object_or_404(models.Entry,id=blog_id) md = markdown.Markdown(extensions=[ 'markdown.extensions.extra', 'markdown.extensions.codehilite', 'markdown.extensions.toc', ]) entry.body = md.convert(entry.body) entry.toc = md.toc entry.increase_visiting() comment_list = list() def get_comment_list(comments): for comment in comments: comment_list.append(comment) children = comment.child_comment.all() if len(children) > 0: get_comment_list(children) top_comments = Comment.objects.filter(object_pk=blog_id, parent_comment=None, content_type__app_label='blog').order_by('-submit_date') get_comment_list(top_comments) return render(request, 'blog/detail.html', locals())
(2)detail.html
<div class="row"> <hr /> {% get_comment_form for entry as form %} {% get_comment_count for entry as comment_count %} <h3 >评论总数: {{ comment_count }}</h3> <hr /> </div> {# 评论表单#} {% if request.session.login or request.user.is_authenticated %} <div class="row"> <form class="form-horizontal" action="{% comment_form_target %}" method="post"> {% csrf_token %} <div class="form-group"> <label for="input_title" class="pull-left control-label">评论标题:</label> <div class="col-sm-6"> <input class="form-control" name="comment_title" id="input_title" placeholder="请输入标题" required /> </div> </div> <div class="form-group"> <label for="input_comment" class="pull-left control-label">评论内容:</label> <div class="col-sm-6"> <textarea style="resize:none;" class="form-control" rows=6 name="comment" id="input_comment" placeholder="在此输入评论" required></textarea> </div> </div> <span style="display: none;">{{ form.honeypot }}</span> {{ form.content_type }} {{ form.object_pk }} {{ form.timestamp }} {{ form.security_hash }} <input type="hidden" name="next" value="{% url 'blog:blog_detail' entry.id %}" /> <input name="parent_id" type="hidden" value="-1" /> <input name="level" type="hidden" value="0" /> <div class="form-group col-sm-7"> <div class="pull-left" style="margin-left: 68px;"> <button type="reset" class="btn btn-default"><span class="glyphicon glyphicon-repeat"></span> 重置</button> </div> <div class="pull-right" style="margin-right: 12px;"> <button type="submit" class="btn btn-success" id="id_submit"><span class="glyphicon glyphicon-send"></span> 评论</button> </div> </div> </form> </div> {% else %} <h3>登陆后才可以评论</h3> {% endif %} <hr /> {# 评论显示区#} <div class="row"> {% for comment in comment_list %} <div class="single_comment" style="margin-left: {{ comment.level }}em"> <div> {% if comment.user_img %} <img src="{{ comment.user_img }}" alt="user_image" /> {% else %} <img src="{% static 'blog/images/cl.jpg' %}" /> {% endif %} </div> <div class="col-md-11 comment-content" style="margin-bottom: 10px;"> <strong>{{ comment.comment_title }}</strong> <div> {% if comment.parent_comment %} {{ comment.user_name }}{{ request.user }} <i class="glyphicon glyphicon-share-alt"></i> {{ comment.parent_comment.user_name }}{{ request.user }} {% else %} By {{ comment.user_name }}{{ request.user }} On {% endif %} <em>{{ comment.submit_date }}</em> {% if request.session.login or request.user.is_authenticated %} <a href="#">回复</a> {% endif %} </div> <br /> <p>{{ comment.comment }}</p> </div> </div> {% endfor %} </div> </div>
(3)static/blog/images/cl.jpg
设置默认图片(如果没有登录就显示默认图片,为了测试评论)
(4)blog/blog_comment.css
hr { border-top: 1px solid lightgrey; border-bottom: 1px solid #fff; } .single_comment { margin-bottom: 20px; font-family: "Microsoft Yahei","微软雅黑",Arial,Helvetica,STHeiti,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; } .single_comment img { width:50px; height:50px; border-radius:50%; overflow:hidden; float: left; margin-left: 10px; margin-top: 5px; } .single_comment p { margin-bottom:; } .comment-content { border-bottom: 1px dashed lightgrey; border-left: 1px dashed #2d7da4; padding-bottom: 5px; }
detail.html引用
{% block css %} <link rel="stylesheet" href="{% static 'blog/css/github.css' %}"> <link rel="stylesheet" href="{% static 'blog/css/blog_comment.css' %}"> {% endblock %}
效果:
6.4.评论回复
(1)blog/urls.py
url(r'^reply/(?P<comment_id>\d+)/$', views.reply, name='comment_reply'),
(2)views.py
from django_comments import models as comment_models def reply(request, comment_id): if not request.session.get('login', None) and not request.user.is_authenticated(): return redirect('/') parent_comment = get_object_or_404(comment_models.Comment, id=comment_id) return render(request, 'blog/reply.html', locals())
(3)blog/reply.html
{% extends 'blog/base.html' %} {% load comments %} {% load static %} {% block title %}回复评论{% endblock %} {% block css %} <link rel="stylesheet" href="{% static 'blog/css/blog_comment.css' %}"> {% endblock %} {% block content %} <div class="container-fluid" style="margin: 30px 50px 0 50px;min-height: 450px;"> <div class="row"> <div class="single_comment"> <div> {% if request.session.login %} <img src="{{ parent_comment.user_img }}" alt="user_img" /> {% else %} <img src="{% static 'blog/images/cl.jpg' %}" alt="admin_img" /> {% endif %} </div> <div class="col-md-11"> <strong>{{ parent_comment.comment_title }}</strong> <div class="small"> <strong>{{ parent_comment.username }} {{ request.user }}</strong> <em>{{ parent_comment.submit_date }}</em> </div> <br /> <p>{{ parent_comment.comment }}</p> </div> </div> </div> <br /> {% if request.session.login or request.user.is_authenticated %} <div class="row" style="margin-left: 30px;"> <h3>回复 {{ parent_comment.username }}{{ request.user }} 的评论:</h3> {% get_comment_form for parent_comment.content_object as form %} <form class="form-horizontal" action="{% comment_form_target %}" method="post"> {% csrf_token %} <div class="form-group"> <label for="input_title" class="pull-left control-label">评论标题:</label> <div class="col-sm-6"> <input class="form-control" name="comment_title" id="input_title" placeholder="请输入标题" required /> </div> </div> <div class="form-group"> <label for="input_comment" class="pull-left control-label">评论内容:</label> <div class="col-sm-6"> <textarea style="resize:none;" class="form-control" rows=6 name="comment" id="input_comment" placeholder="在此输入评论" required></textarea> </div> </div> <span style="display: none;">{{ form.honeypot }}</span> {{ form.content_type }} {{ form.object_pk }} {{ form.timestamp }} {{ form.security_hash }} <input type="hidden" name="next" value="{% url 'blog:blog_detail' parent_comment.content_object.id %}" /> <input name="parent_id" type="hidden" value="{{ parent_comment.id }}" /> <input name="level" type="hidden" value="{{ parent_comment.level }}" /> <div class="form-group col-sm-7"> <div class="pull-left" style="margin-left: 68px;"> <button type="reset" class="btn btn-default"><span class="glyphicon glyphicon-repeat"></span> 重置</button> </div> <div class="pull-right" style="margin-right: 12px;"> <button type="submit" class="btn btn-success" id="id_submit"><span class="glyphicon glyphicon-send"></span> 评论</button> </div> </div> </form> </div> {% else %} <h3>登陆后才可以评论</h3> {% endif %} <br /> <div> <a href="{% url 'blog:blog_detail' parent_comment.content_object.id %}">暂时不评论,返回先前页面!</a> </div> </div> {% endblock %}
(4)detail.html
<a href="{% url 'blog:comment_reply' comment.id %}">回复</a>
测试回复功能如下:
Django+Bootstrap+Mysql 搭建个人博客(六)的更多相关文章
- Django+Bootstrap+Mysql 搭建个人博客(一)
1.1.环境搭建 (1)虚拟环境 mkvirtualenv website pip install django==1.11.7 (2)创建项目和app:website和blog (3)设置中文set ...
- Django+Bootstrap+Mysql 搭建个人博客(五)
5.1.自定义403,404和500页面 (1)website/urls.py from blog import views as blog_views handler403 = blog_views ...
- Django+Bootstrap+Mysql 搭建个人博客(四)
4.1.博客分类 (1)blog_tags.py @register.simple_tag def get_categories(): return Category.objects.all() @r ...
- Django+Bootstrap+Mysql 搭建个人博客(三)
3.1.分页功能 (1)views.py from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger def make ...
- Django+Bootstrap+Mysql 搭建个人博客(二)
2.1.博客首页设计 (1)settings.py MEDIA_ROOT = os.path.join(BASE_DIR,'media').replace("//","/ ...
- Django+Bootstrap+Mysql 搭建个人博客 (六)
6.1.comments插件 (1)安装 pip install django-contrib-comments (02)settings INSTALLED_APPS = [ 'django.con ...
- Python Web开发:Django+BootStrap实现简单的博客项目
创建blog的项目结构 关于如何创建一个Django项目,请查看[Python Web开发:使用Django框架创建HolleWorld项目] 创建blog的数据模型 创建一个文章类 所有开发都是数据 ...
- django入门--django-blog-zinnia搭建个人博客
1.安装python 选择合适python2.7及以上版本安装https://www.python.org/downloads/ 2.建立虚拟环境 这不是必须的,但是建议使用,为每个项目单独引入依赖, ...
- Django两天搭建个人博客
传送门:https://github.com/1417766861/django-blog(可直接运行,上面有步骤) 效果: 首页: 侧栏: 详情页面: 修改头像,资料,文章发布: 支持添加标签拖拽 ...
随机推荐
- android 获取Bitmap位图所占用的内存大小
今天在看Universal-Image-Loader源码的时候,在对图片的超过用户在所设的阈值的时候,系统会调用GC将LinkHashMap比较靠底层的图片引用去掉,这里涉及到一个技术单个图片的文图大 ...
- 使用schemaExport自动生成表结构
一.Hibernate原生状态 ? 1 2 3 4 5 Configuration cfg = new Configuration().configure(); SchemaExport expo ...
- 安卓TV开发(前言)— AndroidTV模拟器初识与搭建
原文:http://blog.csdn.net/sk719887916/article/details/39612577skay 前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居 ...
- listview中的adapter学习小结
概述 Adapter是数据和UI之间的一个桥梁,在listview,gridview等控件中都会使用到,android给我们提拱了4个adapte供我们使用: BaseAdapter是一个抽象类,继承 ...
- obj-c编程16:键值编码(KVC)
我们可以借助obj-c中的键值编码(以后简称KVC,Key-Value Coding)来存取类的属性,通过指定所要访问的属性名字符串标示符,可以使用存取器方法来获取或设置类的属性.下面的例子,借助于K ...
- AngularJS学习笔记之directive——scope选项与绑定策略
开门见山地说,scope:{}使指令与外界隔离开来,使其模板(template)处于non-inheriting(无继承)的状态,当然除非你在其中使用了transclude嵌入,这点之后的笔记会再详细 ...
- java程序的内存分配(一)
首 页 阅览室 馆友 我的图书馆 帐号 java程序的内存分配(一) 收藏 JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据J ...
- [总结] 二维ST表及其优化
二维 \(\mathcal{ST}\) 表,可以解决二维 \(\mathcal{RMQ}\) 问题.这里不能带修改,如果要修改,就需要二维线段树解决了. 上一道例题吧 ZOJ2859 类比一维 \(\ ...
- Ruby中如何复制对象 (deep clone)(转载)
Ruby中如何复制对象 (deep clone) 用Ruby复制一个对象(object)也许没有你想像的那么容易. 今天我google了半天, 做个总结吧. 先从最简单的开始, b = a 是复制吗? ...
- Java main方法全解
1.main方法的重载 package cn.nxl2018; public class Main_test { public static void main(String args[]) { Sy ...