ORM之模型层表操作(Fields)字段

注解

从技术上讲,这些方法都被定义在 django.db.models.fields,但为了方便,它们被导入到 django.db.models;标准的惯例是使用 from django.db import models 并利用 models.Field

一 字段名命名限制

Fields字段被指定为模型类的属性,是模型最重要的部分,也是模型唯一必须要有的部分,是用来定义数据库字段的。

Django 对字段的命名设置了一些限制:

1、注意字段名不要选择与模型API冲突的名字,如clean、save或delete等

2、字段名不能是Python保留字,因为这将导致Python语法错误。例如:

1
2
class Example(models.Model):
pass = models.IntegerField() # 'pass'是保留字

3、由于Django 查询语法的工作方式,所以字段名称中连续的下划线不能超过两个。 例如:

1
2
class Example(models.Model):
foo__bar = models.IntegerField() # 'foo__bar'有两个下划线

4、出于类似的原因,字段名不能以下划线结尾。

上述只是针对模型字段的限制,并不是针对数据库列的限制,我们的模型字段名与数据库列名并不是匹配的,可以用db_column字段指定数据库名

1
2
3
class Example(models.Model):
aaa=models.CharField(max_length=10,db_column='aaa__aaa')
bbb=models.CharField(max_length=10,db_column='bbb_')

5、SQL 的保留字例如select、where 和join,可以用作模型的字段名,因为Django 会对底层的SQL 查询语句中的数据库表名和列名进行转义。 它根据你的数据库引擎使用不同的引用语法。

二 字段类型

字段类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
##1、BigAutoField
int自增列,必须填入参数 primary_key=True。你通常不需要直接使用它,当model中如果没有自增列,则自动会创建一个列名为id的列。
Changed in Django 3.2:
在旧版本中,自动创建的主键字段总是 AutoField。

##2、IntegerField
一个整数类型,范围在 -2147483648 to 2147483647

##3、CharField
字符类型,必须提供max_length参数, max_length表示字符长度。

##4、DateField
日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。

##5、DateTimeField
日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例

示例

1
2
3
4
5
6
7
8
9
10
11
12
from django.db import models

class Musician(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
instrument = models.CharField(max_length=100)

class Album(models.Model):
artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
release_date = models.DateField()
num_stars = models.IntegerField()
  • 更多详见:

附录1:常用字段和非常用字段合集

三 字段选项和参数

每个字段都有一组特定于该字段的参数。例如字段CharField(及其子类)必须定义一个max_length参数,该参数指定用于存储数据的VARCHAR数据库字段的大小,这部分参数参考官网或提示指定即可。

我们主要讨论一下可用于所有字段类型的公共参数,当然,所有的都是可选的

  • 1、null: 如果为True,Django将在数据库中将空值存储为NULL。默认值为False。
  • 2、blank: 如果为True,则该字段允许为空。默认值为False。

注意,这与null不同。null纯粹与数据库相关,而blank则与验证相关。如果字段的blank=True,则表单验证将允许输入空值。如果字段为空=假,则该字段是必需的。

  • 3、unique: 如果为True,该字段必须是唯一的

  • 4、db_index:如果db_index=True 则代表着为此字段设置索引。

  • 5、db_column

指定数据对应的字段名 name = models.CharField(max_length=64, db_column=‘book_name’)

默认字段名为name,指定db_column后,数据库表字段名为book_name

  • 6、choices

用于指定一个二元组,如果给定了此选项,则admin界面默认表单小部件将是一个选择框,而不是标准文本字段,并且将选择限制为给定的选项,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from django.db import models

class Person(models.Model):
# 每个元组的第二个元素用来在amdin管理界面显示,而第一个元素才是被存入数据库中的值
SHIRT_SIZES = (
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
)
name = models.CharField(max_length=60)
shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)


