上一节,我们讲述了怎么使用静态文件,并使用bootstrap对页面进行了美化,这一节我们将增强我们blog的功能,添加发表博客,删除博客的功能。
一.表单的使用
要实现添加blog的功能,就得使用表单。
Django带有一个form库,称为django.forms,这个库可以处理我们本章所提到的包括HTML表单显示以及验证。当然我们现在有两个选择
- 自己写,完成表单显示以及验证
- 使用django提供的From
首先修改blog目录下urls.py,添加
url(r'^blog/add/$','blog_add',name='addblog'),
在blog目录下新建forms.py文件
from django import froms
class BlogForm(forms.Form):
caption = forms.CharField(label = 'title' , max_length = 100)
content = forms.CharField(widget = forms.Textarea)
tag_name = forms.CharField()
新建blog_add.html
{% extends "blog_base.html" %} {% block title %} 发表博客 {% endblock %} {% block article %} <form action="" method="post"> {% csrf_token %} <div> <label for="id_caption">Title: </label> {% if form.caption.errors %} <div class="alert alert-error"> {{ form.caption.errors }} </div> {% endif %} {{ form.caption }} </div> <div > <label for="id_content">Content: </label> {% if form.content.errors %} <div class="alert alert-error"> {{ form.content.errors }} </div> {% endif %} {{ form.content }} </div> <div> <label for="id_tag">tags</label> {% if tag.tag_name.errors %} <div class="alert alert-error"> {{ tag.tag_name.errors }} </div> {% endif %} {{ tag.tag_name }} </div> <div> <input class="btn btn-primary" type="submit" value="save and add"> </div> </form> {% endblock %}
在views.py中添加红色部分
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.template import RequestContext
from blog.models import Blog ,Tag ,Author
from django.http import Http404
from blog.forms import BlogForm ,TagForm
def blog_list(request):
blogs = Blog.objects.all()
tags =Tag.objects.all()
return render_to_response("blog_list.html", {"blogs": blogs,"tags":tags})
def blog_show(request, id=''):
try:
blog = Blog.objects.get(id=id)
except Blog.DoesNotExist:
raise Http404
return render_to_response("blog_show.html", {"blog": blog})
def blog_filter(request,id=''):
tags = Tag.objects.all()
tag = Tag.objects.get(id=id)
blogs = tag.blog_set.all()
return render_to_response("blog_filter.html",{"blogs":blogs,"tag":tag,"tags":tags})
def blog_add(request):
if request.method == 'POST':
form = BlogForm(request.POST)
tag = TagForm(request.POST)
if form.is_valid() and tag.is_valid():
cd = form.cleaned_data
cdtag = tag.cleaned_data
tagname = cdtag['tag_name']
for taglist in tagname.split():
Tag.objects.get_or_create(tag_name=taglist.strip())
title = cd['caption']
author = Author.objects.get(id=1)
content = cd['content']
blog = Blog(caption=title, author=author, content=content)
blog.save()
for taglist in tagname.split():
blog.tags.add(Tag.objects.get(tag_name=taglist.strip()))
blog.save()
id = Blog.objects.order_by('-publish_time')[0].id
return HttpResponseRedirect('/web/blog/%s' % id)
else:
form = BlogForm()
tag = TagForm(initial={'tag_name': 'notags'})
return render_to_response('blog_add.html',
{'form': form, 'tag': tag}, context_instance=RequestContext(request))
使用 form的is_valid()方法,验证它的数据是否合法,如果一个Form实体的数据是合法的,它就会有一个可用的cleaned_data属性。 这是一个包含干净的提交数据的字典。
这里我们默认作者是id=1,当然你也可以自己修改或者根据登录的session读取
博客提交后 使用HttpResponseRedirect 跳转到最新发表的博客页面
因为我们使用的是post ,所以必须在表单后面添加 {% csrf_token %},然后在视图中使用 context_instance=RequestContext(request)。
重新编辑blog_list.html,在其中添加:
{% extends "blog_base.html" %} {% block title %} 博文列表 {% endblock %} {% block article %} <article class='content'> {% for blog in blogs %} <h4><a href="{% url 'detailblog' blog.id %}">{{blog.caption}}</a></h4> <p class="muted"> {% for tag in blog.tags.all %} <span class="glyphicon glyphicon-tag"></span><small>{{tag}}</small> {% endfor %} </p> <div class="row"> <div class="col-md-3"> <span class="glyphicon glyphicon-time"></span><small> {{ blog.publish_time }}</small> </div> <div class="col-md-2 col-md-offset-7"> </div> </div> <hr> {% endfor %} </article> {% endblock %} {% block aside %}
<!--此处添加发表新博客的按钮--!> <a href="{% url 'addblog' %}" class="btn"> <span class="glyphicon glyphicon-plus">发表新的博客</a> {% block tags %} <div class="well"> {% for tag in tags %} <span class="label"><a href="{% url 'filterblog' tag.id %}">{{tag}}</a></span> {% endfor %} </div> {% endblock %} {% endblock %}
二.编辑博客
在blog目录下的urls.py中添加
url(r'^blog/update/(?P<id>w+)/$', 'blog_update',name='updateblog'),
因为更新和编辑的表单相同,所以使用跟blog_add.html作为模板
在views.py中添加如下内容
def blog_update(request, id=""): id = id if request.method == 'POST': form = BlogForm(request.POST) tag = TagForm(request.POST) if form.is_valid() and tag.is_valid(): cd = form.cleaned_data cdtag = tag.cleaned_data tagname = cdtag['tag_name'] tagnamelist = tagname.split() for taglist in tagnamelist: Tag.objects.get_or_create(tag_name=taglist.strip()) title = cd['caption'] content = cd['content'] blog = Blog.objects.get(id=id) if blog: blog.caption = title blog.content = content blog.save() for taglist in tagnamelist: blog.tags.add(Tag.objects.get(tag_name=taglist.strip())) blog.save() tags = blog.tags.all() for tagname in tags: tagname = unicode(str(tagname), "utf-8") if tagname not in tagnamelist: notag = blog.tags.get(tag_name=tagname) blog.tags.remove(notag) else: blog = Blog(caption=blog.caption, content=blog.content) blog.save() return HttpResponseRedirect('/sblog/blog/%s' % id) else: try: blog = Blog.objects.get(id=id) except Exception: raise Http404 form = BlogForm(initial={'caption': blog.caption, 'content': blog.content}, auto_id=False) tags = blog.tags.all() if tags: taginit = '' for x in tags: taginit += str(x) + ' ' tag = TagForm(initial={'tag_name': taginit}) else: tag = TagForm() return render_to_response('blog_add.html', {'blog': blog, 'form': form, 'id': id, 'tag': tag}, context_instance=RequestContext(request))
在blog_list.html中添加(红色部分)
<div class="row"> <div class="col-md-3"> <span class="glyphicon glyphicon-time"></span><small> {{ blog.publish_time }}</small> </div> <div class="col-md-2 col-md-offset-7"> <a href="{% url 'updateblog' blog.id %}" title="edit"> <span class="glyphicon glyphicon-edit"></span> </a> </div> </div>
在blog_show.html中添加(红色部分)
<div class="col-md-2 col-md-offset-7"> <a href="{% url 'updateblog' blog.id %}" title="edit"> <span class="glyphicon glyphicon-edit"></span> </a> </div>
同样,在blog_filter.html中添加以上内容。
三.删除文章
修改blog目录下的urls.py,添加
url(r'^blog/del/(?P<id>w+)/$', 'blog_del', name='delblog'),
修改views.py添加
def blog_del(request, id=""): try: blog = Blog.objects.get(id=id) except Exception: raise Http404 if blog: blog.delete() return HttpResponseRedirect("/web/bloglist/") blogs = Blog.objects.all() return render_to_response("blog_list.html", {"blogs": blogs})
在blog_list.list 、blog_show.html、blog_filter.html中添加红色加粗部分代码
<div class="col-md-2 col-md-offset-7"> <a href="{% url 'updateblog' blog.id %}" title="edit"> <span class="glyphicon glyphicon-edit"></span> </a> <a href="{% url 'delblog' blog.id %}" title="delete"> <span class="glyphicon glyphicon-trash"></span> </a> </div>
这样一个具有增删改的博客站点就完成了,但是我们可以看到使用django自定义的表单对象,界面还是非常丑的,需要自己进行重新进行美化。