模型
模型是你的数据的唯一的、权威的信息源。它包含你所储存数据的必要字段和行为。通常,每个模型对应数据库中唯一的一张表。
基础:
每个模型都是django.db.models.Model 的一个Python 子类。
模型的每个属性都表示为数据库中的一个字段。
Django 提供一套自动生成的用于数据库访问的API;详见执行查询。
实例:
#-*- coding:utf-8-*-
from django.db import models
class Person(models.Model):
pname = models.CharField('姓名',max_length=20)
page = models.ImageField('年龄')
每个字段都被指定成一个类属性,每个属性映射到一个数据库的列。
使用下面命令可以查看在数据库中生成的表:
python manage.py sqlmigrate app1 0001
生成的SQL语句如下:
CREATE TABLE "app1_person" ("id" integer NOT PRIMARY KEY AUTOINCREMENT,"pname" verchar(20) NOT NULL,"page" integer NOT NULL)
一些技术上的注意事项:
- 这个表的名称app1_person,是根据模型中的元数据自动生成的,也可以重写为别的名称.
- id 字段是自动添加的,但这个行为可以被重写。
- 这个例子中的CREATE TABLE SQL 语句使用sqlite3语法格式,要注意的是Django会根据设置文件中指定的数据库类型来使用相应的SQL语句。
使用模型
定义好模型之后,接下来你需要告诉Django 使用这些模型。你要做的就是修改配置文件中的INSTALLED_APPS 设置,在其中添加models.py所在应用的名称。
例如,如果你的应用的模型位于app1.models(由manage.py startapp 命令自动创建的结构),INSTALLED_APPS部分看上去应该是:
INSTALLED_APPS = (
#...
'app1',
#...
)
当你在INSTALLED_APPS 中添加新的应用名时,请确保运行命令manage.py migrate,可以事先使用manage.py makemigrations 给应用生成迁移脚本。
字段
对于一个模型来说,最重要的和不可或缺的是列出该模型在数据库中定义的字段。字段由models类属性指定。要注意选择的字段名称不要和模型 API 冲突,比如clean、save 或者delete。
例如:
#-*- coding:utf-8-*-
from django.db import models
class Musician(models.Model):
frist_name = models.CharField(max_ength = 50)
last_name = models.CharField(max_ength = 50)
instrument = models.CharField(max_ength = 50)
class Album(models.Model):
artist = models.ForeignKey(Musician)
name = models.CharField(max_ength = 100)
release_date = models.DateField()
num_stars = models.IntegerField()
字段类型
模型中的每个字段都是 Field 子类的某个实例。Django 根据字段类的类型确定以下信息:
- 数据库当中的列类型 (比如: INTEGER, VARCHAR)。
- 渲染表单时使用的默认HTML 部件(例如,, )。
最低限度的验证需求,它被用在 Django 管理站点和自动生成的表单中。
Django 自带数十种内置的字段类型;完整字段类型列表可以在模型字段参考 中找到。如果内置类型仍不能满足你的要求,你可以自由地编写符合你要求的字段类型
字段选项
每个字段有一些特有的参数,详见模型字段参考。例如,CharField(和它的派生类)需要max_length 参数来指定VARCHAR 数据库字段的大小。
还有一些适用于所有字段的通用参数。 这些参数在参考中有详细定义,这里我们只简单介绍一些最常用的:
- null:如果为True,Django 将会把数据库中空值保存为NULL。默认值是 False.
blank:如果为True,该字段允许为空值,默认为False。
要注意,这与 null 不同。null纯粹是数据库范畴,指数据库中字段内容是否允许为空,而 blank 是表单数据输入验证范畴的。如果一个字段的blank=True,表单的验证将允许输入一个空值。如果字段的blank=False,该字段就是必填的。choices:由二项元组构成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,默认的表单将是一个选择框而不是标准的文本框,而且这个选择框的选项就是choices 中的选项。
这是一个关于 choices 列表的例子:
YEAR_IN_SCHOOL_CHOICES = (
('FR','Freshman'),
('SO','Sophomore'),
('JR','Junior'),
('SR','Senior'),
('GR','Graduate'),
)
每个元组中的第一个元素,是存储在数据库中的值;第二个元素是在管理界面或 ModelChoiceField 中用作显示的内容。 在一个给定的 model 类的实例中,想得到某个 choices 字段的显示值,就调用 get_FOO_display 方法(这里的 FOO 就是 choices 字段的名称 )。例如:
#-*- coding:utf-8-*-
from django.db import models
class Person(models.Model):
SHIRT_SIZES = (
('S','Small'),
('M','Medium'),
('L','Large')
)
name = models.CharField(max_length=60)
shirt_size = models.CharField(max_length=1,choice=SHIRT_SIZES)
>>>p = Person(name='Fred Flintstone',shirt_size='L')
>>>p.save()
>>>p.shrit_size
'L'
>>>p.get_shrit_size_display()
'Large'
- default:字段的默认值。可以是一个值或者可调用对象。如果可调用 ,每个新对象被创建它都会被调用。
- help_text:表单部件额外显示的帮助内容。即使字段不在表单中使用,它对生成文档也很有用。
- primary_key:如果为True,那么这个字段就是模型的主键。
如果你没有指定任何一个字段的primary_key=True,Django 就会自动添加一个IntegerField 字段做为主键,所以除非你想覆盖默认的主键行为,否则没必要设置任何一个字段的primary_key=True。详见自增主键字段。
主键字段是只读的。如果你在一个已存在的对象上面更改主键的值并且保存,一个新的对象将会在原有对象之外创建出来。例如:
#-*- coding:utf-8-*-
from django.db import models
class Fruit(models.Model):
pname = models.CharField(max_length=100,primary_key=True)
>>>fruit = Fruit.objects.create(name='Apple')
>>>fruit.name = 'pear'
>>>fruit.save()
>>>Fruit.objects.values_list('name',flat=True)
['Apple','Pear']
unique:如果该值设置为 True, 这个数据字段在整张表中必须是唯一的
字段的自述名
除ForeignKey、ManyToManyField 和 OneToOneField 之外,每个字段类型都接受一个可选的位置参数(在第一的位置) —— 字段的自述名。如果没有给定自述名,Django 将根据字段的属性名称自动创建自述名 —— 将属性名称的下划线替换成空格。
在这个例子中,自述名是 “person’s pname ,page”:
ForeignKey、ManyToManyField 和 OneToOneField 都要求第一个参数是一个模型类,所以要使用 verbose_name 关键字参数才能指定自述名:
poll = models.ForeignKey(Poll,verbose_name='the related poll')
sites = models.ManyToManyField(Site,verbose_name='list of sites')
place = models.OneToOneField(place,verbose_name='related place')
关系
显然,关系数据库的威力体现在表之间的相互关联。 Django 提供了三种最常见的数据库关系:多对一(many-to-one),多对多(many-to-many),一对一(one-to-one)。
多对一关系
Django 使用 django.db.models.ForeignKey 定义多对一关系。和使用其它字段类型一样:在模型当中把它做为一个类属性包含进来。
ForeignKey 需要一个位置参数:与该模型关联的类。
比如,一辆汽车(Car)有一个制造商(Manufacturer) —— 但是一个制造商(Manufacturer) 生产很多汽车(Car),每一辆汽车(Car) 只能有一个制造商(Manufacturer) —— 使用下面的定义:
#-*- coding:utf-8-*-
from django.db import models
class Manufacturer(models.Model):
#...
pass
class Car(models.Model):
manufacturer = models.ForeignKey(Manufacturer)
#...
你还可以创建递归的关联关系(对象和自己进行多对一关联)和 与尚未定义的模型的关联关系;详见模型字段参考。
建议你用被关联的模型的小写名称做为ForeignKey 字段的名字(例如,上面manufacturer)。当然,你也可以起别的名字。例如:
class Car(models.Model):
company_that_makes_it = models.ForeignKey(Manufacturer)
#...