Django对于数据库提供了它自己的一套ORM(对象关系映射,Object Relational Mapping,简称ORM)
连表关系分为三种:
1、一对多:models.ForeignKey(其他表)
2、一对一:models.OneToOneField(其他表)
3、多对多:models.ManyToManyField(其他表)
应用场景:
-
- 一对一:在某表中创建一行数据时,有一个单选的下拉框(下拉框中的内容被用过一次就消失了)。例如:原有含10列数据的一张表保存相关信息,经过一段时间之后,10列无法满足需求,需要为原来的表再添加5列数据。
- 一对多:当一张表中创建一行数据时,有一个单选的下拉框(可以被重复选择)。例如:创建用户信息时候,需要选择一个用户类型【普通用户】【金牌用户】【铂金用户】等。
- 多对多:在某表中创建一行数据是,有一个可以多选的下拉框。例如:创建用户信息,需要为用户指定多个爱好。
一、一对多连表操作
创建两张表,并使用一对多关系关联起来
class UserType(models.Model): caption = models.CharField(max_length=32)class UserInfo(models.Model): username = models.CharField(max_length=32) age = models.IntegerField() user_type = models.ForeignKey(UserType)
插入测试数据
def user_type(request): dic = { 'caption':'CEO'} models.UserType.objects.create(**dic) return HttpResponse("ok")def user_info(request): dic = { 'username': 'xx', 'age': 73, 'user_type': models.UserType.objects.get(id=1)} models.UserInfo.objects.create(**dic)
查询本表的内容比较简单,不多赘述:
models.UserInfo.objects.filter(username="alex")
下面我们了解一下跨表操作
正向跨表查询:
result = models.UserInfo.objects.filter(user_type__caption="CEO")for item in result: print item.username,item.age,item.user_type.caption
反向跨表查询需要用到Django为我们提供的_set功能:
user_type_obj = models.UserType.objects.get(userinfo__username='xx')print user_type_obj.captionprint user_type_obj.userinfo_set.all().count()
二、多对多连表操作
创建两张表,并使用多对多关系关联起来
class Host(models.Model): hostname = models.CharField(max_length=32) port = models.IntegerField()class HostAdmin(models.Model): username = models.CharField(max_length=32) email = models.CharField(max_length=32) host = models.ManyToManyField(Host)
创建多对多关系后Django会自动为我们生成第三张表host_admin_host,这张表相当于一张字典表,分别存储了Host表和HostAdmin表中对应的id
正向添加数据
admin_obj = models.HostAdmin.objects.get(username='xx')host_list = models.Host.objects.filter(id__lt=3)admin_obj.host.add(*host_list)
反向添加数据
host_obj = models.Host.objects.get(id=3)admin_list = models.HostAdmin.objects.filter(id__gt=1)host_obj.hostadmin_set.add(*admin_list)
我们也可以不使用Django自动为我们生成的第三张表,自己来定义
class Host1(models.Model): hostname = models.CharField(max_length=32) port = models.IntegerField()class HostAdmin1(models.Model): username = models.CharField(max_length=32) email = models.CharField(max_length=32) host = models.ManyToManyField(Host1, through='HostRelation')class HostRelation(models.Model): c1 = models.ForeignKey(Host1) c2 = models.ForeignKey(HostAdmin1)
through='HostRelation' 参数说明了我们希望与Host1表建立多对多关系,并且使用我们自己定义的HostRelation表
为HostRelation表创建数据
models.HostRelation.objects.create(c1_id = 2,c2_id = 1,)
创建好数据后,我们就可以开始查数据了
#第一种方式 # 正向查 admin_obj = models.HostAdmin.objects.all(id=1) for item in admin_obj: item.host.all() # 反向查 host_obj = models.Host.objects.get(id=1) host_obj.hostadmin_set.all()#第二种方式 relation_list = models.HostRelation.objects.all() relation_list = models.HostRelation.objects.filter(c2__username='xx') for item in relation_list: print item.c1.hostname print item.c2.username