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()
    
  • 相关阅读:
    Redis(二) 扩展
    Redis(一)基础
    Java垃圾回收机制 入门
    freeregex-0.01 使用文档
    上传文件到阿里云linux服务器
    jQuery代码解释(基本语法)
    JQuery中使用FormData异步提交数据和提交文件
    jQuery获取data-*属性值
    jquery 中 $.map 的使用方法
    mysql创建表时反引号的作用
  • 原文地址:https://www.cnblogs.com/cupid10/p/14307762.html
Copyright © 2011-2022 走看看