zoukankan      html  css  js  c++  java
  • Django的ORM基本操作详解

    一对多关系

    -------------------models.py----------------
    from django.db import models
    
    class Classes(models.Model):
        # 班级表
        title = models.CharField(max_length=32)
        m = models.ManyToManyField('Teachers') # 多对多
    
    class Teachers(models.Model):
        # 老师表
        name = models.CharField(max_length=32)
    
    class Student(models.Model):
        # 学生表
        username = models.CharField(max_length=32)
        age = models.IntegerField()
        gender = models.BooleanField()
        cs = models.ForeignKey("Classes",on_delete=models.CASCADE)  #cs是Classes的一个对象

    表中的数据:

    Classes       Student

    示例:
        -查询所有学生的名称以及其所在班级的名称,QuerySet

    stu_list = Student.objects.all()
    # [obj,obj,ibj,obj]  里面是一个一个的对象
    
    stu_list = Student.objects.all().values('id','username')
    # [{'id':1,'username':'xx'},{'id':'','username':''}...]  里面是字典
    
    stu_list = Student.objects.all().values_list('id','username')
    [(1,'小王'),(2,'小明')...]  # 里面是元组
    
    # 正解        
    stu_list = Student.objects.all().values('username','cs__title')
    # <QuerySet [{'username': '小王', 'cs__title': '2班'}, {'username': '小明', 'cs__title': '2班'}, {'username': '小刘', 'cs__title': '2班'}, {'username': '小李', 'cs__title': '3班'}]>
    for row in stu_list: # 里面元素是字典 print(row['username'],row['cs__title'])

    这里的跨表操作只是跨了两张表,跨三张表也一样的道理,例如,假如还有一张校区表School(有字段name),Classes表
    中的另一个字段sch是外键,依赖于校区表,那么,找到所有学生的姓名、班级、校区则是:

     stu_list = Student.objects.all().values('username','cs__title','cs__title__name')

    正反向查询(通过双下划线跨表查询)

    # 找到2班的学生
    # -----正向-----
    a=models.Student.objects.filter(cs__title='2班')  # 3个Student对象
        print(a) # 正向查
    # <QuerySet [<Student: Student object (1)>, <Student: Student object (2)>, <Student: Student object (3)>]>
    #------反向------
    obj = models.Classes.objects.filter(title='2班').first()
        print(obj.student_set.all()) # 反向查
    # <QuerySet [<Student: Student object (1)>, <Student: Student object (2)>, <Student: Student object (3)>]

    总结:

    1、类代表数据库的表
    2、类的对象代指数据库的一行记录
    3、ForeignKey(外键)字段代指关联表中的一行数据(类的对象)
    4、ManyToManyField字段,自动生成第三张表,依赖关联表对第三张表间接操作
    5、 -正向:cs字段   (推荐使用)
          -反向:小写类名_set(还有一个 .all()方法,返回所有对象) 默认是这个名字,但也可以修改,
           Student表的外键中有一个 related_name= 参数,可换成想要的名字。反向查只需
           小写类名_set换成修改好的名字即可,

     多对多关系

    -------------------models.py----------------
    from django.db import models
    
    class Classes(models.Model):
        # 班级表
        title = models.CharField(max_length=32)
        m = models.ManyToManyField('Teachers') # 多对多
        # 这里同样有个参数 related_name= 可以修改用于反向查找时用的名字
    class Teachers(models.Model):
        # 老师表
        name = models.CharField(max_length=32)
    
    class Student(models.Model):
        # 学生表
        username = models.CharField(max_length=32)
        age = models.IntegerField()
        gender = models.BooleanField()
        cs = models.ForeignKey("Classes",on_delete=models.CASCADE)  #cs是Classes的一个对象

    表中的数据:

    Classes   Teacher    

    classes_m

    示例:

    cls_list = models.Classes.objects.all()
        for obj in cls_list:
            print(obj.id,obj.title,obj.m.all()) # 查看班级表中的ID,班级名,任课老师
           #1 2班 <QuerySet [<Teachers: Teachers object (1)>, <Teachers: Teachers     object (2)>,<Teachers: Teachers object (3)>]>
           # 2 3班 <QuerySet []>
           # 3 4班 <QuerySet []>
            for row in obj.m.all():
                print('----',row.name)       #---- 刘老师
                                                #---- 侯老师    
    
    obj = models.Classes.objects.filter(id=1).first()
    obj.m.add(3)   # 给班级id为1的班分配一个id为3的老师,正向操作
    
    obj = models.Teachers.objects.filter(id=2).first()
    obj.classes_set.add(2) # 为id为2的老师分配一个id为2的班,反向操作
    
    obj = models.Teachers.objects.filter(id=2).first()  # models.Teachers.objects.filter(id=2)拿到的只是一个QuerySet对象集合,一个列表,.first()方法取出第一个对象,才能进行操作
    obj.classes_set.set([1,2])  # 为id为2的老师添加班级id为1、2的班
    
    v = models.Classes.objects.all().values('id','title','m','m__name')
    print(v)  # 正向操作   想要对teacher表进行信息查看,在 .values方法下对m已经操作不了了,此时已经是字典了,要在 .all方法下拿到的对象才能对m进行操作
    # <QuerySet [{'id': 1, 'title': '2班', 'm': 1, 'm__name': '刘老师'}, {'id': 1, 'title': '2班', 'm': 2, 'm__name': '侯老师'},
    # {'id': 1, 'title': '2班', 'm': 3, 'm__name': '赵老师'}, {'id': 2, 'title': '3班', 'm': 2, 'm__name': '侯老师'}, {'id': 3, 'title': '4班', 'm': None, 'm__name': None}]>
    
    查询所有老师的姓名以及所教的班级名称 v = models.Teachers.objects.all().values('name','classes__title') print(v) # 反向操作 # <QuerySet [{'name': '刘老师', 'classes__title': '2班'}, {'name': '侯老师', 'classes__title': '2班'}, {'name': '侯老师', 'classes__title': '3班'}, # {'name': '赵老师', 'classes__title': '2班'}, {'name': '王老师', 'classes__title': None}]>

     

    一对一关系

    一对一关系的反向查找则是 对象名.小写表名.字段

  • 相关阅读:
    bugKu getshell
    XCTF 进阶区 CAT
    php弱类型比较
    XCTF command_execution
    关于错误 openssl/ssl.h:没有那个文件或目录的解决办法
    libffi-dev : 依赖: libffi6 (= 3.2.1-4) 但是 3.2.1-4kord 正要被安装
    如何查看 Ubuntu下已安装包版本号
    git 下载指定tag版本的源码
    ubuntu 环境 openstack 源码包制成 deb 包
    fedora 国内源
  • 原文地址:https://www.cnblogs.com/zq8421/p/10386538.html
Copyright © 2011-2022 走看看