Python的Django框架中设置日期和字段可选的方法


Posted in Python onJuly 17, 2015

设置字段可选

在摆弄了一会之后,你或许会发现管理工具有个限制:编辑表单需要你填写每一个字段,然而在有些情况下,你想要某些字段是可选的。 举个例子,我们想要Author模块中的email字段成为可选,即允许不填。 在现实世界中,你可能没有为每个作者登记邮箱地址。

为了指定email字段为可选,你只要编辑Book模块(回想第五章,它在mysite/books/models.py文件里),在email字段上加上blank=True。代码如下:

class Author(models.Model):
  first_name = models.CharField(max_length=30)
  last_name = models.CharField(max_length=40)
  email = models.EmailField(**blank=True** )

这些代码告诉Django,作者的邮箱地址允许输入一个空值。 所有字段都默认blank=False,这使得它们不允许输入空值。

这里会发生一些有趣的事情。 直到现在,除了__unicode__()方法,我们的模块充当数据库中表定义的角色,即本质上是用Python的语法来写CREATE TABLE语句。 在添加blank=True过程中,我们已经开始在简单的定义数据表上扩展我们的模块了。 现在,我们的模块类开始成为一个富含Author对象属性和行为的集合了。 email不但展现为一个数据库中的VARCHAR类型的字段,它还是页面中可选的字段,就像在管理工具中看到的那样。

