• 【Django学习笔记 - 13】:关联查询(日期查询、一对一查询、一对多查询、多对多查询)


    Django配置数据库utf-8编码

    1. settings.py文件中配置数据库
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'dj2022',
            'HOST': '127.0.0.1',
            'PORT': 3306,
            'USER': 'root',
            'PASSWORD': '1064865165QAF',
            'TEST': {
                'CHARSET': 'utf-8',
                'COLLATION': 'utf-8_general_ci'
            }
        }
    }
    
    SESSION_ENGINE = 'django.contrib.sessions.backends.db'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2.在Navicat中输入如下命令

    CREATE DATABASE 数据库名 DEFAULT SET utf8;
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    一、日期查询

    添加日期字段:
    DateTimeField(verbose_name=‘’, auto_now=True)
    auto_now 表示以现在的时间作为其值

    日期字段的添加

    1. 创建一个模型类

    在这里插入图片描述
    2、进行数据库的迁移后,在终端中进入shell环境,添加字段值
    在这里插入图片描述
    在这里插入图片描述
    3、在Navicat中进行数据的添加
    在这里插入图片描述
    在这里插入图片描述

    日期字段的查询

    1、查询生日为1993-12-14

    >>> Husband_1.objects.filter(birthday='1993-12-14')
    <QuerySet [<Husband_1: Husband_1 object (1)>]>
    
    
    • 1
    • 2
    • 3

    2、查询1991年后的数据

    >>> Husband_1.objects.filter(birthday__gt='1991-01-01')
    <QuerySet [<Husband_1: Husband_1 object (1)>, <Husband_1: Husband_1 object (3)>, <Husband_1: Husband_1 object (4)>, <Husband_1: Husband_1 object (5)>]>
    
    • 1
    • 2

    3、只根据年代或月份查询

    >>> Husband_1.objects.filter(birthday__year__gt='1991')
    <QuerySet [<Husband_1: Husband_1 object (1)>, <Husband_1: Husband_1 object (3)>, <Husband_1: Husband_1 object (4)>, <Husband_1: Husband_1 object (5)>]>
    
    • 1
    • 2
    
    >>> Husband_1.objects.filter(birthday__month__gt='8')
    <QuerySet [<Husband_1: Husband_1 object (1)>, <Husband_1: Husband_1 object (3)>, <Husband_1: Husband_1 object (4)>]>
    
    • 1
    • 2
    • 3

    二、F、Q对象

    F对象

    F对象,用于属性与属性之间进行比较
    导包:from django.db.models import F
    语法:filter(字段名_运算符=F(‘字段名’))

    • 例:查询身高大体重两倍的数据
    
    >>> from django.db.models import F
    >>> Husband_1.objects.filter(weight__lt=F('height')/2)
    <QuerySet [<Husband_1: Husband_1 object (1)>, <Husband_1: Husband_1 object (2)>, <Husband_1: Husband_1 object (3)>, <Husband_1: Husband_1 object (4)>]>
    
    • 1
    • 2
    • 3
    • 4

    Q对象

    Q对象,用于逻辑运算操作,与、或、非
    导包:from django.db.models import Q

    1. 例1:查询大于1993年或小于1992年的数据
    >>> Husband_1.objects.filter(Q(birthday__year__gt='1993')|Q(birthday__year__lt='1992'))
    <QuerySet [<Husband_1: Husband_1 object (2)>, <Husband_1: Husband_1 object (3)>]>
    
    • 1
    • 2
    1. 查询除了1993年的所有数据
    >>> Husband_1.objects.filter(~Q(birthday__year__gt='1993'))
    <QuerySet [<Husband_1: Husband_1 object (1)>, <Husband_1: Husband_1 object (2)>, <Husband_1: Husband_1 object (4)>, <Husband_1: Husband_1 object (5)>]>
    
    • 1
    • 2
    1. 查询大于1992年且年龄为33的数据
    >>> Husband_1.objects.filter(Q(birthday__year__gt='1992')&Q(age=33))
    <QuerySet [<Husband_1: Husband_1 object (1)>, <Husband_1: Husband_1 object (5)>]>
    
    • 1
    • 2

    >>> Husband_1.objects.filter(Q(birthday__year__gt='1992',age=33))
    <QuerySet [<Husband_1: Husband_1 object (1)>, <Husband_1: Husband_1 object (5)>]>
    
    • 1
    • 2

    三、关联查询

    一对一关系

    1. 添加模型类
    class Wife_1(models.Model):
        name = models.CharField(verbose_name='姓名', max_length=8)
        age = models.IntegerField(verbose_name='年龄')
        height = models.FloatField(verbose_name='身高')
        weight = models.FloatField(verbose_name='体重', null=None)
        husband = models.OneToOneField(Husband_1, verbose_name='丈夫', on_delete=models.CASCADE)
    
        class Meta:
            db_table = 'Wife_1'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    models.OneToOneField(Husband_1, verbose_name=‘丈夫’, on_delete=models.CASCADE)
    on_delete,设置表与表之间的级联
    级联:将表与表之间进行联系,当主表中的数据删除时,子表中的数据也会被删除,在进行一对一的关联时,必须添加上on_delete参数

    1. 级联演示

    绑定表husband_1中id为3的数据

    >>> Wife_1.objects.create(name='小芳', age=30, height=168, weight=48, husband_id=3)
    <Wife_1: Wife_1 object (1)>
    
    • 1
    • 2
    >>> wife = Wife_1.objects.get(id=1)
    
    >>> husband = Husband_1.objects.get(id=3)
    >>> wife.husband
    <Husband_1: Husband_1 object (3)>
    >>> wife.husband.name
    '王五'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    从主表中查询子表的数据:
    例如:husband.子表的模型类类名(小写).name

    >>>husband.wife_1.name
    '小芳'
    
    • 1
    • 2

    一对多多对一

    1. 添加模型类
    class Children_1(models.Model):
        Children_choice = (
            (1, '男'),
            (2, '女')
        )
        name = models.CharField(verbose_name='姓名', max_length=8)
        age = models.IntegerField(verbose_name='年龄')
        sex = models.CharField(choices=Children_choice, verbose_name='性别', max_length=2)
        father = models.ForeignKey(Husband_1, on_delete=models.CASCADE)
        mother = models.ForeignKey(Wife_1, on_delete=models.CASCADE)
    
        class Meta:
            db_table = 'Children_1'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2.建立连接

    >>> Children_1.objects.create(name='王小五', age=10, sex='男', father_id=3, mother_id=1)
    <Children_1: Children_1 object (1)>
    >>> Children_1.objects.create(name='王小美', age=8, sex=2, father_id=3, mother_id=1)
    <Children_1: Children_1 object (2)>
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    3.查询演示

    >>> son = Children_1.objects.get(id=1)
    >>> daughter = Children_1.objects.get(id=2)
    >>> son.mother
    <Wife_1: Wife_1 object (1)>
    >>> daughter.father.name
    '王五'
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 使用_set进行一对多的查询

    没有related_name参数时,从‘一‘(父母)这一方查询’多‘(孩子)的一方,需要在模型类类名小写后加上’_set‘进行查询,当查询的记过可能有多个的时候,就需要再模型类类名小写后加上’_set’进行查询

    >>> mother = Wife_1.objects.get(id=1)
    >>> mother.children_1.set
    >>> mother.children_1_set
    <django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager object at 0x0000026FE5696988>
    >>> mother.children_1_set.all()
    <QuerySet [<Children_1: Children_1 object (1)>, <Children_1: Children_1 object (2)>]>
    >>> data1 = mother.children_1_set.all()
    >>> data1[0].name
    '王小五'
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. 使用related_name参数

    related_name参数:表示为关联的字段起一个关联名称,相当于起别名,便于开发人员进行查询

    在这里插入图片描述

    
    >>> wife = Wife_1.objects.get(id=1)
    >>> wife.mother
    <django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager object at 0x00000272C5CD68C8>
    >>> data = wife.mother.all() # 获取所有孩子的信息
    >>> data
    <QuerySet [<Children_1: Children_1 object (1)>, <Children_1: Children_1 object (2)>]>
    >>> data[1].name
    '王小美'
    >>> data[0].name
    '王小五'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    多对多查询

    1. 添加模型类
    class Brother_1(models.Model):
        Brother_choice = (
            (1, '男'),
            (2, '女')
        )
        name = models.CharField(verbose_name='姓名', max_length=8)
        age = models.IntegerField(verbose_name='年龄')
        sex = models.CharField(choices=Brother_choice, verbose_name='性别', max_length=2)
        brother = models.ManyToManyField(Husband_1, verbose_name='兄弟')
        sister = models.ManyToManyField(Wife_1, verbose_name='姐妹')
    
        class Meta:
            db_table = 'brother_1'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    数据库表的命名格式:模型类名小写_关联字段名 -> brother_1_brother

    在这里插入图片描述

    1. 演示如下
    >>> Brother_1.objects.create(name='大海', age=35, sex='男')
    <Brother_1: Brother_1 object (1)>
    >>> brother = Brother_1.objects.get(id=1)
    >>> husband = Husband_1.objects.get(id=1)
    # 1、通过对象进行关联
    >>> brother.brother.set([husband,])
    # 2、通过id进行关联
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

  • 相关阅读:
    动态规划:01背包问题+3道子序列问题困难题
    10.9作业
    客观看待mybatis 中使用 where 1=1
    powershell中的常用软件打开命令
    MySQL的日志管理、备份和恢复
    (AS笔记)Android选择图片+HttpURLConnection表单POST上传图片到后端
    Java的方法
    用go基于有向图实现一个有限状态机器(FSM)
    视频怎么制作动图?分享简单的视频制作gif方法
    docker login harbor http login登录
  • 原文地址:https://blog.csdn.net/Oh_Python/article/details/125250247