01.不创建第三张表推荐
(法1)
- 第一种: 自己不创建第三张关系表,有m2m字段: 根据queryset对象增删改查(推荐)
1.1 创建表
from django.db import models
class UserInfo(models.Model):
username = models.CharField(max_length=32)
def __str__(self):
return self.username
class UserGroup(models.Model):
group_name = models.CharField(max_length=64)
user_info = models.ManyToManyField(to='UserInfo',related_query_name='m2m')
def __str__(self):
return self.group_name
1.2 根据queryset对象操作
from django.shortcuts import HttpResponse
from app01 import models
def orm(request):
user_info_obj = models.UserInfo.objects.get(username='zhangsan')
user_info_objs = models.UserInfo.objects.all()
group_obj = models.UserGroup.objects.get(group_name='group_python')
group_objs = models.UserGroup.objects.all()
# 添加: 正向
group_obj.user_info.add(user_info_obj)
group_obj.user_info.add(*user_info_objs)
# 删除:正向
group_obj.user_info.remove(user_info_obj)
group_obj.user_info.remove(*user_info_objs)
# 添加: 反向
user_info_obj.usergroup_set.add(group_obj)
user_info_obj.usergroup_set.add(*group_objs)
# 删除:反向
user_info_obj.usergroup_set.remove(group_obj)
user_info_obj.usergroup_set.remove(*group_objs)
# 查找:正向
print(group_obj.user_info.all()) # 查找group_python组中所有用户
print(group_obj.user_info.all().filter(username='zhangsan'))
# 查找:反向
print(user_info_obj.usergroup_set.all()) # 查找用户zhangsan属于那些组
print(user_info_obj.usergroup_set.all().filter(group_name='group_python'))
# 双下划线 正向、反向查找
# 正向:从用户组表中查找zhangsan属于哪个用户组:[<UserGroup: group_python>]
print( models.UserGroup.objects.filter(user_info__username='zhangsan'))
# 反向:从用户表中查询group_python组中有哪些用户:related_query_name='m2m'
print( models.UserInfo.objects.filter(m2m__group_name='group_python'))
# 自动创建UserInfo表和UserGroup表中的数据
'''
user_list = [{'username':'zhangsan'},
{'username':'lisi'},
{'username':'wangwu'},]
group_list = [{'group_name':'group_python'},
{'group_name':'group_linux'},
{'group_name':'group_mysql'},]
for c in user_list:
models.UserInfo.objects.create(**c)
for l in group_list:
models.UserGroup.objects.create(**l)
'''
return HttpResponse('orm')
02.自己创建第三张关系表(法2)
第二种: 自己创建第三张关系表,无 m2m 字段,自己链表查询
from django.db import models
#表1:主机表
class Host(models.Model):
nid = models.AutoField(primary_key=True)
hostname = models.CharField(max_length=32,db_index=True)
#表2:应用表
class Application(models.Model):
name = models.CharField(max_length=32)
#表3:自定义第三张关联表
class HostToApp(models.Model):
hobj = models.ForeignKey(to="Host",to_field="nid")
aobj = models.ForeignKey(to='Application',to_field='id')
# 向第三张表插入数据,建立多对多外键关联
HostToApp.objects.create(hobj_id=1,aobj_id=2)
03.根据外检ID操作(法3)
- 第三种: 自己不创建第三张关系表,有m2m字段: 根据数字id增删改查
3.1 创建表
from django.db import models
class Host(models.Model):
hostname = models.CharField(max_length=32,db_index=True)
class Group(models.Model):
group_name = models.CharField(max_length=32)
m2m = models.ManyToManyField("Host")
3.2 根据id增删改查
from django.shortcuts import HttpResponse
from app01 import models
def orm(request):
# 使用间接方法对第三张表操作
obj = models.Group.objects.get(id=1)
# 1、添加
obj.m2m.add(1) # 在第三张表中增加一个条目(1,1)
obj.m2m.add(2, 3) # 在第三张表中增加条目(1,2)(1,3)两条关系
obj.m2m.add(*[1,3]) # 在第三张表中增加条目(1,2)(1,3)两条关系
# 2、删除
obj.m2m.remove(1) # 删除第三张表中的(1,1)条目
obj.m2m.remove(2, 3) # 删除第三张表中的(1,2)(1,3)条目
obj.m2m.remove(*[1, 2, 3]) # 删除第三张表中的(1,1)(1,2)(1,3)条目
# 3、清空
obj.m2m.clear() # 删除第三张表中application条目等于1的所有条目
# 4 更新
obj.m2m.set([1, 2,]) # 第三张表中会删除所有条目,然后创建(1,1)(1,2)条目
# 5 查找
print( obj.m2m.all() ) # 等价于 models.UserInfo.objects.all()
# 6 反向查找: 双下划线
hosts = models.Group.objects.filter(m2m__id=1) # 在Host表中id=1的主机同时属于那些组
# 自动创建Host表和Group表中的数据
'''
hostname = [{'hostname':'zhangsan'},
{'hostname':'lisi'},
{'hostname':'wangwu'},]
group_name = [{'group_name':'DBA'},{'group_name':'public'},]
for h in hostname:
models.Host.objects.create(**h)
for u in group_name:
models.Group.objects.create(**u)
'''
return HttpResponse('orm')
04.ManyToManyField参数
- 创建m2m多对多时ManyToManyField可以添加的参数
1、to, # 要进行关联的表名
2、related_name=None, # 反向操作时,使用的字段名,用于代替 【表名_set】如: obj.表名_set.all()
3、related_query_name=None, # 反向操作时,使用的连接前缀,用于替换【表名】
# 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
4、limit_choices_to=None, # 在Admin或ModelForm中显示关联数据时,提供的条件:
# - limit_choices_to={'nid__gt': 5}
5、symmetrical=None, # 用于多对多自关联,symmetrical用于指定内部是否创建反向操作字段
6、through=None, # 自定义第三张表时,使用字段用于指定关系表
7、through_fields=None, # 自定义第三张表时,使用字段用于指定关系表中那些字段做多对多关系表
8、db_constraint=True, # 是否在数据库中创建外键约束
db_table=None, # 默认创建第三张表时,数据库中表的名称
05.values和values_list
from django.shortcuts import HttpResponse
from app01 import models
def orm(request):
# 第一种:values-----获取的内部是字典,拿固定列数
# 1.1 正向查找: 使用ManyToManyField字段名user_info结合双下划线查询
models.UserGroup.objects.filter(group_name='group_python').values('group_name', 'user_info__username')
# 1.2 反向查找: 使用ManyToManyField的related_query_name='m2m',的字段
models.UserInfo.objects.filter(username='zhangsan').values('username', 'm2m__group_name')
# 第二种:values_list-----获取的是元组 拿固定列数
# 2.1 正向查找: 使用ManyToManyField字段名user_info结合双下划线查询
models.UserGroup.objects.filter(group_name='group_python').values_list('group_name', 'user_info__username')
# 2.2 反向查找: 使用ManyToManyField的related_query_name='m2m',的字段
lesson = models.UserInfo.objects.filter(username='zhangsan').values_list('username', 'm2m__group_name')
# 自动创建UserInfo表和UserGroup表中的数据
'''
# user_info_obj = models.UserInfo.objects.get(username='lisi')
# user_info_objs = models.UserInfo.objects.all()
#
# group_obj = models.UserGroup.objects.get(group_name='group_python')
# group_objs = models.UserGroup.objects.all()
#
# group_obj.user_info.add(*user_info_objs)
# user_info_obj.usergroup_set.add(*group_objs)
user_list = [{'username':'zhangsan'},
{'username':'lisi'},
{'username':'wangwu'},]
group_list = [{'group_name':'group_python'},
{'group_name':'group_linux'},
{'group_name':'group_mysql'},]
for c in user_list:
models.UserInfo.objects.create(**c)
for l in group_list:
models.UserGroup.objects.create(**l)
'''
return HttpResponse('orm')