3既然是博客,那肯定就有留言评论系统.在这一章就来建立一个评论系统.

1 创建一个模型来保存评论

2 创建一个表单来提交评论并且验证输入的数据

3 添加一个视图函数来处理表单和保存新的评论到数据库

4 编辑帖子模板来展示评论列表以及用来添加新评论的表单

首先来创建一个模型来存储评论

class Comment(models.Model):

post=models.ForeignKey(Post,related_name='comments')

name=models.CharField(max_length=80)

email=models.EmailField()

body=models.TextField()

created=models.DateTimeField(auto_now_add=True)

updated=models.DateTimeField(auto_now=True)

active=models.BooleanField(default=True)

class Meta:

ordering = ('created',)

def __str__(self):

return 'Comments by {} on {}'.format(self.name,self.post)

这就是我们增加评论的模型,其中最关键的是post,通过ForeignKey将Comment和Post关联了起来,关联关系是多对一,原因是一个博客是有多个评论的.定义好之后,我们就可以通过commens.post来取得对应的帖子.以及通过postcomments.all()来取回一个帖子所有的评论.如果你没有定义related_name属性,Django会使用这个模型(model)的名称加上*_set*(在这里是:comment_set)来命名从相关联的对象反向定位到这个对象的manager。

接下来完成数据迁移

zhf@zhf-maple:~/py_prj/mysite$ python manage.py makemigrations blog

Migrations for 'blog':

blog/migrations/0002_auto_20180303_1216.py

- Create model Comment

- Alter field author on post

- Alter field body on post

- Alter field created on post

- Alter field publish on post

- Alter field status on post

- Alter field title on post

- Alter field updated on post

- Add field post to comment

zhf@zhf-maple:~/py_prj/mysite$ python manage.py migrate

Operations to perform:

Apply all migrations: admin, auth, blog, contenttypes, sessions

Running migrations:

Applying blog.0002_auto_20180303_1216... OK

同步增加一个评论的管理并在后台进行注册admin.site.register(Comment,CommentAdmin)

class CommentAdmin(admin.ModelAdmin):

list_display = ('name','email','post','created','active')

list_filter = ('active','created','updated')

search_fields = ('name','email','body')

 

创建表单:

在这里的表单和前面的邮件分享不太一样,这里通过模型来创建表单

from .models import Comment

class CommentsForm(forms.ModelForm):

class Meta:

model=Comment

fields=('name','email','body')

根据模型(model)创建表单,我们只需要在这个表单的Meta类里表明使用哪个模型(model)来构建表单。Django将会解析model并为我们动态的创建表单。每一种模型(model)字段类型都有对应的默认表单字段类型。表单验证时会考虑到我们定义模型(model)字段的方式。Django为模型(model)中包含的每个字段都创建了表单字段。然而,使用fields 列表你可以明确的告诉框架你想在你的表单中包含哪些字段,或者使用exclude 列表定义你想排除在外的那些字段。对于我们的CommentForm来说,我们在表单中只需要name,email,和body字段,因为我们只需要用到这3个字段让我们的用户来填写。

视图中操作ModelForm

根据模型

def post_list_page(request):

object_list = Post.objects.all()

paginator = Paginator(object_list, 1)  # 3 posts in each page

page = request.GET.get('page')

new_comment = None

try:

posts = paginator.page(page)

comments=posts.object_list[0].comments.filter()

except PageNotAnInteger:

posts = paginator.page(1)

comments = posts.object_list[0].comments.filter()

except EmptyPage:

posts = paginator.page(paginator.num_pages)

id = posts.object_list[0].id

post = get_object_or_404(Post, id=id, status='published')

if request.method == 'POST':

comment_form = CommentsForm()

if comment_form.is_valid():

new_comment = comment_form.save(commit=False)

new_comment.post = post

new_comment.save()

else:

comment_form = CommentsForm()

return render(request,

'post/list.html',

{'page': page,

'posts': posts,

'comments':comments,

'new_comment': new_comment,

'comment_form': comment_form,

})

1 通过comments=posts.object_list[0].comments.filter()得到每个博客对应的评论实例

2 id = posts.object_list[0].id得到每个博客实例的id,并通过id得到Post实例

3 通过上传的CommentsForm表单数据将评论和博客连接起来

(1)我们通过调用这个表单的save()方法创建一个新的Comment对象

new_comment = comment_form.save(commit=False)

Save()方法创建了一个表单链接的model的实例,并将它保存到数据库中。如果你调用这个方法时设置commit=False,你创建的模型(model)实例不会即时保存到数据库中。当你想在最终保存之前修改这个model对象会非常方便,我们接下来将做这一步骤。save()方法是给ModelForm用的,而不是给Form实例用的,因为Form实例没有关联上任何模型(model)

为刚才的评论分配一个帖子

new_comment.post = post

(3) 最后,我们用下面的代码将新的评论保存到数据库中:

new_comment.save()

更新模板

既然帖子有了评论功能,现在我们需要修改我们的list模板来适应这个功能。需要呈现如下功能

1 评论总数

2 显示评论的列表

3 显示一个表单给用户来添加新的评论

前面视图传递的comments参数。通过with comments.count as total_comments语句将评论的个数传递给total_comments.这样就能显示具体有多少个评论

{% with comments.count as total_comments %}

<h2>

{{ total_comments }} comment{{ total_comments|pluralize }}

现在加入评论列表我们使用{% for %}模板(template)标签(tag)来循环所有的评论。如果comments列为空我们会显示一个默认的信息,告诉我们的用户这篇帖子还没有任何评论。我们使用 {{ forloop.counter }}变量来枚举所有的评论,在每次迭代中该变量都包含循环计数。之后我们显示发送评论的用户名,日期,和评论的内容。

