• Django模型


    一、    基本开发流程

    1、       配置数据库

    2、       定义模型类:一个模型类都在数据库中对应一张数据表

    3、       生成迁移文件

    4、       执行迁移文件生成数据表

    5、       使用模型类进行增删改查操作

    二、    ORM

    1、       概述

    将对象转换成SQL,然后使用数据API执行SQL并获取执行结果。ORM表示的是对象-关系-映射。

    2、       作用

    A、      根据对象类型生成表结构

    B、       将对象、列表的操作转换成sql语句

    C、      将sql语句查询到的结果转换为对象、列表

    3、       优点

    极大的减轻了开发人员的工作量,不需要面对因数据库的变更而修改代码

    三、定义模型

    1、模型、属性、表、字段间的关系:

    一个模型类在数据库中对应一张表;在模型类中定义的属性,对应该模型对照表中的字段。

    2、定义属性

        A、概述

             ·django根据属性的类型确定以下信息

              ·当前选择的数据库支持字段的类型

             ·渲染管理表单时使用的默认html控件

             ·在管理站点最低限度的验证

    B、

             ·django会为表增加自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后,则django不会再生成默认的主键列

        C、属性命名限制

             ·遵循标识符规则

             ·由于django的查询方式,不允许使用连续的下划线

        3、库

             定义属性时,需要字段类型,字段类型被定义在django.db.models.fields目录下,为了方便使用,被导入到django.db.models中

             ·使用方式:

                   ·导入from django.db import models

                   ·通过models.Field创建字段类型的对象,赋值给属性

        4、逻辑删除

             ·对于重要数据都做逻辑删除,不做物理删除,实现方法是定义isDelete属性,类型为BooleanField,默认值为False

        5、字段类型

             ·AutoField

                   ·一个根据实际ID自动增长的IntegerField,通常不指定如果不指定,一个主键字段将自动添加到模型中

             ·CharField(max_length=字符长度)

                   ·字符串,默认的表单样式是 TextInput

             ·TextField

                   ·大文本字段,一般超过4000使用,默认的表单控件是Textarea

             ·IntegerField

                   ·整数

             ·DecimalField(max_digits=None, decimal_places=None)

                   ·使用python的Decimal实例表示的十进制浮点数

                   ·参数说明

                         ·DecimalField.max_digits

                              ·位数总数

                         ·DecimalField.decimal_places

                              ·小数点后的数字位数

             ·FloatField

                   ·用Python的float实例来表示的浮点数

             ·BooleanField

                   ·true/false 字段,此字段的默认表单控制是CheckboxInput

             ·NullBooleanField

                   ·支持null、true、false三种值

             ·DateField([auto_now=False, auto_now_add=False])

                   ·使用Python的datetime.date实例表示的日期

                   ·参数说明

                         ·DateField.auto_now

                              ·每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false

                         ·DateField.auto_now_add

                              ·当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false

                   ·说明

                         ·该字段默认对应的表单控件是一个TextInput. 在管理员站点添加了一个JavaScript写的日历控件,和一个“Today"的快捷按钮,包含了一个额外的invalid_date错误消息键

                   ·注意

                         ·auto_now_add, auto_now, and default 这些设置是相互排斥的,他们之间的任何组合将会发生错误的结果

             ·TimeField

                   ·使用Python的datetime.time实例表示的时间,参数同DateField

             ·DateTimeField

                   ·使用Python的datetime.datetime实例表示的日期和时间,参数同DateField

             ·FileField

                   ·一个上传文件的字段

             ·ImageField

                   ·继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image

        6、字段选项

             ·概述

                   ·通过字段选项,可以实现对字段的约束

                   ·在字段对象时通过关键字参数指定

             ·null

                   ·如果为True,Django 将空值以NULL 存储到数据库中,默认值是 False

             ·blanke

                   ·如果为True,则该字段允许为空白,默认值是 False

             ·注意

                   ·null是数据库范畴的概念,blank是表单验证证范畴的

             ·db_column

                   ·字段的名称,如果未指定,则使用属性的名称

             ·db_index

                   ·若值为 True, 则在表中会为此字段创建索引

             ·default

                   ·默认值

             ·primary_key

                   ·若为 True, 则该字段会成为模型的主键字段

             ·unique

                   ·如果为 True, 这个字段在表中必须有唯一值

        7、关系

             ·分类

                   ·ForeignKey:一对多,将字段定义在多的端中

                   ·ManyToManyField:多对多,将字段定义在两端中

                   ·OneToOneField:一对一,将字段定义在任意一端中

             ·用一访问多

                   ·格式

                         ·对象.模型类小写_set

                   ·示例

                         grade.students_set

             ·用一访问一

                   ·格式

                         ·对象.模型类小写

                   ·示例

                         ·grade.students

             ·访问id

                   ·格式

                         ·对象.属性_id

                   ·示例

                         ·student.sgrade_id

    8、元选项

             概念:

                   在模型类中定义Mate类,用于设置元信息

             db_table:

                   定义表名,推荐使用小写字母,默认为项目名(小写)_类名(小写)

             ordering:

                   对象的默认排序字段,获取对象的列表时使用。

                   ordering[‘id’]          :以id升序排列

                   ordering[‘-id’]           :以id降序排列

                   使用排序会增大数据库的开销

    四、模型成员

    1、类属性

        objects:是Manager类的一个对象,作用是与数据库进行交互。

    定义模型类时,没有定义管理器,则默认创建名为objects的管理器。

    2、自定义模型管理器

    格式:自定义名=models.Manager()

    当为模型定义管理器后,Django将不再为模型生成objects模型管理器。

    3、自定义管理器Manager类

    概述:模型管理器是Django的模型进行与数据库进行交互个接口,一个模型可以有多个管理器。

    作用:向管理器类中添加额外的方法;修改管理器返回的原始查询集—重写get_queryset()方法。

    Eg:在models.py文件中

    class StudentsManager(models.Manager):
        def get_queryset(self):
            return super(StudentsManager,self).get_queryset().filter(isDelete=False)#将满足isDelete=False条件的数据取出

     

    五、创建对象

    1、目的

    向数据库中添加数据。当创建对象时,Django不会对数据库进行读写操作,当调用save()方法时,才与数据库交互,将对象保存到数据库中

    2、注意

    __init__方法已经在父类models.Model中使用,在自定义的模型中无法使用

    3、创建方法

    A、定义一个类

    在models.py中写以下代码:

    class Students (models.Model):     #创建数据表
        sname=models.CharField(max_length=20) #定义字段
        sage=models.IntegerField(3)
        sgender=models.CharField(max_length=20)
        @classmethod       #自定义创建对象
        def createStudent(cls,name,age,gengder):
            stu=cls(sname=name,sage=age,sgender=gengder)
            return stu

    在views.py文件中这样写;

    from .models import Students
    
    def addstudent(requset):
    
        stu=Students.createStudent('tom',34,'tom is good !')#参数顺序与创建类时cls中参数顺序对应起来
    
        stu.save()
    
        return render(requset,'addstudent.html')

    B、在模型管理器里创建类

    class StudentsManager(models.Manager):
    
        def creatStudent(self,name,age,content):
    
            stu=self.model()
    
            stu.sname=name
    
            stu.sage=age
    
            stu.scontent=content
    
            return stu

    六、模型查询

    1、概述

    查询集,表示从数据库获取的对象集合。过滤器就是一个函数,基于所给的参数限制查询集结果。查询集可以有多个过滤器。从sql角度来说,查询集合等价于select语句,过滤器等价于where条件。

    2、查询集

    A、概述

    在管理器上调用过滤器方法返回查询集。查询集经过过滤器方法筛选后返回新的查询集,所以可以写成链式调用。

    B、惰式执行

    创建查询集不会带来任何数据的访问,直到调用数据时,才会访问数据库

    C、直接访问数据库的情况

    迭代、序列化、与if合用

    D、过滤器

    过滤器,返回查询集的方法称为过滤器。

    all():返回所有数据    

    Grades.objects.all()

    filter():

             返回符合条件的数据。

             filter(‘键’=‘值’):键是数据表中的字段名,值是条件。返回满足条件的数据

             filter(‘键’=‘值’,‘键’=‘值’):返回同时满足两个条件的数据

             filter(‘键’=‘值’)filter(‘键’=‘值’):同上

    Grands.objects.all().filter(isDelete=False)
    #取出所有的isDelete为False的班级

    exclude():过滤掉符合条件的数据

    Grands.objects.all().exclude(isDelete=False)
    #取出所有的isDelete不为False的班级

    order_by(‘字段名’):以某字段排序

    values():一条数据就是一个对象(字典类),返回一个列表

    E、返回单个数据

    get():返回一个满足条件的对象。注意:如果没有找到符合条件的对象,会引发“模型类.DoesNotExist”异常;如果找到多个对象,会引发“模型类.MultipleObjectsReturned”异常。

    count():返回当前查询集中的对象个数。

    first():返回查询集中的第一个对象

    last():返回查询集中的最后一个对象

    exists():判断查询集中是否有数据,如果有数据则返回True

    F、限制查询集

    查询集返回列表,可以使用下标的方法进行限制,等同于sql中的limit语句。

    eg:

    studentsList=students.objects.all()[0:5]

    注意:下标不能为负数

    G、查询集的缓存

    每个查询集都包含一个缓存,来最小化的对数据库访问;在新建的查询集中,缓存首次为空,第一次对数据集查询求值,会发生数据缓存,Django会将查询出来的数据做一个缓存,并返回查询结构,以后的查询直接使用查询集的缓存。

    F、字段查询

    概述:

    实现了sql中的where语句,作为方法filter()、exclude()、get()的参数。

    语法:

    属性名称__比较运算符=值

    外键:

    属性名_id

    转义:

    比较运算符:

    exact:判断,区分大小写

    contains:是否包含,区分大小写

    eg:views.py

    def studentsearch(request):
    
    studentList=Students.objects.filter(sname_contains='孙')#查询Student数据表中sname字段值中包含‘孙’的值
    
        return rander(request,'news.html',{"students":studentList})

    startswith(value),endswith(value):以value开头或结尾,区分大小写

    eg:views.py

    def studentsearch(request):
    
        studentList=Students.objects.filter(sname_startswith='孙') #查询Student数据表中sname字段值中以‘孙’开头的值
    
        return rander(request,'news.html',{"students":studentList})

    注意:以上四个在前面加上i,表示不区分大小写。iexact,icontains,istartswith,iendswith。

    isnull、isnotnull:

    判断是否为空。和以上几个使用方法一致:属性名__isnull=False)

    eg: 

    studentList=Students.objects.filter(sname__insnull=False)
    #返回所有名字非空的学生的列表

    in:

    是否在内。

    eg:

    filter(pk__in=[2,4,6,8,10])  #找出pk为[2,4,6,8,10]中的值的

    gt:大于

    eg:

    filter(sage__gt=30)   #找出年龄大于30的

    gte:大于等于

    lt:小于

    lte:小于等于

    year:年

    month:月

    day:天

    week_day

    minute:分

    second:秒

    G、查询快捷

    PK:代表主键

    H、聚合函数 【使用aggregate()函数返回聚合函数的值】

    Avg():取平均值

    Count():返回数据的个数

    Max():返回该字段的最大值

    Min():返回该字段的最小值

    Sun():返回该字段的和

    #需要引入
    from django.db.models import Max
    maxAge=Students.stuObj2.aggregate(Max('sage'))
    print maxAge
    
    #聚合函数返回的是一个值,不是一个对象,也不是一个列表

    I:跨关联查询

    处理join查询。语法:模型类名__属性名__比较运算符。

    eg:返回描述中带有“孙红雷”这三个字的的数据属于哪个班级

    grade=Grades.objects.filter(students__scontend__contains='孙红雷')

    Grades:年级数据表,该表中有班级字段

    students:学生数据表,该表中有描述字段“scontend”

    contains:比较运算符,包含

    J、F对象

    使用模型A的属性与模型B属性进行比较,实际上是一条数据的两个值进行比较。

    F对象支持算数符运算。

    eg:views.py     取出女生人数比男生人数多的数据

    from django.db.models import F
    
    def grades(request):  
    
    #取出女生人数比男生人数多的数据g=Grades.objects.filter(ggirlnum__gt=F('gboynum'))
    
    #取出女生人数大于男生人数加20后的数据
    
    gb=Grades.objects.filter(ggirlnum__gt=F('gboynum'+20))
    
        print(g)
    
        print(g)

    Grades:年级数据表

    ggirlnum:字段,女生人数

    gt:比较运算符,大于

    gboynum:字段,男生人数

    K、Q对象

    进行或查询。

    eg:views.py

    from django.db.models import Q
    def grades(request):
        #取出主键值小于3或sage大于18的所有值
    
    s=Students.objects.filter(Q(PK__lte=3)|Q(sage__gt=18))#
        print(s)

    七、外键的添加

    models.py

    class A(models.Model):
        title = models.CharField(max_length=20)
    
    
    class B(models.Model):
        bname = models.CharField(max_length=20)
        fk = models.ForeignKey(A, on_delete=models.DO_NOTHING)

    views.py

    from .models import *
    
    # 方法一
    B.objects.creat(bname='test', fk=A.object.get(id=1))
    # 方法二
    B.objects.creat(bname='test', fk_id=1)
  • 相关阅读:
    drf之版本控制
    drf自定义筛选
    drf----分页
    初识drf
    flask源码分析01:框架简介
    Werkzeug之LocalStack源码解析
    Werkzeug之Local源码解析
    threading.local之数据存储隔离
    python之attr
    Python在pycharm中编程时应该注意的问题汇总
  • 原文地址:https://www.cnblogs.com/catxjd/p/9012964.html
Copyright © 2020-2023  润新知