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 相关文章推荐
Python2中的raw_input() 与 input()
Jun 12 Python
浅析Python中的多条件排序实现
Jun 07 Python
Python实现针对给定单链表删除指定节点的方法
Apr 12 Python
Centos 升级到python3后pip 无法使用的解决方法
Jun 12 Python
在mac下查找python包存放路径site-packages的实现方法
Nov 06 Python
python实现车牌识别的示例代码
Aug 05 Python
浅谈tensorflow中张量的提取值和赋值
Jan 19 Python
python3+openCV 获取图片中文本区域的最小外接矩形实例
Jun 02 Python
解决Keras使用GPU资源耗尽的问题
Jun 22 Python
python代码实现图书管理系统
Nov 30 Python
Python中OpenCV实现简单车牌字符切割
Jun 11 Python
详解Python如何批量采集京东商品数据流程
Jan 22 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
一个ftp类(ini.php)
2006/10/09 PHP
PHP模块 Memcached功能多于Memcache
2011/06/14 PHP
PHP 自定义错误处理函数的使用详解
2013/05/10 PHP
laravel中的fillable和guarded属性详解
2019/10/23 PHP
原生javascript兼容性测试实例
2013/07/01 Javascript
jQuery实现鼠标可拖动调整表格列宽度
2014/05/26 Javascript
node.js中实现同步操作的3种实现方法
2014/12/05 Javascript
对于jQuery性能的一些优化建议
2015/08/13 Javascript
Javascript中函数名.length属性用法分析(对比arguments.length)
2016/09/16 Javascript
JS使用正则截取两个字符串之间的字符串实现方法详解
2017/01/06 Javascript
JS 组件系列之BootstrapTable的treegrid功能
2017/06/16 Javascript
JS实现数组去重方法总结(六种方法)
2017/07/14 Javascript
Vue+Element使用富文本编辑器的示例代码
2017/08/14 Javascript
jQuery的时间datetime控件在AngularJs中的使用实例(分享)
2017/08/17 jQuery
vue 子组件向父组件传值方法
2018/02/26 Javascript
js代码规范之Eslint安装与配置详解
2018/09/08 Javascript
微信小程序使用scroll-view标签实现自动滑动到底部功能的实例代码
2018/11/09 Javascript
浅析Vue.js 中的条件渲染指令
2018/11/19 Javascript
vue在响应头response中获取自定义headers操作
2020/07/24 Javascript
JS实现购物车基本功能
2020/11/08 Javascript
js中延迟加载和预加载的具体使用
2021/01/14 Javascript
[02:03]DOTA2亚洲邀请赛 HGT战队出场宣传片
2015/02/07 DOTA
[34:39]DOTA2上海特级锦标赛主赛事日 - 4 败者组第四轮#1COL VS EG第二局
2016/03/05 DOTA
[52:08]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#2Fnatic VS OG第一局
2016/03/05 DOTA
Python连接mssql数据库编码问题解决方法
2015/01/01 Python
pyqt5、qtdesigner安装和环境设置教程
2019/09/25 Python
python爬虫要用到的库总结
2020/07/28 Python
武汉瑞得软件笔试题
2015/10/27 面试题
自荐书模板
2013/12/19 职场文书
基层工作经历证明
2014/01/13 职场文书
六查六看自查报告
2014/10/14 职场文书
乡镇群众路线整改落实情况汇报
2014/10/28 职场文书
2015年团委副书记工作总结
2015/07/23 职场文书
写一个Python脚本自动爬取Bilibili小视频
2021/04/24 Python
详解用Python把PDF转为Word方法总结
2021/04/27 Python
Go gRPC进阶教程gRPC转换HTTP
2022/06/16 Golang