Python工程师详细讲解Django之model
2017-12-27 20:57
627 查看
一大波model操作
model的功能:创建数据库表、操作数据库表、数据验证(弱)
关于自定义表名
下面是一个创建表的的类:
1
2
3
这样默认生成的表名为app名称+下划线+类名这里即:app01_user
如果想要更改默认的表名,可以通过db_table参数实现,并且必须在 class Meta类下写,代码更改为更改为:
1
2
3
4
5
关于索引
按照之前的方式我们会这样创建表:
1
2
3
4
5
这样就会在本地生成两个文件来保存索引
联合索引
这里可以通过创建联合索引index_together从而生成一个文件,代码如下:
1
2
3
4
5
6
7
8
联合索引的特点:
最左前缀
上面代码中生成索引是("user","pwd")是name在前面,所以这样会导致:
select * fromuserwhere user= "zhaofan" 可以命中索引
select * fromuserwhere user= "zhaofan" and pwd= "123" 可以命中索引
select * fromuserwhere pwd= "123" 这种查询时则无法命中索引
所以联合索引的就会导致只有加上最左边的索引值时索引才能起作用,这里的name在最左边,所以查询时条件中有name时索引才能命中
联合唯一索引
unique_together = (("name", "pwd"),)
表示("name","pwd")的组合是唯一的
多表操作及参数
一对多
下面是创建一对多的类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
如果数据库中已经有用户属于每个usertype,这样当我们通过下面方式删除usertype表中的数据时:
UserType.objects.filter(id=1).delete()
Django1.10之后不会报错,并且默认还会把属于usertype的用户user也删除
这里ForeignKey有几个参数:
to 要进行关联的表名
to_field 要关联的表中的字段名称
on_delete 当删除关联表中的数据时,当前表与其关联的行的行为
- models.CASCADE,删除关联数据,与之关联也删除
- models.DO_NOTHING,删除关联数据,引发错误IntegrityError(这个错误是数据库提示的错误)
- models.PROTECT,删除关联数据,引发错误ProtectedError(这个错误是Django提示的错误)
- models.SET_NULL,删除关联数据,与之关联的值设置为null(前提该字段需要设置为可空)
- models.SET_DEFAULT,删除关联数据,与之关联的值设置为默认值(前提该字段需要设置默认值)
- models.SET,删除关联数据
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象即函数)
关于正向查找
model中的代码如下:
1
2
3
4
5
6
7
8
9
10
在views函数中写如下代码:
1
2
3
即正常的通过models.User.objects.all().values("user","ut__name"),就可以实现跨表
当然也可以通过下面方式实现跨表查询:
v2 = models.User.objects.all()
for i in v2:
print(i.ut.id,i.ut.name)
关于反向查找
通过v3 = models.UserType.objects.all().values("name","user__user")同样能够实现反向跨表查询
同样也可以通过for循环实现反向查询的跨表
v4 = models.UserType.objects.all()
for i in v4:
print(i.name,i.user_set.name)
这里的反向操作都需要用另外一张的表名_set__列名或者表名__列名
这里可以实现自定制related_name
在models里设置表结构的时候:
1
2
3
4
5
6
7
8
这样再次获取的时候就可以通过related_name值获取:
v3 = models.UserType.objects.all().values("name","cc__user")这种方式和
3 = models.UserType.objects.all().values("name","user__user")结果是一样的
这里还有一个参数叫related_query_name
反向操作时,使用的连接前缀,用于替换“表名__set”中的“表名”,如果related_query_name=“aa”,则反向查找是可以通过aa_set查找
在Django admin中用到的参数
limit_choices_to
通过limit_choices_to,在Admin或ModelForm中显示关联数据时,提供的条件
如下图所示usertype中有四个类型:
如果不做任何设置,添加用户时应该也能看到四个类型如下图:
在代码中通过limit_choices_to={"id__gt":2},可以修改显示的个数
1
2
3
4
5
6
7
8
9
db_constraint=True # 是否在数据库中创建外键约束
parent_link=False # 在Admin中是否显示关联数据
一对一OnetoOneField
OneToOneField(ForeignKey)
OneToOneField继承ForeignKey
所以同样有
to, # 要进行关联的表名
to_field=None # 要关联的表中的字段名称
on_delete=None, # 当删除关联表中的数据时,当前表与其关联的行的行为
当两个类之间有继承关系时,默认会创建一个一对一的字段
多对多ManyToManyField
常见的参数:
to, # 要进行关联的表名
related_name# 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
related_query_name=None, # 反向操作时,使用的连接前缀,用于替换【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
limit_choices_to # 在Admin或ModelForm中显示关联数据时,提供的条件
特殊参数:
symmetrical=None,
仅用于多对多自关联时,symmetrical用于指定内部是否创建反向操作的字段
做如下操作时,不同的symmetrical会有不同的可选字段
symmetrical=True:
class BB(models.Model):
code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=True)
这个时候可选字段有:code,id,m1
symmetrical=Falses时:
class BB(models.Model):
code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=False)
这个时候可选字段有:code,id,m1,bb
其实这个时候发反向查询没有多大意义,毕竟这里是多丢多的自关联
创建对多的三种方式
第一种:让django自动创建第三张表,即通过models.ManyToManyField
1
2
3
4
5
这样就可以通过
models.Blog.m.add
models.Blog.m.update
models.Blog.m.clear
models.Blog.m.all
models.Blog.m.create
……
第二种方式:手动创建第三张表
1
2
3
4
5
6
7
8
9
model的功能:创建数据库表、操作数据库表、数据验证(弱)
关于自定义表名
下面是一个创建表的的类:
1
2
3
class
User(models.Model):
user
=
models.CharField(max_length
=
32
)
pwd
=
models.CharField(max_length
=
64
)
这样默认生成的表名为app名称+下划线+类名这里即:app01_user
如果想要更改默认的表名,可以通过db_table参数实现,并且必须在 class Meta类下写,代码更改为更改为:
1
2
3
4
5
class
User(models.Model):
user
=
models.CharField(max_length
=
32
)
pwd
=
models.CharField(max_length
=
64
)
class
Meta:
db_table
=
"user"
关于索引
按照之前的方式我们会这样创建表:
1
2
3
4
5
class
User(models.Model):
user
=
models.CharField(max_length
=
32
,db_index
=
True
)
pwd
=
models.CharField(max_length
=
64
,db_index
=
True
)
class
Meta:
db_table
=
"user"
这样就会在本地生成两个文件来保存索引
联合索引
这里可以通过创建联合索引index_together从而生成一个文件,代码如下:
1
2
3
4
5
6
7
8
class
User(models.Model):
user
=
models.CharField(max_length
=
32
)
pwd
=
models.CharField(max_length
=
64
)
class
Meta:
db_table
=
"user"
index_together
=
[
(
"user"
,
"pwd"
)
]
联合索引的特点:
最左前缀
上面代码中生成索引是("user","pwd")是name在前面,所以这样会导致:
select * fromuserwhere user= "zhaofan" 可以命中索引
select * fromuserwhere user= "zhaofan" and pwd= "123" 可以命中索引
select * fromuserwhere pwd= "123" 这种查询时则无法命中索引
所以联合索引的就会导致只有加上最左边的索引值时索引才能起作用,这里的name在最左边,所以查询时条件中有name时索引才能命中
联合唯一索引
unique_together = (("name", "pwd"),)
表示("name","pwd")的组合是唯一的
多表操作及参数
一对多
下面是创建一对多的类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class
UserType(models.Model):
name
=
models.CharField(max_length
=
32
)
class
User(models.Model):
user
=
models.CharField(max_length
=
32
,db_index
=
True
)
pwd
=
models.CharField(max_length
=
64
,db_index
=
True
)
class
Meta:
db_table
=
"user"
index_together
=
[
(
"name"
,
"pwd"
)
]
ut
=
models.ForeignKey(
to
=
"UserType"
,
to_field
=
"id"
,
)
如果数据库中已经有用户属于每个usertype,这样当我们通过下面方式删除usertype表中的数据时:
UserType.objects.filter(id=1).delete()
Django1.10之后不会报错,并且默认还会把属于usertype的用户user也删除
这里ForeignKey有几个参数:
to 要进行关联的表名
to_field 要关联的表中的字段名称
on_delete 当删除关联表中的数据时,当前表与其关联的行的行为
- models.CASCADE,删除关联数据,与之关联也删除
- models.DO_NOTHING,删除关联数据,引发错误IntegrityError(这个错误是数据库提示的错误)
- models.PROTECT,删除关联数据,引发错误ProtectedError(这个错误是Django提示的错误)
- models.SET_NULL,删除关联数据,与之关联的值设置为null(前提该字段需要设置为可空)
- models.SET_DEFAULT,删除关联数据,与之关联的值设置为默认值(前提该字段需要设置默认值)
- models.SET,删除关联数据
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象即函数)
关于正向查找
model中的代码如下:
1
2
3
4
5
6
7
8
9
10
class
UserType(models.Model):
name
=
models.CharField(max_length
=
32
)
class
User(models.Model):
user
=
models.CharField(max_length
=
32
)
pwd
=
models.CharField(max_length
=
64
)
ut
=
models.ForeignKey(
to
=
"UserType"
,
to_field
=
"id"
,
)
在views函数中写如下代码:
1
2
3
def
index(request):
v1
=
models.User.objects.
all
().values(
"user"
,
"ut__name"
)
return
HttpResponse(v1)
即正常的通过models.User.objects.all().values("user","ut__name"),就可以实现跨表
当然也可以通过下面方式实现跨表查询:
v2 = models.User.objects.all()
for i in v2:
print(i.ut.id,i.ut.name)
关于反向查找
通过v3 = models.UserType.objects.all().values("name","user__user")同样能够实现反向跨表查询
同样也可以通过for循环实现反向查询的跨表
v4 = models.UserType.objects.all()
for i in v4:
print(i.name,i.user_set.name)
这里的反向操作都需要用另外一张的表名_set__列名或者表名__列名
这里可以实现自定制related_name
在models里设置表结构的时候:
1
2
3
4
5
6
7
8
class
User(models.Model):
user
=
models.CharField(max_length
=
32
)
pwd
=
models.CharField(max_length
=
64
)
ut
=
models.ForeignKey(
to
=
"UserType"
,
to_field
=
"id"
,
related_name
=
"cc"
)
这样再次获取的时候就可以通过related_name值获取:
v3 = models.UserType.objects.all().values("name","cc__user")这种方式和
3 = models.UserType.objects.all().values("name","user__user")结果是一样的
这里还有一个参数叫related_query_name
反向操作时,使用的连接前缀,用于替换“表名__set”中的“表名”,如果related_query_name=“aa”,则反向查找是可以通过aa_set查找
在Django admin中用到的参数
limit_choices_to
通过limit_choices_to,在Admin或ModelForm中显示关联数据时,提供的条件
如下图所示usertype中有四个类型:
如果不做任何设置,添加用户时应该也能看到四个类型如下图:
在代码中通过limit_choices_to={"id__gt":2},可以修改显示的个数
1
2
3
4
5
6
7
8
9
class
User(models.Model):
user
=
models.CharField(max_length
=
32
)
pwd
=
models.CharField(max_length
=
64
)
ut
=
models.ForeignKey(
to
=
"UserType"
,
to_field
=
"id"
,
related_name
=
"cc"
,
limit_choices_to
=
{
"id__gt"
:
2
},
)
db_constraint=True # 是否在数据库中创建外键约束
parent_link=False # 在Admin中是否显示关联数据
一对一OnetoOneField
OneToOneField(ForeignKey)
OneToOneField继承ForeignKey
所以同样有
to, # 要进行关联的表名
to_field=None # 要关联的表中的字段名称
on_delete=None, # 当删除关联表中的数据时,当前表与其关联的行的行为
当两个类之间有继承关系时,默认会创建一个一对一的字段
多对多ManyToManyField
常见的参数:
to, # 要进行关联的表名
related_name# 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
related_query_name=None, # 反向操作时,使用的连接前缀,用于替换【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
limit_choices_to # 在Admin或ModelForm中显示关联数据时,提供的条件
特殊参数:
symmetrical=None,
仅用于多对多自关联时,symmetrical用于指定内部是否创建反向操作的字段
做如下操作时,不同的symmetrical会有不同的可选字段
symmetrical=True:
class BB(models.Model):
code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=True)
这个时候可选字段有:code,id,m1
symmetrical=Falses时:
class BB(models.Model):
code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=False)
这个时候可选字段有:code,id,m1,bb
其实这个时候发反向查询没有多大意义,毕竟这里是多丢多的自关联
创建对多的三种方式
第一种:让django自动创建第三张表,即通过models.ManyToManyField
1
2
3
4
5
class
Blog(models.Model):
site
=
models.CharField(max_length
=
32
)
m
=
models.ManyToManyField(
"Tag"
)
class
Tag(models.Model):
name
=
models.CharField(max_length
=
32
)
这样就可以通过
models.Blog.m.add
models.Blog.m.update
models.Blog.m.clear
models.Blog.m.all
models.Blog.m.create
……
第二种方式:手动创建第三张表
1
2
3
4
5
6
7
8
9
class
Blog(models.Model):
site
=
models.CharField(max_length
=
32
)
class
Tag(models.Model):
name
=
models.CharField(max_length
=
32
)
class
B2T(models.Model):
b
=
models.ForeignKey(
"Blog"
)
t1
=
models.ForeignKey(
"Tag"
)
相关文章推荐
- Python工程师详细讲解Django之model
- Halcon模版匹配算子解析---超级详细的create_shape_model和find_shape_model算子的详细讲解
- python-Django框架,分页以及数据库执行情况详细探究
- 详细讲解Python中的文件I/O操作
- python学习之--Django--连接数据库mysql创建model
- Python线程池详细讲解
- Python开发【Django】:ModelForm操作
- python列表详细讲解
- pythonWeb -- Django开发- 模型Model 和 数据库的操作
- Python Shell 解释器下使用Django Model
- python django model类型总结
- python django模型内部类meta详细解释
- PYTHON--DJANGO--MODEL--多表查询
- python django使用haystack:全文检索的框架(实例讲解)
- python-django 模型model字段类型说明
- python random模块的详细讲解
- Python语言学习讲解七:使用traceback获取详细的异常信息
- Python之路【第二十二篇】:Django之Model操作
- python编写shell脚本详细讲解
- django配置apache model_python