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}]>

     

    一对一关系

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

  • 相关阅读:
    线性代数思维导图——3.向量
    微分中值定理的基础题型总结
    构造函数
    Python课程笔记(七)
    0241. Different Ways to Add Parentheses (M)
    0014. Longest Common Prefix (E)
    0013. Roman to Integer (E)
    0011. Container With Most Water (M)
    0010. Regular Expression Matching (H)
    0012. Integer to Roman (M)
  • 原文地址:https://www.cnblogs.com/zq8421/p/10386538.html
Copyright © 2011-2022 走看看