>>> p = Person(name="Fred Flintstone", shirt_size="L")
>>> p.save()
>>> p.shirt_size
'L'
>>> p.get_shirt_size_display() # 可以使用get_FOO_display()方法访问具有选项的字段的显示值
'Large'
  • 7、default 字段的默认值。这可以是值或可调用对象。如果可调用,则每次创建新对象时都将调用它。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from django.db import models

def func():
print('from func')

class Person(models.Model):
SHIRT_SIZES = (
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
)
name = models.CharField(max_length=60,null=True,default=func)
shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)

## 首先我们设置null=True,default=函数
## 然后执行,当插入值为空时,会使用默认值,如果此时默认值为函数,则会触发函数的执行
>>> p = Person()
from func
>>> p.save()
  • 8、auto_now_add

针对 DateField和DateTimeField可以设置auto_now_add=True,新增对象时会自动添加当前时间

1
create_time=models.DateTimeField(auto_now_add=True) # 只针对创建,不针对修改
  • 9、auto_now

针对 DateField和DateTimeField可以设置auto_now=True,新增或修改对象都会自动填充当前时间

1
modify_time=models.DateTimeField(auto_now=True) # 针对创建以及修改都有效

强调:选项auto_now、auto_now_add和default是互斥的。只能有一个。

  • 10、help_text, 用于在admin管理界面显示的额外“帮助”文本。它对于文档很有用 name = models.CharField(max_length=60,null=True,default=func,help_text=‘哈哈哈哈哈’)
  • 11、primary_key

如果为True,那么这个字段就是模型的主键。

主键字段是只读的。 如果你在一个已存在的对象上面更改主键的值并且保存,一个新的对象将会在原有对象之外创建出来。 例如:

1
2
3
4
5
from django.db import models

class Fruit(models.Model): name = 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)

如果你没有指定任何一个字段的primary_key=True,Django 就会自动添加一个IntegerField 字段做为主键,所以除非你想覆盖默认的主键行为,否则没必要设置任何一个字段的primary_key=True。 详见下一小节

四 自动主键字段

默认情况下,django自动会为每个模型创建一个主键字段,这种自动的行为称之为隐式创建

1
id = models.AutoField(primary_key=True)

如果我们想自定义主键,需要为你的某一个字段指定参数primary_key=True,这种自定义行为称之为显式创建 如果django看到你已经自定义了主键,它将不会自动创建id字段啦

每个模型只需要一个字段使primary_key=True(显式声明或隐式添加)。

五 设置字段的自述名字

除ForeignKey、ManyToManyField和OneToOneField外,每种字段类型都采用可选的第一个位置参数作为详细名称。如果没有指定要显示的详细名称,Django将使用字段的属性名称自动创建它,并将下划线转换为空格。

如下 admin管理界面字段显示的详细名称为:“person’s first name”

1
2
first_name = models.CharField("person's first name", max_length=30)
## first_name = models.CharField(name="person's first name", max_length=30)

如下,字段显示的详细名字为: “first name”:

1
first_name = models.CharField(max_length=30)

针对ForeignKey、ManyToManyField和OneToOneField字段,第一个参数必须为模型类,如果要设置字段显示的详细名字,需要指定参数verbose_name,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from django.db import models

class Person(models.Model):
SHIRT_SIZES = (
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
)
name = models.CharField('用户名',max_length=60,null=True,help_text='哈哈哈')
role=models.ForeignKey(to='Role',verbose_name='权限选择',on_delete=models.CASCADE,null=True)

class Role(models.Model):
PRIVS = (
(0, 'superuser'),
(1, 'user'),
(2, 'visitor'),
)

role=models.CharField('角色',max_length=20)
priv=models.IntegerField('权限',choices=PRIVS)

约定俗称不会将详细名称的第一个字母大写,django会在需要的地方自动将第一个字母大写

六 建立表关系

涉及到字段ForeignKey、ManyToManyField、OneToOneField的使用,详见下一小节