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)

 

posted @ 2017-06-30 18:34  tonycloud  阅读(1981)  评论(0编辑  收藏  举报