通过数据库向Django模型添加字段的示例

首先借用书本(book)的这个数据模型:

from django.db import models

class Publisher(models.Model):
  name = models.CharField(max_length=30)
  address = models.CharField(max_length=50)
  city = models.CharField(max_length=60)
  state_province = models.CharField(max_length=30)
  country = models.CharField(max_length=50)
  website = models.URLField()

  def __unicode__(self):
    return self.name

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

  def __unicode__(self):
    return u'%s %s' % (self.first_name, self.last_name)

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

  def __unicode__(self):
    return self.title


添加字段
当要向一个产品设置表(或者说是model)添加一个字段的时候,要使用的技巧是利用Django不关心表里是否包含model里所没有的列的特性。 策略就是现在数据库里加入字段,然后同步Django的模型以包含新字段。

然而 这里有一个鸡生蛋蛋生鸡的问题 ,由于要想了解新增列的SQL语句,你需要使用Django的 manage.py sqlall命令进行查看 ,而这又需要字段已经在模型里存在了。 (注意:你并 不是非得使用与Django相同的SQL语句创建新的字段,但是这样做确实是一个好主意 ,它能让一切都保持同步。)

这个鸡-蛋的问题的解决方法是在开发者环境里而不是发布环境里实现这个变化。 (你正使用的是测试/开发环境,对吧?)下面是具体的实施步骤。

首先,进入开发环境(也就是说,不是在发布环境里):

在你的模型里添加字段。

运行 manage.py sqlall [yourapp] 来测试模型新的 CREATE TABLE 语句。 注意为新字段的列定义。

开启你的数据库的交互命令界面(比如, psql 或mysql , 或者可以使用 manage.py dbshell )。 执行 ALTER TABLE 语句来添加新列。

使用Python的manage.py shell,通过导入模型和选中表单(例如, MyModel.objects.all()[:5] )来验证新的字段是否被正确的添加 ,如果一切顺利,所有的语句都不会报错。

然后在你的产品服务器上再实施一遍这些步骤。

启动数据库的交互界面。

执行在开发环境步骤中,第三步的ALTER TABLE语句。

