Wolf从零学编程-用Django撸个Blog(六)

来源:互联网 发布:js获取相同class的div 编辑:程序博客网 时间:2024/05/26 08:41

按照计划,这一篇把评论功能添加到博客里。

实现思路

  • 编写评论的数据库表model
  • 将评论与文章关联
  • 编写评论表单form
  • 设置评论发表后的URL
  • 编写发表评论的视图view
  • 美化评论的排版template

Model

参考多数网站,评论系统需要展示以下信息:
- 昵称
- 内容
- 评论时间

为和文章关联,还需要一个article属性。

# models.pyclass Comment(models.Model):    username = models.CharField('昵称',max_length=10)    content = models.TextField('评论内容')    created_time = models.DateTimeField('评论时间',auto_now_add=True)    article = models.ForeignKey(Article,verbose_name='文章',on_delete=models.CASCADE)    def __str__(self):        return self.content[:25]

所有外键属性(ForeignKey)都最好设置on_delete属性,设为models.SET_NULL表示删除某个文章(外键)则其下所有评论的外键设为null,设为models.CASCADE则表示删除文章后,会把其下所有评论都删除,这是默认设置。

当然,对数据库改动后,少不了两行命令:

python manage.py makemigrations blogpython manage.py migrate

Forms

当需要由网页输入信息提交至服务器时,就要用到表单,比如常见的登录、注册、评论等功能。关于表单,可以参阅官方文档Forms或中文文档。

博客的评论表单可以由评论模型生成,使用forms的ModelForm。首先在blog的文件夹里创建forms.py模块,并导入models。

# forms.pyfrom django import formsfrom .models import Article,Commentclass CommentForm(forms.ModelForm):    class Meta:    '''设置Meta'''        model = Comment #设置表单form关联的模型model        fields = ('username','content') #设置在模板中渲染的字段

URL

# urls.pyurlpatterns = [    url(r'^$',views.IndexView.as_view(),name='index'),    ...    url(r'^article/(?P<article_id>\d+)/comment/$',views.CommentView.as_view(),name='comment'),]

View

django中也有表单处理的通用视图FormView,使用此视图数据有效时会定向到所指定渲染的模板,数据无效时会重新显示表单并带有错误提示。

# views.py**from django.http import HttpResponseRedirect**from django.shortcuts import render,**get_object_or_404**from django.views.generic import ListView,DetailView,**FormView****from .forms import CommentForm**class CommentView(FormView):    form_class = CommentForm    template_name = 'blog/detail.html'    #指定评论提交后渲染的模板文件    #评论成功后返回文章详情页    def form_valid(self,form):        #从当前url获取被评论的文章        target_article = get_object_or_404(Article,pk=self.kwargs['article_id'])        #返回生成实例,暂不保存评论        comment = form.save(commit=False)        comment.article = target_article #将评论与文章关联        comment.save()        # 用Article中定义的方法获取重定向的URL        self.success_url = target_article.get_absolute_url()        return HttpResponseRedirect(self.success_url)

代码中get_absolute_url()是在Article的模型中新增的方法,作用是获取当前文章的url。

# models.py**from django.core.urlresolvers import reverse**#创建文章模型class Article(models.Model):    ...    #新增方法,得到当前文章的url,用于CommentView    def get_absolute_url(self):        return reverse('blog:detail',kwargs={'article_id':self.pk})

同时,要把评论表单添加进ArticleView中,以在详情页渲染评论表单。

# views.pyclass ArticleView(DetailView):    ...    #把评论form添加到context    def get_context_data(self,**kwargs):        kwargs['comment_list'] = self.object.comment_set.all()        kwargs['form'] = CommentForm()        return super(ArticleView,self).get_context_data(**kwargs)

只需要再创建一个comment.html,并将其包含在detail.html中就可以了。

# comment.html<html><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><body><hr /><h1>Comment</h1><form method="post" action="{% url 'blog:comment' article.pk %}">    {% csrf_token %}    {% for field in form %}        {{ field }}        <br>        <br>    {% endfor %}<button type="submit">Submit</button></form><hr />{% for comment in comment_list %}    {{ comment.username }}    {{ comment.created_time }}    {{ comment.content }}<a href="">Reply</a><hr />{% endfor %}</body></html># detail.html<html><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><head><title>文章详情</title></head><body><h1 style='color:blue;'>    <a href=" {% url 'blog:index' %}">首页</a></h1><h3>{{article.title}}</h3>{{article.text|safe}}<br />**{% include 'blog/comment.html' %}**</body></html>

除了comment.html里写不了中文,其他运行起来妥妥的,截图如下:

mark


这个画面实在让我提不起兴趣了,所以最近要专攻几天JS和CSS,之后的计划是:
- 画面美化
- 添加前端写博客的功能
- 添加一下如点赞、评论数、回复评论、归档等功能
- 后台添加一些方便管理的功能

0 0