A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

模型之间的三种关系:一对一,一对多,多对多。
一对一:实质就是在主外键(author_id就是foreign key)的关系基础上,给外键加了一个UNIQUE=True的属性;
一对多:就是主外键关系;(foreign key)
多对多:(ManyToManyField) 自动创建第三张表(当然我们也可以自己创建第三张表:两个foreign key)

查询操作:
一对多查询,多对多查询:
注意, 多对多:(ManyToManyField) 自动创建第三张表(当然我们也可以自己创建第三张表:两个foreign key),所以,2张表要有关联,中间表里面必须要有值,中间表的值可以手动填写,也可以通过django web 让其自动填写

我们在views.py中更改查询相关代码:

def list(request):
    _class = "docker班"
    #obj_li = models.Class.objects.filter(name=_class) #querset_list
    obj = models.Class.objects.filter(name=_class).first() #querset
    print("一对多拿值,根据班级,拿学校的数据")
    print(obj.name,obj.sch.name)
    print("多对多拿值,根据班级,拿用户数据")
    #print (obj.user.filter(name=_class).first())
    for i in obj.user.all():
       print (i.username)

控制台会返回:
一对多拿值,根据班级,拿学校的数据
docker班 清华
多对多拿值,根据班级,拿用户数据
xianrenqiu

反向查询:
已知 用户的名字是linux,查询对应的班级。
def list(request):
    user_obj = models.Userinfo.objects.filter(name='linux').first()
    for item in user_obj.class_set.all():
        print (item.name)

可以得到班级为:python班

增加操作:
一对多的增加:
操作也是比较简单的

def add(request):
    obj=models.School.objects.create(name='湖南大学')
    obj_cla=models.Class.objects.create(name='市场营销',sch=obj)
    obj_cla1=models.Class.objects.create(name='酒店管理',sch=obj)
    print ("一对多增加,跨表查到了学校")
    print (obj,obj_cla.sch.name,obj_cla1.sch.name)

控制台输出:
一对多增加
湖南大学 湖南大学 湖南大学

增加的大学:湖南大学,湖南大学增加的班级:市场营销,酒店管理

多对多增加:
操作的是中间表
用户表和中间表,我们增加2张表之间的关系表user_class字段

user_obj= models.Userinfo.objects.create(name="多对多测试",username='test')
class_obj.user.add(user_obj.id)

也可以查询匹配到2张表的字段然后增加关系表字段:

def add(request):
    class_name="linux班"
    class_obj = models.Class.objects.filter(name=class_name).first()
    user_obj= models.Userinfo.objects.filter(name='网络')
    class_obj.user.add(*user_obj)

中间表增加:


反向增加:
反向增加2张表的关联关系,

def add(request):
    class_obj = models.Class.objects.filter(name='计算机班')
    user_obj = models.Userinfo.objects.filter(name='linux').first()
    #反向增加2张表的关联关系
    user_obj.class_set.add(*class_obj)

反之想要反向删除:
其他不变,只需要改变执行方法

user_obj.class_set.move()
1
删除操作:
删除就是匹配到相关的字段,然后执行删除方法就能删除

def delete(request):
    _class = '市场营销'
    models.Class.objects.filter(name=_class).delete()

控制台没打印,所以没输出,但是数据库中已经把数据删除了

一对多删除:
             models.Class.objects.filter(sch__name='湖南大学').delete()
1
此时就能把湖南大学下面所有班级删掉

多对多的删除:
操作的是中间表
格式跟增加一样,所用的方法时move()

def delete(request):
    class_name="linux班"
    class_obj = models.Class.objects.filter(name=class_name).first()
    user_obj= models.Userinfo.objects.filter(name='网络')
    class_obj.user.remove(*user_obj)

可以删除掉对应2张表的关系。

修改操作:
修改跟删除一样,反之删除跟修改也一样,只是一个调用的是delete,一个调用的是update,其他都是一样的,

一对多修改,(删除类似):
def update(request):
    #sch__name代表跨表查询,将学校名为清华的班级名全部改为计算机
    models.Class.objects.filter(sch__name='清华').update(name='计算机')

跟清华关联的班级,全部改名为计算机了

多对多修改:
修改的关系表,clear方法是先把 班级表里面所有跟linux班所有的关系先清掉,然后重新添加

def update(request):
    class_name = "linux班"
    class_obj = models.Class.objects.filter(name=class_name).first()
    user_obj = models.Userinfo.objects.filter(name = "网络")
    #先删后加
    class_obj.user.clear()
    class_obj.user.add(*user_obj)

关于linux班级id只剩我们操作的这一条。


1 个回复

正序浏览
奈斯,加油
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马