上一节,我们讲述了怎么使用静态文件,并使用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自定义的表单对象,界面还是非常丑的,需要自己进行重新进行美化。

  

django开发简易博客(四)的更多相关文章

  1. django开发简易博客(一)

    这几篇博客是根据GoodSpeed的博客该写的,看了他的博客收获很大,但是他的博客从第三篇开始,条理很不清晰,加之又是几年之前写的,编写环境发生很大改变,所以对他的博客进行了一个整理,加入了一些自己的 ...

  2. django 开发简易博客(二)

    这一节我们来了解模板和视图.URL的使用. 一.使用模板 在blog目录中新建templates文件夹,在templates文件夹下新建base.html文件.目录结构如下 templates/ ba ...

  3. django开发简易博客(五)

    这一节将讲述如何添加comments库与ajax的支持. 一.添加comments库 comments库是是django框架内置的一个评论库,可以快速的搭建岀一个评论系统,不过再自定义方面有些麻烦,不 ...

  4. django开发简易博客(三)

    一.静态文件的使用 首先,新建static目录,目录下分别建立css.js.img三个子目录 修改settings.py文件 STATICFILES_DIRS = ( 'F:/web/static', ...

  5. Django搭建简易博客

    Django简易博客,主要实现了以下功能 连接数据库 创建超级用户与后台管理 利用django-admin-bootstrap美化界面 template,view与动态URL 多说评论功能 Markd ...

  6. Django开发个人博客入门学习经验贴

    [写在前面] 入门学习搭建个人博客系统首先还是参考大佬们的经验,记得刚入手Django的时候,一篇博客大佬说过一句话,做技术的不要一开始就扎头于细节中,先把握整体框架,了解这个对象之后再去了解细节,进 ...

  7. Django搭建简易博客教程(四)-Models

    原文链接: http://www.jianshu.com/p/dbc4193b4f95 Django Model 每一个Django Model都继承自django.db.models.Model 在 ...

  8. Django 搭建简易博客

    新增一个 APP 博客算是一个功能集,因此我们应将其体现为一个模块.这表现在 Django 应用里则是为其创建一个 APP Package.现在让 manage.py 中的 startapp 闪亮登场 ...

  9. 实战Django:简易博客Part1

    舍得学习新技能的时候,通常不喜欢傻读书--捧着一本阐述该项技能的书籍,然后傻看,一路看下来,脑子里塞满了新的概念.知识点,头是越来越大,但技能却几乎没掌握半分. 多年来,舍得养成了用做实例来学习新技能 ...

随机推荐

  1. JAVA GUI学习 - JPopupMenu鼠标右键菜单组件学习

    public class JPopmenuKnow { public void test() { //为表格添加鼠标右键菜单 JMenuItem jMenuItemFileInfo = new JMe ...

  2. uva 11137 Ingenuous Cubrency(完全背包)

    题目连接:11137 - Ingenuous Cubrency 题目大意:由21种规模的立方体(r 1~21),现在给出一个体积, 要求计算可以用多少种方式组成. 解题思路:完全背包, 和uva674 ...

  3. 全国三级城市联动 js版

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. 覆盖与重载与隐藏——SAP电面(3)

    参考:http://man.chinaunix.net/develop/c&c++/c/c.htm#_Toc520634042 8.2.1 重载与覆盖 成员函数被重载的特征: (1)相同的范围 ...

  5. 空类的默认函数—— SAP电面(2)/FEI

    定义一个空类 class Empty { }; 默认会生成以下几个函数 2. 拷贝构造函数 Empty(const Empty& copy) { } 3. 赋值运算符 Empty& o ...

  6. Jquery对select的操作(附日历天数变化代码)

    转载请注明出处. 逃不开传统的四种操作:增.删.改.查. <四处搜刮了jquery对select操作的代码,汇集一下,方便以后查看.日历天数变化代码为原创.> [增]: $("# ...

  7. [LeetCode]题解(python):135-Candy

    题目来源: https://leetcode.com/problems/candy/ 题意分析: 有N个孩子站成一条线.每个孩子有个排名.要求1.每个孩子至少一个糖果,2.相邻的孩子,那么较高排名的孩 ...

  8. [LeetCode]题解(python):007-Reverse Integer

    题目来源: https://leetcode.com/problems/reverse-integer/ 题意分析: 这道题目很简单,就是将一个数反转,123变321,-123变321. 题目思路: ...

  9. SIF与CIF

    SIF 动态图像专家组(MPEG)在1992年推出的MPEG-1标准中首次定义了SIF(Source Input Format,源输入格式).CCIR 601标准(现改为ITU-R BT.601标准) ...

  10. html文件中文在浏览器中显示乱码问题解决

    利用浏览器打开html文件时,中文显示乱码,如下是原文件的内容 1 <html>   2         <head>   3             <title> ...