zoukankan      html  css  js  c++  java
  • python ORM关联表

    python ORM关联表

    定义两张表

    # 国家表
    class Country(models.Model):
        name = models.CharField(max_length=100)
        
    # 学生表, country 字段是国家表的外键,形成一对多的关系
    class Student(models.Model):
        name    = models.CharField(max_length=100)
        grade   = models.PositiveSmallIntegerField()
        country = models.ForeignKey(Country,                              on_delete=models.PROTECT)
    

    然后,执行使定义生效到数据库中。

    python manage.py makemigrations common
    python manage.py migrate
    

    然后,命令行中执行 python manage.py shell ,直接启动Django命令行,输入代码。

    先输入如下代码,创建一些数据

    from common.models import *
    c1 = Country.objects.create(name='中国')
    c2 = Country.objects.create(name='美国')
    c3 = Country.objects.create(name='法国')
    Student.objects.create(name='张三', grade=1, country=c1)
    Student.objects.create(name='李四', grade=2, country=c1)
    Student.objects.create(name='王五', grade=1, country=c1)
    Student.objects.create(name='赵六', grade=2, country=c1)
    Student.objects.create(name='Mike', grade=1, country=c2)
    Student.objects.create(name='Gus',  grade=1, country=c2)
    Student.objects.create(name='White', grade=2, country=c2)
    Student.objects.create(name='Napolen', grade=2, country=c3)
    
    由学生查国家
    访问所有一年级的学生
    Student.objects.filter(grade=1).values()
    获取一年级所有的学生姓名
    Student.objects.filter(grade=1).values('name')
    

    根据对象访问外键表

    访问某一个学生所在的国家
    s1.Student.objects.get(name='张三')
    s1.country.name
    查找一年级的中国学生(注意:country__name两个横线)
    Student.objects.filter(grade=1,country__name='中国').values()
    如果需要学生姓名和国家2个字段
    Student.objects.filter(grade=1,country__name='中国')
         .values('name','country__name')
    输出为:<QuerySet [{'name': '王五', 'country__name': '中国'}, {'name': '张三', 'country__name': '中国'}]>
    也可以对获取的字段进行重命名,引入from django.db.models import F
    # annotate 可以将表字段进行别名处理
    Student.objects.annotate(
        countryname=F('country__name'),
        studentname=F('name')
        )
        .filter(grade=1,countryname='中国').values('studentname','countryname')
    
    
    由国家查学生,反向访问

    通过 表Model名转化为小写 ,后面加上一个 _set 来获取所有的反向外键关联对象

    获取所有中国的学生
    cn = Country.objects.get(name='中国')
    cn.student_set.all()
    

    在定义Model的时候,外键字段使用 related_name 参数,像这样

    # 国家表
    class Country(models.Model):
        name = models.CharField(max_length=100)
    
    # country 字段是国家表的外键,形成一对多的关系
    class Student(models.Model):
        name    = models.CharField(max_length=100)
        grade   = models.PositiveSmallIntegerField()
        country = models.ForeignKey(Country,
                    on_delete = models.PROTECT,
                    # 指定反向访问的名字
                    related_name='students')
    

    就可以使用更直观的属性名,像这样

    cn = Country.objects.get(name='中国')
    cn.students.all()
    
    反向过滤
    Country.objects.filter(students__grade=1).values()
    或者
    Country.objects.filter(student__grade=1).values()
    

    但是,我们发现,这种方式,会有重复的记录产生,如下

    <QuerySet [{'id': 1, 'name': '中国'}, {'id': 1, 'name': '中国'}, {'id': 2, 'name': '美国'}, {'id': 2, 'name': '美国'}]>
    

    可以使用 .distinct() 去重

    Country.objects.filter(students__grade=1).values().distinct()
    
  • 相关阅读:
    VUE assets里的scss没有引用会被打包进代码里,本地代码和打包后的代码样式不一致解决办法
    echarts图表配置
    关于哈希路由多项目部署同一个服务器的链接访问问题
    git操作失误,提交代码因为网络问题没有成功,然后操作时候点错按钮导致代码全部没有了,也没用备份,如何解决
    浏览器刷新时候不删除信息,关闭后删除用户信息处理办法,浏览器监听刷新以及删除事件、cookie、session、sessionStorage、localStorage区别
    angular打包部署设置publicPath文件目录及访问地址,解决打包完成后,运行打包文件,报错404,js,css未找到
    Oracle spatial与arcsde 的关系
    Oracle Spatial图层元数据坐标范围影响R-TREE索引的ROOT MBR吗?
    centos下安装supervisor的步骤详解
    laravel 队列
  • 原文地址:https://www.cnblogs.com/cupid10/p/14307762.html
Copyright © 2011-2022 走看看