1. 创建数据表并添加数据
创建用户表和用户类型表,用户类型表是用户表的父表,用户表是用户类型的字表。
models.py:
class UserType(models.Model):
"""
用户类型表
"""
title = models.CharField(max_length=32)
class UserInfo(models.Model):
"""
用户表
"""
name = models.CharField(max_length=16)
age = models.IntegerField()
ut = models.ForeignKey('UserType', on_delete=models.CASCADE)
views.py:
:
def user(request):
models.UserType.objects.create(title='普通用户')
models.UserType.objects.create(title='VIP用户')
models.UserInfo.objects.create(name='Thanlon', age=20, ut_id=1)
models.UserInfo.objects.create(name='Kiku', age=23, ut_id=2)
return HttpResponse('...')
2. 正向连表操作
正向连表查的是UserInfo表,是通过UserInfo表的外健ut字段来获取父表与之对应的字段。一个用户只有一个用户类型
。
def user(request):
result = models.UserInfo.objects.all()
for obj in result:
# print(obj.id,obj.name,obj.age,obj.ut,obj.ut.id,obj.ut.title)
# 如果UserType还有父表则继续使用.的方式获取父表的值(三个表,四个表...都可以通过这种方式)
print(obj.id, obj.name, obj.age, obj.ut.title)
"""
2 Thanlon 20 普通用户
3 Kiku 23 VIP用户
"""
return HttpResponse('...')
3. 反向连表操作
反向连表查询的父表UserType,通过父表隐藏的字段来获取子表UserInfo的字段,这个“隐藏”的字段的格式是 表名_set
。一个用户类型下可以有多个用户
。
def user(request):
# 一个用户类型下可以有多个用户
# obj = models.UserType.objects.first()
# print(obj.id, obj.title, obj.userinfo_set.all())
"""
1 普通用户 <QuerySet [<UserInfo: UserInfo object (2)>]>
"""
# 查所有用户类型下所有的用户
result = models.UserType.objects.all()
for obj in result:
for row in obj.userinfo_set.all():
print(row.id, row.name, row.age, row.ut.title)
"""
2 Thanlon 20 普通用户
3 Kiku 23 VIP用户
"""
return HttpResponse('...')
如果是查Userinfo的所有字段,使用反向连表和正向连表都能查询到结果,但是我们发现反向连表的时间复杂度比正向连表要大。
反向连表可以获取用户类型下对应的所有用户,还可以通过过滤这些用户:
def user(request):
obj = models.UserType.objects.first()
print(obj.id, obj.title, obj.userinfo_set.filter(name='Thanlon'))
for row in obj.userinfo_set.filter(name='Thanlon'):
print(row.id, row.name, row.ut.title)
"""
1 普通用户 <QuerySet [<UserInfo: UserInfo object (2)>]>
2 Thanlon 普通用户
"""
return HttpResponse('...')
4. 获取数据的三种方式
第一种方式,获取的是对象:
def user(request):
result = models.UserType.objects.all()
print(result) # [obj,obj,obj,,,]
"""
<QuerySet [<UserInfo: UserInfo object (2)>, <UserInfo: UserInfo object (3)>]>
"""
for obj in result:
for row in obj.userinfo_set.all():
print(row.id, row.name, row.ut.title)
"""
2 Thanlon 普通用户
3 Kiku VIP用户
"""
return HttpResponse('...')
第二种方式,获取的是字典:
def user(request):
# 获取所有字段
# result = models.UserInfo.objects.values()
# 获取指定字段
result = models.UserInfo.objects.values('age', 'name', 'ut__title')
print(
result) # [{'age': 20, 'name': 'Thanlon', 'ut__title': '普通用户'}, {'age': 23, 'name': 'Kiku', 'ut__title': 'VIP用户'}]
"""
<QuerySet [{'age': 20, 'name': 'Thanlon', 'ut__title': '普通用户'}, {'age': 23, 'name': 'Kiku', 'ut__title': 'VIP用户'}]>
"""
for row in result:
print(row['age'], row['name'], row['ut__title'])
"""
20 Thanlon 普通用户
23 Kiku VIP用户
"""
return HttpResponse('...')
第三种方式,获取的是元组:
def user(request):
# 获取所有字段
# result = models.UserInfo.objects.values_list()
# 获取指定字段
result = models.UserInfo.objects.values_list('age', 'name', 'ut__title')
print(result) # [(20, 'Thanlon', '普通用户'), (23, 'Kiku', 'VIP用户')]
"""
<QuerySet [(20, 'Thanlon', '普通用户'), (23, 'Kiku', 'VIP用户')]>
"""
for row in result:
print(row[0], row[1], row[2])
"""
20 Thanlon 普通用户
23 Kiku VIP用户
"""
return HttpResponse('...')
三种方式都支持跨表操作,只不过对象的方式跨表是在循环对象的时候,而字典和元组的方式是在查询的的时候。