django 中manytomany , foreign key自关联 ,正向查找,反向查找(values,values_list)
1、在此之前做多对多连表操作的时候,都是利用 A表 和B表的外键 ,创建出第三张关系表。现在在 django ORM 中有了另外的方式可以实现多对多,并且使用的方式可以更便捷。
方式一:外键自关联 ------
django app目录下的models.py 创建表:
class UserInfo(models.Mode): username=models.CharField(max_length=32) password=models.CharField(max_length=32) gender_list=( (1,'男'), (2,'女'), ) gender=models.IntegerField(choices=gender_list) class U2U(models.Model): 利用一张表创建出 男生对应约会女生的关系表,但是这个需要从程序层面维护,直接插入男对男的约会,数据库也不知道这是一张男女约会的关系表。 g=models.ForeignKey('UserInfo',related_name='boys') b=models.ForeignKey('UserInfo',related_name='girl')
创建并插入数据 -----如图:
方式二:
在models.py ::
class UserInfo(models.Model): username=models.CharField(max_length=32) gender_list=( (1,'男'), (2,'女'), ) gender=models.IntegerField(choices=gender_list) m=models.ManyToMany('UserInfo')
生成的第二张表:
例 :
相亲: 创建一个数据表,表里有男生和女生,只用一个表创建出另一个关系表, 并查询出这个男生与哪些女生有过相亲记录:
models.py 文件创建表
class UserInfo(models.Model): name=models.CharField(max_length=32) gender_list=( (1,'男'), (2,'女'), ) gender=models.IntegerField(choices=gender_list) m=models.ManyToManyField('UserInfo') #这里会生成另一个表叫 userinfo_m ,里面的是字段是from_userinfo_id to_userinfo_id ,这两个字段便是男生与女生的相亲关系,至于会不会男生和男生相亲,这个需要从程序层面避免,因为数据库只1 和 2 ,而1 和1 这样的数据,数据库不会分辨
views.py 创建数据记录:
def test(request): '''数据库数据创建''' # models.UserInfo.objects.create(name='liang1',gender=1) # models.UserInfo.objects.create(name='liang2',gender=1) # models.UserInfo.objects.create(name='liang2',gender=1) # models.UserInfo.objects.create(name='lili1',gender=2) # models.UserInfo.objects.create(name='lili2',gender=2) # models.UserInfo.objects.create(name='lili3',gender=2)
正向查找:查询数据男生liang1 相亲过的女生:
#正向查找: boyret=models.UserInfo.objects.filter(name='liang1').first() print(boyret,'boyret--------') boyret1=boyret.m.all() #通过本表的外键查询到的是 UserInfo object,如果是all() 那就是<QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]> for row1 in boyret1: print(row1.name) #找到与之关联的女生的名字
反向查询数据:查询 女生lili3 相亲过的男生记录:
#反向查找 result=models.UserInfo.objects.filter(name='lili3').first() # result.m.add(4) result1=result.userinfo_set.all() #通过女生的名字,查询到女生这一条记录,通过表名的小写 userinfo_set.all() 查询到这个女生的所有数据,再用for循环取到男生名字 for row in result1: print(row.name)
扩展:∆ 在BBS中,数据库的记录:foreign key 自关联
root 用户发布了一则话题 ‘别比比’ 自增ID为1 ,没有人回复reply_id 为null , xxxxx用户回复了 自增ID为2 的记录,回复了一条‘拉倒吧1’
class Comment(models.Model): #ForeignKye 的自关联 news_id=models.IntegerField() #新闻ID content=models.CharField(max_length=32) #评论内容 user=models.CharField(max_length=32) #评论者 replay=models.ForeignKey('Comment',null=True,blank=True,related_name='xx') #回复这个内容的ID是哪个 ''' 自增id news_id content user reply_id 1 1 钓鱼岛是中国的 root null # root 用户评论了 新闻 ID 为 1 ,评论内容是'钓鱼岛是中国的’ ,(reply_id)没有人回复root 2 1 就是要这样... root null # 3 1 就是 admin null . #admin 用户评论 新闻 ID 为 1 ,评论内容是 ‘就是’,没有人回复 4 2 不评论 zhangsan null 5 1 说的对 guest 2 #guest用户 回复 的新闻ID 为 1 ,回复的是 2 的自增id ,内容是‘说的对’ 6 1 很好 guest2 2 '''
如:
新闻ID 1 : 钓鱼岛新闻:XXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
----------- 评论:---------
root: 钓鱼岛是中国的
root: 就是要这样....
来自 guest 回复:说得对
来自guest2回复:很好
新闻ID2: 中国人民的GDP
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----------评论:------------
zhangsan: 不评论。
目前没人回复此评论。
values()取值 与 values_list() 取值,问: 两个表(一个用户表,一个部门表),用户表里的外键关联着部门,要从部门表获取到用户的名字?用三个方法获取到用户表的用户的名字:
方法一:直接反向查询用户结果
def index(request): result=models.DepartMent.objects.filter(dname='销售').first() v=result.userinfo_set.all() li=[] for row in v: li.append(row.name) return HttpResponse(li,)
方法二:反向查询结果为字典格式:values() #取值,取到的是字典
def two(request): result=models.DepartMent.objects.all().values(‘dname’,’userinfo__id’,’userinfo__name’)#∆备注拿到的是字典,因为拿到的是’部门’的all()结果,所以会有一个None在。。。。。 print(result) li=[] for item in result: print(item['userinfo__name']) print(item['userinfo__id']) # li.append(item['userinfo__name']) # li.append(item['dname']) print(li) return HttpResponse(li) ∆备注:不要拿到None是result=models.DepartMent.objects.filter(dname=‘销售’).values(‘dname','userinfo__id','userinfo__name')#拿到的是字典,因为拿到的是'部门'的‘销售‘,这时就没有None 了
方法三:反向查询结果为元组格式:values_list()取值 ,取到的是元组
使用values_list() ,取到的是元组值(1, 'tony') 3】[(1,tonh),(2,django)] 元组类型取值 Models.UserInfo.objects.all().values_list(‘id’,’name’) def three(request): result=models.DepartMent.objects.filter(dname='销售').values_list('userinfo__id','userinfo__name')#拿到的是元组 for item in result: print(item[0]) return HttpResponse(result)