{% for comment in comments %}

<div class="comment">

<p class="info">

Comment {{ forloop.counter }} by {{ comment.name }}

{{ comment.created }}

</p>

{{ comment.body|linebreaks }}

</div>

{% empty %}

<p>还没有评论</p>

{% endfor %}

最后,你需要渲染表单或者显示一条成功的信息来代替之前的内容。在之前的代码后面添加如下内容

{% if new_comment %}

<h2>Your comment has been added.</h2>

{% else %}

<h2>添加新评论</h2>

<form action="/blog/{{ p.id }}/comment/" method="post">

{{ comment_form.as_p }}

{% csrf_token %}

<input type="submit" value="增加评论">

</form>

{% endif %}

如果new_comment对象存在,我们会展示一条成功信息因为成功创建了一条新评论。否则,我们用段落<p>元素渲染表单中每一个字段

下面来测试下功能:

1 进入博客,此时还没有评论,因此显示0个评论。在下面有添加评论的界面

2在评论表单中填入信息,点击增加评论。成功的话显示评论已经添加成功的页面

3 此时在回到帖子的页面,可以看到添加的评论

Django之博客系统:增加评论的更多相关文章

  1. 纯django开发博客系统

    企业级教程:纯django开发博客系统 1.视频教程 https://www.duanshuilu.com/ 2.教程文档 https://www.duanshuilu.com/ 0.课程简介1.简价 ...

  2. Django(博客系统):基于pycharm如何一个django工程下创建多个app

    背景:通常我们创建一个django系统时,为了把业务模块划分清楚往往会把一个独立的业务模块放到一个app中,如果多个独立的业务模块就会创建多个app,一般情况下为了更好的管理这些app,会把他们都存放 ...

  3. Django练习——博客系统小试

    在上一篇博客Todolist的基础上(http://blog.csdn.net/hcx25909/article/details/24251427),本周继续进行实践,这次我要搭建一个简单的博客系统. ...

  4. python 全栈开发,Day83(博客系统子评论,后台管理,富文本编辑器kindeditor,bs4模块)

    一.子评论 必须点击回复,才是子评论!否则是根评论点击回复之后,定位到输入框,同时加入@评论者的用户名 定位输入框 focus focus:获取对象焦点触发事件 先做样式.点击回复之后,定位到输入框, ...

  5. 【django之博客系统开发】

    一.项目简介 使用django开发一套博客系统,参考博客园. 需求如下: 项目结构: 二.全部代码 from django.db import models # Create your models ...

  6. Django之博客系统邮件分享博客

    在上一章中,我们创建了一个基础的博客应用,我们能在http://127.0.0.1:8000/blog/显示我们的博客.在这一章我们将尝试给博客系统添加一些高级的特性,比如通过email来分享帖子,添 ...

  7. Django之博客系统搭建一

    前面已经介绍了django的各种用法,从这一章开始,将实际搭建一个blog系统. 首先我们需要设计blog的模型,在models.py中添加如下内容 # -*- coding: utf-8 -*- f ...

  8. Django之博客系统:增加标签

    一般在发表博客后会给每个帖子加上一个标签.类似帖子关键字的功能.在这一章中来看下如何给博客添加标签功能(tagging) 添加标签需要集成第三方的Django标签应用来完成这个功能.django-ta ...

  9. Django之博客系统:用户登陆

    使用django有一个好处就是有各种各样的框架可以拿来直接使用.相比flask,django自带的框架确实要多很多.比如这一章就要介绍的用户登录.Django拥有一个内置的认证(authenticat ...

随机推荐

  1. unix下网络编程之I/O复用(三)

    poll函数 在上文unix下网络编程之I/O复用(二)中已经介绍了select函数的相关使用,本文将介绍另一个常用的I/O复用函数poll.poll提供的功能与select类似,不过在处理流设备时, ...

  2. eclipse -- propedit 安装.

    SSH 项目中.用到国际化文件,Message.properties 但里面的文本都是 unicode 格式的,用起来不谁.而且也不想通过其它工具转码来使用. 可以通过安装 eclipse 的 pro ...

  3. 【转】LTE-NAS过程学习总结

    为了从网络得到非接入层服务,网络中非接入层节点必须知道有关UE的信息.为了这个目的,UE不得不发起附属过程,该过程是在UE开机和初始接入网络时必须被执行的. 一旦该过程成功,MME上就会建立好一个该U ...

  4. git学习4 常用命令

    1:更新: 更新后,更新只在Workspace中,没有到暂存区.git status可以查看当前状态. git add <file>  可以放到待提交区.      git  checko ...

  5. SQL属性第一个值不被选中,属性默认第一个值

    把 Please Choose Color 属性名设置为不可选的 UPDATE `products_attributes` SET `attributes_display_only` = '1' WH ...

  6. Rails:Rails使用sqlite3数据库 及数据操作基本命令

    Rails默认使用sqlite3做为数据库,虽然很多人更喜欢mysql.但如果是学习用,sqlite3够了,因为它轻量,不需要安装. 首先对sqlite3做个简短的介绍:1.sqlite3不需要配置, ...

  7. PDM生成数据库-0设置表名和字段名中不带双引号

    如果PDM直接导出脚本的话,所有的表和字段都会被加上双引号,非常不方便,去除双引号的办法: Database->Edit Current DBMS在弹出窗体中第一项General中找到 Scri ...

  8. DAY16-Django之model

    Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据 ...

  9. 使用myeclipse开发Servlet

    1.在myeclipse中创建一个web工程 2.在src目录下建立一个包并建立一个Servlet(myeclipse会自把Servlet映射到web.xml文件中) 3.发布工程,实际上就是把web ...

  10. Python 面向对象 (进阶篇)

    <Python 面向对象(初级篇)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可 ...