上一节,我们讲述了怎么使用静态文件,并使用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. qwtplot3D安装——终结解决方案(YOUYOU版)

    转自CSDN: 首先不得不说,要感谢北京邮电大学的阿科.感谢他慷慨的分享和极具科学态度的记录,将自己搜集到的众多资料收集整理发布,拯救众多苦逼寻找方案的程序员于苦海之中.因为最近接手新的项目,涉及到使 ...

  2. POJ 3693 Maximum repetition substring(后缀数组+ST表)

    [题目链接] poj.org/problem?id=3693 [题目大意] 求一个串重复次数最多的连续重复子串并输出,要求字典序最小. [题解] 考虑错位匹配,设重复部分长度为l,记s[i]和s[i+ ...

  3. 基于xml文件实现系统属性配置管理

    文章标题:基于xml文件实现系统属性配置管理 . 文章地址: http://blog.csdn.net/5iasp/article/details/11774501 作者: javaboy2012 E ...

  4. Zoie Merge Policy

    Zoie有一个ZoieMergePolicy如若价格值不是特别的.这是为lucene早期的版本号merge在不考虑删除doc会计并加以改进,和LogMergePolicy只是做同样的也合并相邻节段,而 ...

  5. iOS中Block介绍 基础

    ios开发block的使用指南,以及深入理解block的内存管理,也适用于osx开发.讨论范围:block的使用,内存管理,内部实现.不包含的内容:gc arc下的block内存,block在c++中 ...

  6. raphael入门到精通---入门篇之总览

    什么是Raphael raphael.js是一小巧的javascript库,它可以在web上画矢量图简化你的工作,如果你想创建你指定的图表,图形区域或者可移动的组件,那么就使用raphael吧 话不多 ...

  7. DropDownList为啥总是获取第一项的值???

    小菜: DropDownList控件绑定的数据,在获取数据时总是获取到第一项,很是郁闷,怎么回事,于是就各种想,都没有找到问题的原因. 请看下面的代码 前台代码: <asp:DropDownLi ...

  8. 汉字转拼音的vc++程序源代码

    #include "StdAfx.h" #include "MyChiToLetter.h" // Download by http://www.codefan ...

  9. p95 3.5、3.8

    3.5  有一农夫带一条狼,一只羊和一筐菜欲从河的左岸乘船到右岸,但受下列条件限制:(1)船太小,农夫每次只能带一样东西过河:(2)如果没有农夫看管,则狼要吃羊,羊要吃菜.请设计一个过河方案,是的农夫 ...

  10. 跳出for循环

    如下面,有两个循环,break只能退出一个for循环,不能直接跳过第二个for循环 for (Type type : types) { for (Type t : types2) { if (some ...