将新的字段加入到模型中。 如果你使用了某种版本控制工具,并且在第一步中,已经提交了你在开发环境上的修改,现在,可以在生产环境中更新你的代码了(例如,如果你使用Subversion,执行svn update。

重新启动Web server,使修改生效。

让我们实践下,比如添加一个num_pages字段到第五章中Book模型。首先,我们会把开发环境中的模型改成如下形式:

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

  def __unicode__(self):
    return self.title

然后,我们运行命令manage.py sqlall books 来查看CREATE TABLE语句。 语句的具体内容取决与你所使用的数据库, 大概是这个样子:

CREATE TABLE "books_book" (
  "id" serial NOT NULL PRIMARY KEY,
  "title" varchar(100) NOT NULL,
  "publisher_id" integer NOT NULL REFERENCES "books_publisher" ("id"),
  "publication_date" date NOT NULL,
  "num_pages" integer NULL
);

新加的字段被这样表示:

"num_pages" integer NULL

接下来,我们要在开发环境上运行数据库客户端,如果是PostgreSQL,运行 psql,,然后,我执行如下语句。

ALTER TABLE books_book ADD COLUMN num_pages integer;

添加 非NULL 字段

这里有个微妙之处值得一提。 在我们添加字段num_pages的时候,我们使用了 blank=True 和 null=True 选项。 这是因为在我们第一次创建它的时候,这个数据库字段会含有空值。

然而,想要添加不能含有空值的字段也是可以的。 要想实现这样的效果,你必须先创建 NULL 型的字段,然后将该字段的值填充为某个默认值,然后再将该字段改为 NOT NULL 型。 例如:

BEGIN;
ALTER TABLE books_book ADD COLUMN num_pages integer;
UPDATE books_book SET num_pages=0;
ALTER TABLE books_book ALTER COLUMN num_pages SET NOT NULL;
COMMIT;

如果你这样做,记得你不要在模型中添加 blank=True 和 null=True 选项。

执行ALTER TABLE之后,我们要验证一下修改结果是否正确。启动python并执行下面的代码:

>>> from mysite.books.models import Book
>>> Book.objects.all()[:5]

如果没有异常发生,我们将切换到生产服务器,然后在生产环境的数据库中执行命令ALTER TABLE 然后我们更新生产环境中的模型,最后重启web服务器。

(0)

相关推荐

  • Django1.7+python 2.78+pycharm配置mysql数据库教程

    配置好virtualenv 和virtualenvwrapper后,使用pycharm创建新项目.之后要面临的问题就来了,之前一直使用的是sqlite作为开发数据库进行学习,按照之前看教程的原则,好像就是说开发环境要和生产环境尽量的一致,所以现在想尝试一下使用更有可能在生产环境部署的mysql数据库进行开发. 本觉得是一件应该很轻松的事情,没想到遇到了一些麻烦 根据一通百度,搜出来的方案大概有: MySQLdb mysql安装时候自带的connector pymysql MySQLdb 是dja

  • 在Python的Django框架中更新数据库数据的方法

    先使用一些关键参数创建对象实例,如下: >>> p = Publisher(name='Apress', ... address='2855 Telegraph Ave.', ... city='Berkeley', ... state_province='CA', ... country='U.S.A.', ... website='http://www.apress.com/') 这个对象实例并 没有 对数据库做修改. 在调用`` save()`` 方法之前,记录并没有保存至数据库,

  • Python的Django框架中的数据库配置指南

    记住这些理念之后,让我们来开始 Django 数据库层的探索. 首先,我们需要做些初始配置:我们需要告诉Django使用什么数据库以及如何连接数据库. 我们假定你已经完成了数据库服务器的安装和激活,并且已经在其中创建了数据库(例如,用 CREATE DATABASE 语句). 如果你使用SQLite,不需要这步安装,因为SQLite使用文件系统上的独立文件来存储数据. 象前面章节提到的 TEMPLATE_DIRS 一样,数据库配置也是在Django的配置文件里,缺省 是 settings.py

  • 用实例详解Python中的Django框架中prefetch_related()函数对数据库查询的优化

    实例的背景说明 假定一个个人信息系统,需要记录系统中各个人的故乡.居住地.以及到过的城市.数据库设计如下: Models.py 内容如下: from django.db import models class Province(models.Model): name = models.CharField(max_length=10) def __unicode__(self): return self.name class City(models.Model): name = models.Ch

  • 在Django的视图中使用数据库查询的方法

    在视图中也有笨方法可以从数据库中获取数据. 很简单: 用现有的任何 Python 类库执行一条 SQL 查询并对结果进行一些处理. 在本例的视图中,我们使用了 MySQLdb 类库(可以从 http://www.djangoproject.com/r/python-mysql/ 获得)来连接 MySQL 数据库,取回一些记录,将它们提供给模板以显示一个网页: from django.shortcuts import render_to_response import MySQLdb def bo

  • 通过数据库对Django进行删除字段和删除模型的操作

    删除字段 从Model中删除一个字段要比添加容易得多. 删除字段,仅仅只要以下几个步骤: 删除字段,然后重新启动你的web服务器. 用以下命令从数据库中删除字段: ALTER TABLE books_book DROP COLUMN num_pages; 请保证操作的顺序正确. 如果你先从数据库中删除字段,Django将会立即抛出异常. 删除多对多关联字段 由于多对多关联字段不同于普通字段,所以删除操作是不同的. 从你的模型中删除ManyToManyField,然后重启web服务器. 用下面的命

  • Python的Django框架中使用SQLAlchemy操作数据库的教程

    零.SQLAlchemy是什么? SQLAlchemy的官网上写着它的介绍文字: SQLAlchemy is the Python SQL toolkit and Object Relational Mapper that gives application developers the full power and flexibility of SQL. SQLAlchemy 是一个非常强大的ORM和数据库工具,但是它庞大的文档和复杂的功能总是让很 多人望而生畏.而Django的ORM相对来说

  • Django使用多数据库的方法

    有些项目可能涉及到使用多个数据库的情况,方法很简单. 1.在settings中设定DATABASE 比如要使用两个数据库: DATABASES = { 'default': { 'NAME': 'app_data', 'ENGINE': 'django.db.backends.postgresql', 'USER': 'postgres_user', 'PASSWORD': 's3krit' }, 'users': { 'NAME': 'user_data', 'ENGINE': 'django

  • 通过数据库向Django模型添加字段的示例

    首先借用书本(book)的这个数据模型: from django.db import models class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30)

  • Django模型中字段属性choice使用说明

    今天设计models时,用到了choice这个属性,用来限制用户做出选择的范围.比如说性别的选择(男或女). class User(AbstractUser): ... sex = models.CharField(verbose_name='性别',max_length=5,choices=(('male','男'),('female','女')),default='male') choice接收一个元组(保证值不可变),同理每一个选项也是由一个元组(value,display_name)构成

  • 对django 模型 unique together的示例讲解

    unique_together 这个元数据是非常重要的一个!它等同于数据库的联合约束! 举个例子,假设有一张用户表,保存有用户的姓名.出生日期.性别和籍贯等等信息.要求是所有的用户唯一不重复,可现在有好几个叫"张伟"的,如何区别它们呢?(不要和我说主键唯一,这里讨论的不是这个问题) 我们可以设置不能有两个用户在同一个地方同一时刻出生并且都叫"张伟",使用这种联合约束,保证数据库能不能重复添加用户(也不要和我谈小概率问题).在Django的模型中,如何实现这种约束呢?

  • Postgresql数据库中的json类型字段使用示例详解

    目录 1. Json概述 2. Postgresql数据库中使用Json类型字段 2.1. 创建表定义字段信息 2.2. 增加 2.3. 查询键值 2.3.1. 查询键 2.3.2. 查询值 2.3.3. where查询条件使用json键值作为条件 PostgreSQL 最重要的文档性数据类型就是JSON了,与 MongoDB 的BSON相比较,PostgreSQL 或许更加强大,因为它能与原有的关系性范式兼容,给数据库存储与维护带来了更多的可行性和便利性. 1. Json概述 JSON 代表

  • 利用信号如何监控Django模型对象字段值的变化详解

    django信号系统 django自带一套信号发射系统来帮助我们在框架的不同位置传递信息.也就是说,当某一事件发生时,信号系统可以允许一个或多个发送者(senders)将通知或信号(signals)推送给一组接受者(receivers).信号系统在我们多处代码与同一个事件相关是特别有用. 既然是信号系统,那么必须包含以下要素: 1. 发送者-谁发送了信号 2. 信号-发送的信号本身 3. 接收者-信号是发给谁的 Django 信号 (Signals) 的功能类似于 WordPress 的动作 (

  • access数据库用sql语句添加字段,修改字段,删除字段

    以下就是示例: 用 DDL 的 Create Table 建立一个表 Table1 ,主键是自动编号字段,另一个字段是长度是 10 的文本字段. 复制代码 代码如下: CREATE TABLE Table1 (Id COUNTER CONSTRAINT PrimaryKey PRIMARY KEY, MyText TEXT (10)) 再建一个包含两个字段的表 Table2,字段 id 为长整型,字段 MyText 为文本 复制代码 代码如下: CREATE TABLE Table2 (Id L

  • django模型动态修改参数,增加 filter 字段的方式

    我就废话不多说啦,还是直接看代码吧! kwargs = { # 动态查询的字段 } # 选择deleted_datetime为空的记录 if exclude_deleted: kwargs[ 'deleted_datetime__isnull' ] = True # 选择特的category if category is not None: kwargs[ 'category' ] = category # 特定的用户 if current_user_only: kwargs[ 'user' ]

  • ASP.NET MVC4入门教程(七):给电影表和模型添加新字段

    在本节中,您将使用Entity Framework Code First来实现模型类上的操作.从而使得这些操作和变更,可以应用到数据库中. 默认情况下,就像您在之前的教程中所作的那样,使用 Entity Framework Code First自动创建一个数据库,Code First为数据库所添加的表,将帮助您跟踪数据库是否和从它生成的模型类是同步的.如果他们不是同步的,Entity Framework将抛出一个错误.这非常方便的在开发时就可以发现错误,否则您可能会在运行时才发现这个问题. (由

  • 解决django model修改添加字段报错的问题

    关于django models中添加字段的一个小节,记录下 django的models中已经写好了字段,可是后面我又想在添加一些字段,于是就在models中添加了字段 ,发现报错了 报错的类型: 字段重复了 不知道的列 : 最后解决的方法 : 到models的目录下打开文件 ,直接把所需的字段添加到第一次编译的文件中 , 重新执行数据库的迁移 ,如果依然有报错,提示有未知的列 ,就查看数据库 ,那个列缺失,就把列给添加上 添加未知的列 至此,重新执行迁移 ,妥妥的成功了 ! 以上这篇解决djan

随机推荐