• 08-常用查询及表关系的实现


    常用查询及表关系的实现

    01-常用的查询

    02-常用的模型字段类型

    03-Field的常用参数

    04-表关系的实现

    01-常用的查询

    每一个django模型类,都有一个默认的管理器,`objects`

    QuerySet表示数据库中对象的列表。它可以有0到多个过滤器。过滤器通过给定参数,缩小查询范围。(filter)

    QuerySet等同于select语句,过滤器是一个限制子句,比如where,比如limit。

    User是django模型的类

    查找对象的条件的意思是传给以上方法的一些参数。相当于是SQL语句中的where语句后面的条件,语法为字段名__规则(是连着连个下划线哦)

    一、常用查询

     
    #查找数据
    def search_user(request):
        #获取
        rs = User.objects.first() #获取第一条数据
        rs = User.objects.last() #获取最后一条数据
        rs = User.objects.filter(name = 'TAKA') #获取name为TAKA的数据,返货queryset类型,可以用rs[0]来查询
        rs = User.objects.exclude(name = 'TAKA') #排除name为TAKA的数据
        rs = User.objects.get(name = 'TAKA') #获取name为TAKA的记录对象,获取的对象具有唯一性,如果获取多个就报错
    
        #排序 order_by
        rs = User.objects.order_by('age') #以age为准则正向排序
        rs = User.objects.order_by('age','id') #以age为第一准则,id为第二准则正向排序
        rs = User.objects.order_by('-age') #以age为准则逆向排序
    
        #其他方法
        rs = User.objects.all().values() #将返回的qureyset中的model转换为字典
        rs = User.objects.count()   #获取当前查询的数据的总数
    
        rs = User.objects.filter(name__exact='budong') #name_exact相当于name
        rs = User.objects.filter(name__iexact='budong') #name_iexact跟上面的区别是这个忽略大小写
    
        #模糊查询
        rs = User.objects.filter(name__contains='i') #name中包含i的对象
        rs = User.objects.filter(name__icontains='i') #name中包含i的对象,忽略大小写
    
        rs = User.objects.filter(name__startswith='b') #name中以b开头的的对象
        rs = User.objects.filter(name__istartswith='b') #name中以b开头的的对象,忽略大小写
    
        rs = User.objects.filter(name__endswith='b')  # name中以b结尾的的对象
        rs = User.objects.filter(name__iendswith='b')  # name中以b结尾的的对象,忽略大小写
    
        rs = User.objects.filter(age__in=[18,19,20]) #in成员所属,age在18,19,20的对象
        rs = User.objects.filter(age__gt=18)   #age大于18的对象
        rs = User.objects.filter(age__gte=18)   #age大于等于18的对象
        rs = User.objects.filter(age__lt=18)   #age小于18的对象
        rs = User.objects.filter(age__lte=18)   #age小于18的对象
        rs = User.objects.filter(age__range=(18,20))   #age在18到20之间的对象,都包括
        rs = User.objects.filter(age__isnull=True)   #判断age栏是否为空 
    
    
        print(rs)
        return HttpResponse('查找数据成功')

    二、常用类型和字段参数

    #常用的字段类型映射关系
     int             -----------   IntegetField #整型,映射到数据库中的int类型
    varchar       -----------   CharFileld #字符串类型,通过max_length指定最大长度
    longtext      -----------   TextFiled   #长文本
    tinyint         -----------   BooleanField #布尔类型,在使用的时候,传递True/False进去;如果为空,则为NullBooleanField
    date           -----------    DateFiled  #日期;在使用的时候,可以设DateField.auto_now_add当对象第一次被创建的时候自动设置创建时间
    datetime     -----------    DatetimeField  #时间
    #Field的常用参数
    primary_key #主键
    unique #唯一键
    null  #是否为空,默认为False
    blank #等于True时form表单验证是可以为空,默认为False
    default #默认值
    DateField.auto_now#每次修改都会把当前时间更新进去,只用调用Model.save()方法才会调用,Queryset.update方法将不会调用。这个参数只是Date和Datetime以及Time类才有的
    Datetime.auto_now_add# 第一次添加进去,都会讲抢钱时间设置进去。以后修改,不会修改这个值
    class Ftest(models.Model):
        name = models.CharField(max_length=30,unique=True) #名字,最大长度30,唯一键
        age = models.IntegerField() #年龄
        note = models.TextField() #长文本
        gender = models.BooleanField(default=True) #性别,默认为女(1)
        create_time = models.DateTimeField(auto_now_add=True) #创建时间,不更改
        update_time = models.DateTimeField(auto_now=True) #更新时间,会自动更改
    
    
    
    
    from .models import Ftest
    def add_ftest(request):
        Ftest.objects.create(name='爱宝贝',age=25,note='啦啦啦啦',gender=False)
        return HttpResponse('插入数据成功')
    
    def update_ftest(request):
        # Ftest.objects.filter(id=2).update(age=80) #使用fiiter是不能成功使用auto_now的,因为是queryset
        f = Ftest.objects.get(id=2) #get获取的对象,在使用save才能成功使用auto_now
        f.age = 55
        f.save()
        return HttpResponse('更新数据成功')
    三、 聚合函数
    - 聚合函数
    
      - Avg 平均值
    
        ```
        # 计算同学们的年龄平均值
        res = Student.objects.aggregate(age_avg=Avg('age'))  
        ```
    
      - Max 最大值
    
        ```
        # 找到最大的年龄
        res = Student.objects.aggregate(age_max=Max('age')) 
        ```
    
      - Min 最小值
    
      - Sum求和    
    
    - 分组,聚合,分组需要结合values,annotate和聚合方法看下面的案例
    
      ```
      # 查询男生女生分别有多少人
      In [84]: from django.db.models import Count                                                          
      
      In [85]: res = Student.objects.values('sex').annotate(Count('sex'))  
      ```

    django Q和F查询

    Q查询——对对象的复杂查询
    F查询——专门取对象中某列值的操作

    Q查询
    1、Q对象(django.db.models.Q)可以对关键字参数进行封装,从而更好地应用多个查询,例如:

    from django.db.models import Q
    from login.models import New #models对象
    
    news=New.objects.filter(Q(question__startswith='What'))

    2、可以组合使用&,|操作符,当一个操作符是用于两个Q的对象,它产生一个新的Q对象。

    Q(question__startswith='Who') | Q(question__startswith='What')

    3、Q对象可以用~操作符放在前面表示否定,也可允许否定与不否定形式的组合

    Q(question__startswith='Who') | ~Q(pub_date__year=2005)

    4、应用范围

    Poll.objects.get(
    Q(question__startswith='Who'),
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
    )
    等价于
    SELECT * from polls WHERE question LIKE 'Who%'
    AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')

    5、Q对象可以与关键字参数查询一起使用,不过一定要把Q对象放在关键字参数查询的前面。

    Poll.objects.get(
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
    question__startswith='Who')
    
    错误:
    Poll.objects.get(
    question__startswith='Who',
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))

    四、表关系的建立

    一对一   OneToOneField()

    参数:

    1. to:{_meta}  用于指定关联的Model

    2.on_delete   级联删除

    •         CASCADE:默认值,model对象会和ForeignKey关联对象一起被删除
    •         SET_NULL:将model对象的ForeignKey字段设为null。当然需要将null设为True。
    •         SET_DEFAULT:将model对象的ForeignKey字段设为默认值。
    •         Protect:删除ForeignKey关联对象时会生成一个ProtectedError,这样ForeignKey关联对象就不会被删除了。
    •         SET():将model对象的ForeignKey字段设为传递给SET()的值。
    •         DO_NOTHING:啥也不做

    3.to_field  指定当前关系与被关联对象中的哪个字段关联。默认情况下,to_field 指向被关联对象的主键。

    一对多    ForeignKey()

    参数:

    to:{_meta}  ,on_delete , to_field 同上

    limit_choices_to 它是一个包含筛选条件和对应值的字典,用来在 Django 管理后台筛选 关联对象。

    related_name 反向名称,用来从被关联字段指向关联字段。
                            当一张表的多个字段指向同一张表时,通过另外一张表逆向访问XXX_set属性时无法确定访问到的是哪个属性。这时,我们就需要为每个字段定义一个related_name属性,另外一张表访问这个表时,就会根据related_name的值来得到各个属性了。

    注意:如果Django不需要创建向后关系,只需related_name = '+'或以'+'结尾。当在抽象模型上定义关系时,
                必须设置此值。当这样做时可以使用一些特殊的语法。

    related_query_name 用于来自目标模型的反向过滤器名称的名称。 它默认为related_name或的值

    db_constraint  默认值为 True ,当db_constraint=True时会在数据库上建立外键约束, 在该值为False时不建立约束.

    多对多    ManyToManyField()

    参数:

    to:{_meta}  , to_field ,related_name , limit_choices_to 同上

    注意:当使用 through 手动指定中间表时  limit_choices_to  不起作用

    symmetrical  只要定义递归的多对多关系时起作用。
     
    through  手动指定中间表

    through_fields  接受一个2元组('field1','field2'),其中field1是定义ManyToManyField的模型外键的名称,
                               field2是外键的名称目标模型)。如果在中介模型上有多个外键用于参与多对多关系的任何
                               模型(或甚至两个模型),则必须指定through_fields
     
    db_table  指定数据库中保存多对多关系数据的表名称。如果没有提供该选项,
                    Django 就会根据两个关系表的名称生成一个新的表名,做为中间表的名称。

    例子:

    from django.db import models
    
    
    # Create your models here.
    class Department(models.Model):
        d_id = models.AutoField(primary_key=True)
        d_name = models.CharField(max_length=30)
    
    
    class Student(models.Model):
        s_id = models.AutoField(primary_key=True)
        s_name = models.CharField(max_length=30)
        department = models.ForeignKey('Department', on_delete=models.CASCADE)  # 由于有学生所属学院的关系在,要将这个表与Department表关联在一起,
        # 就可以用外键约束起来,这个department关联的是Department表的id,on_delete表示的是上面的数据删除,这个表也会把相关的数据删除
        #一对多关系用外键约束即可,默认关联表的主键
    
    class Stu_Detail(models.Model):
        s_id = models.OneToOneField('Student',on_delete=models.CASCADE) #一对一关系,用Onetoone;同样要加上on_delete
        age = models.IntegerField()
        gender = models.BooleanField(default=1)
        city = models.CharField(max_length=30)
    
    class Course(models.Model):
        c_id = models.AutoField(primary_key=True)
        c_name = models.CharField(max_length=30)
        student = models.ManyToManyField('Student') #课程表和学生信息表有这多对多的关系,直接用Manytomany来实现关联,会生成一个中间表,不用加on_delete
    因此,整理一下on_delete参数的各个值的含义:
    
    on_delete=None,               # 删除关联表中的数据时,当前表与其关联的field的行为
    on_delete=models.CASCADE,     # 删除关联数据,与之关联也删除
    on_delete=models.DO_NOTHING,  # 删除关联数据,什么也不做
    on_delete=models.PROTECT,     # 删除关联数据,引发错误ProtectedError
    # models.ForeignKey('关联表', on_delete=models.SET_NULL, blank=True, null=True)
    on_delete=models.SET_NULL,    # 删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空,一对一同理)
    # models.ForeignKey('关联表', on_delete=models.SET_DEFAULT, default='默认值')
    on_delete=models.SET_DEFAULT, # 删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值,一对一同理)
    on_delete=models.SET,         # 删除关联数据,
     a. 与之关联的值设置为指定值,设置:models.SET(值)
     b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象
    --------------------- 

    本章完结,有空一起交流

  • 相关阅读:
    Redis 启动失败
    Java本机直接内存溢出
    Java元数据区域(MetaSpace)OOM
    Java虚拟机本地方法栈溢出例子
    Java堆溢出实例
    C# DllImport CallingConvention选择
    光源选型
    条型光的光路分析
    VS安装包官方下载网址
    win7装.net framework4.6注意事项
  • 原文地址:https://www.cnblogs.com/jun-1024/p/10664987.html
Copyright © 2020-2023  润新知