当你添加blank=True以后,刷新页面Add author edit form (http://127.0.0.1:8000/admin/books/author/add/ ),将会发现Email的标签不再是粗体了。 这意味它不是一个必填字段。 现在你可以添加一个作者而不必输入邮箱地址,即使你为这个字段提交了一个空值,也再不会得到那刺眼的红色信息“This field is required”。
设置日期型和数字型字段可选

虽然blank=True同样适用于日期型和数字型字段,但是这里需要详细讲解一些背景知识。

SQL有指定空值的独特方式,它把空值叫做NULL。NULL可以表示为未知的、非法的、或其它程序指定的含义。

在SQL中, NULL的值不同于空字符串,就像Python中None不同于空字符串("")一样。这意味着某个字符型字段(如VARCHAR)的值不可能同时包含NULL和空字符串。

这会引起不必要的歧义或疑惑。 为什么这条记录有个NULL,而那条记录却有个空字符串? 它们之间有区别,还是数据输入不一致? 还有: 我怎样才能得到全部拥有空值的记录,应该按NULL和空字符串查找么?还是仅按字符串查找?

为了消除歧义,Django生成CREATE TABLE语句自动为每个字段显式加上NOT NULL。 这里有个生成Author模块的例子:

CREATE TABLE "books_author" (
  "id" serial NOT NULL PRIMARY KEY,
  "first_name" varchar(30) NOT NULL,
  "last_name" varchar(40) NOT NULL,
  "email" varchar(75) NOT NULL
)
;

在大多数情况下,这种默认的行为对你的应用程序来说是最佳的,因为它可以使你不再因数据一致性而头痛。 而且它可以和Django的其它部分工作得很好。如在管理工具中,如果你留空一个字符型字段,它会为此插入一个空字符串(而* 不是*NULL)。

但是,其它数据类型有例外:日期型、时间型和数字型字段不接受空字符串。 如果你尝试将一个空字符串插入日期型或整数型字段,你可能会得到数据库返回的错误,这取决于那个数据库的类型。 (PostgreSQL比较严禁,会抛出一个异常;MySQL可能会也可能不会接受,这取决于你使用的版本和运气了。)在这种情况下,NULL是唯一指定空值的方法。 在Django模块中,你可以通过添加null=True来指定一个字段允许为NULL。

因此,这说起来有点复杂: 如果你想允许一个日期型(DateField、TimeField、DateTimeField)或数字型(IntegerField、DecimalField、FloatField)字段为空,你需要使用null=True * 和* blank=True。

为了举例说明,让我们把Book模块修改成允许 publication_date为空。修改后的代码如下:

class Book(models.Model):
  title = models.CharField(max_length=100)
  authors = models.ManyToManyField(Author)
  publisher = models.ForeignKey(Publisher)
  publication_date = models.DateField(**blank=True, null=True** )

添加null=True比添加blank=True复杂。因为null=True改变了数据的语义,即改变了CREATE TABLE语句,把publication_date字段上的NOT NULL删除了。 要完成这些改动,我们还需要更新数据库。

出于某种原因,Django不会尝试自动更新数据库结构。所以你必须执行ALTER TABLE语句将模块的改动更新至数据库。 像先前那样,你可以使用manage.py dbshell进入数据库服务环境。 以下是在这个特殊情况下如何删除NOT NULL:

ALTER TABLE books_book ALTER COLUMN publication_date DROP NOT NULL;

(注意:以下SQL语法是PostgreSQL特有的。)

我们将在第十章详细讲述数据库结构更改。

现在让我们回到管理工具,添加book的编辑页面允许输入一个空的publication date。

Python 相关文章推荐
python网络编程学习笔记(九):数据库客户端 DB-API
Jun 09 Python
跟老齐学Python之用while来循环
Oct 02 Python
web.py在SAE中的Session问题解决方法(使用mysql存储)
Jun 24 Python
Python2.7+pytesser实现简单验证码的识别方法
Dec 29 Python
Python模块WSGI使用详解
Feb 02 Python
Python给定一个句子倒序输出单词以及字母的方法
Dec 20 Python
Python turtle绘画象棋棋盘
Aug 21 Python
python基于socket实现的UDP及TCP通讯功能示例
Nov 01 Python
tensorflow的计算图总结
Jan 12 Python
在 Linux/Mac 下为Python函数添加超时时间的方法
Feb 20 Python
Django 解决开发自定义抛出异常的问题
May 21 Python
查看keras各种网络结构各层的名字方式
Jun 11 Python
Python的Django框架下管理站点的基本方法
Jul 17 #Python
Django中更新多个对象数据与删除对象的方法
Jul 17 #Python
Django框架中数据的连锁查询和限制返回数据的方法
Jul 17 #Python
Django中对数据查询结果进行排序的方法
Jul 17 #Python
在Python的Django框架中获取单个对象数据的简单方法
Jul 17 #Python
Python的Django框架中的数据过滤功能
Jul 17 #Python
在Python的Django框架中更新数据库数据的方法
Jul 17 #Python
You might like
ajax php 实现写入数据库
2009/09/02 PHP
关于session在PHP5的配置文件中的详细设置参数说明
2011/04/20 PHP
通过PHP的Wrapper无缝迁移原有项目到新服务的实现方法
2020/04/02 PHP
Javascript 陷阱 window全局对象
2008/11/26 Javascript
JavaScript实现统计文本框Textarea字数增强用户体验
2012/12/21 Javascript
js history对象简单实现返回和前进
2013/10/30 Javascript
javascript结合Canvas 实现简易的圆形时钟
2015/03/11 Javascript
React.js入门学习第一篇
2016/03/30 Javascript
JS代码实现百度地图 画圆 删除标注
2016/10/12 Javascript
javascript中数组(Array)对象和字符串(String)对象的常用方法总结
2016/12/15 Javascript
微信小程序开发经验总结(推荐)
2017/01/11 Javascript
jQuery使用bind动态绑定事件无效的处理方法
2018/12/11 jQuery
玩转Koa之koa-router原理解析
2018/12/29 Javascript
使用webpack搭建pixi.js开发环境
2020/02/12 Javascript
elementui更改el-dialog关闭按钮的图标d的示例代码
2020/08/04 Javascript
Python脚本实现集群检测和管理功能
2015/03/06 Python
Python中用sleep()方法操作时间的教程
2015/05/22 Python
python 文件操作删除某行的实例
2017/09/04 Python
python2.7 json 转换日期的处理的示例
2018/03/07 Python
在Python 字典中一键对应多个值的实例
2019/02/03 Python
基于MSELoss()与CrossEntropyLoss()的区别详解
2020/01/02 Python
python实现将列表中各个值快速赋值给多个变量
2020/04/02 Python
基于Python中random.sample()的替代方案
2020/05/23 Python
pycharm远程连接服务器并配置python interpreter的方法
2020/12/23 Python
Python 的 f-string 可以连接字符串与数字的原因解析
2021/02/20 Python
远程调用的原理
2014/07/05 面试题
驾驶员岗位职责
2014/01/29 职场文书
社区居务公开实施方案
2014/03/27 职场文书
党支部换届选举方案
2014/05/08 职场文书
十八大宣传标语
2014/10/09 职场文书
有限公司股东合作协议书
2014/10/29 职场文书
普通党员群众路线教育实践活动心得体会
2014/11/04 职场文书
迟到检讨书
2015/01/26 职场文书
社区文明创建工作总结2015
2015/04/21 职场文书
实战 快速定位MySQL的慢SQL
2022/03/22 MySQL
Oracle 11g数据库使用expdp每周进行数据备份并上传到备份服务器
2022/06/28 Oracle