美文网首页
Django - 02-Django模型

Django - 02-Django模型

作者: 找呀找提莫 | 来源:发表于2020-03-06 13:36 被阅读0次

[toc]

1 模型

Django对各种数据库都提供了很好的支持,Django为这些数据库提供了统一的调用API,可以根据不同的业务需求,选择不同的数据库;

1.1 开发流程

配置数据库:
        python3.x 安装的是PyMySQL; python2.x 安装的是mysql-python
        
        在工程目录下的__init__.py写入两行代码
                import pymysql
                pymysql.install_as_MySQLdb()
            
        配置 settings.py
                DATABASES = {
                    'default': {
                        'ENGINE': 'django.db.backends.mysql',
                        'NAME': 'class',
                        'USER': 'root',
                        'PASSWORD': 'admin',
                        'HOST': '192.168.23.128',
                        'PORT': '3306',
                    }
                }


定义模型类
        一个模型类都在数据库中队形一张数据表;

生成迁移文件

执行迁移

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

1.2 ORM

1.2.1 概述

对象-关系-映射

1.2.2 任务

  • 根据对象类型生成表结构;
  • 将对象、列表的操作转换为SQL语句;
  • 将SQL语句查询到的结果转换为对象、列表;

1.2.3 优点

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

1.2.4 图解

graph TD
    A[Django] 
    B[ORM]
    C1[MySQL]
    C2[sqlite]
    C3[Oracle]

1.3 定义模型

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

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

1.3.2 定义属性

1. 概述

  • Django根据属性的类型确定以下信息:
    • 当前选择的数据库支持字段的类型;
    • 渲染管理表单时使用的默认html控件;
    • 在管理站点最低限度的验证;
  • Django会为表增加自动增长的主键列;
    每个模型只能有一个主键列;
    如果使用选项设置某属性为主键列后,则Django不会再生成默认的主键列;
  • 属性命名限制:
    • 遵循标识符规则
    • 不能是python的保留关键字;
    • 由于Django的查询方式,不允许使用连续的下划线;

2. 库

  • 定义属性时,需要字段类型,字段类型被定义在 django.db.models.fields 目录下;
    为了方便使用,被导入到 django.db.models 中;
  • 使用方式:
    • 导入: from django.db import models
    • 通过 models.Field 创建字段类型的对象,赋值给属性;

3. 逻辑删除

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

4. 字段类型

字段类型(字段选项)

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

CharField(max_length=字符长度)
        字符串,默认表单样式是 TextInput;

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

IntegerField
        整数类型;

DecimaField(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;<br>在管理员站点添加了一个 JavaScrtpt 写的日历控件,和一个“Today”的快捷按钮;<br>包含了一个额外的 invalid_date 错误消息键;
        注意:
                auto_now、auto_now_add、default 这些设置是相互排斥的,他们之间的任何组合都将会发生错误的结果;

TimeField
        使用 python 的 datetime.time 实例表示的时间,参数同 DateField;

DateTimeField
        使用 python 的 datetime.datetime 实例表示的日期和时间,参数同 DateField;


FileField
        一个上传文件的字段;


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

5. 字段选项

字段类型(字段选项)

概述:
        通过字段选项,可以实现对字段的约束;
        在字段对象时,通过关键字参数指定;

null
        null = True     一般不写
        如果为 True,Django 将空值以 NULL 存储到数据库中,默认值是 False;

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

注意:null 是数据库范畴的概念;blank 是表单验证范畴的概念;


db_column
        sage = models.IntegerField(db_column='age')     指定这个字段再数据库中名字是age 
        字段的名称,如果未指定,则使用属性的名称;

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

default
        默认值

primary_key
        若为True,则该字段会成为模型的主键字段;
        
unique
        如果为True,则该字段再表中必须有唯一值;

6. 关系

分类:
        Foreignkey:一对多,将字段定义在多的端中
                Grades 和 Students 是一对多关系,Foreignkey定义在Students中;
        ManyToManyField:多对多,将字段定义在两端中;
        OneToOneField:一对一,将字段定义在任意一端中;
        
        
用一访问多:
        格式: 对象.模型类小写_set
        示例: grade.student_set

用一访问一:
        格式: 对象.模型类小写
        示例: grade.student

访问id:
        格式: 对象.属性_id
        示例: student.sgrade_id

1.3.3 创建模型类

1.3.4 元选项

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

        class Grade(models.Molde):
            class Meat:
                db_table='students'     # 定义数据表名,推荐使用小写字母,数据表名默认为:项目名小写_类名小写
                ordering=['id']           # 对象的默认排序字段,获取对象的列表时使用
                        ordering=['id]      # 按id字段升序排列
                        ordering=['-id']    # 按id字段降序排列
                        注意: 排序会增加数据库开销

    
示例:
        class Student(models.Model):
            sname = models.CharField(max_length=20)
            sgender = models.BooleanField(default=True)
            sage = models.IntegerField()
            scontend = models.TextField()
            isDelete = models.BooleanField(default=False)
            sgrade = models.ForeignKey('Grade')
        
            def __str__(self):
                return self.sname
            
            lasttime = models.DateTimeField(auto_now=True)
            createtime = models.DateTimeField(auto_now_add=True)
            
            class Meta:
                db_table = 'student'
                ordering = ['id']

1.4 模型成员

1.4.1 类属性

objects
        是Manager类型的一个对象,作用是与数据库进行交互;
        当定义模型类时,没有指定管理器,那么Django为模型创建一个名为objects的管理器;
        
        
自定义管理器:
        class Student(models.Model):
            # 自定义模型管理器
            stuObj = models.Manager()
        
        stu = Student.stuObj.get(pk=1)
        
        当为模型指定模型管理器,Django就不在为模型类生成objects模型管理器;
        
        
自定义管理器Manager类:
        模型管理器是Django的模型进行与数据库进行交互的接口;一个模型类可以有多个模型管理器;
                stuObj = models.Manager()
                stuObj1 = models.Manager()
                
        作用:
                向管理器类中添加额外的方法
                修改管理器返回的原始查询集      重写get_queryset()方法
                
        示例: 查询Student表中 isDelete=Flase的内容
                class StudentManager(models.Manager):
                    def get_queryset(self):
                        return super(StudentManager, self).get_queryset().filter(isDelete=False)
                
                class Student(models.Model):
                    # 自定义模型管理器
                    stuObj = models.Manager()
                    stuObj2 = StudentManager()

1.4.2 创建对象

目的:
        项数据库添加数据
        
当创建对象时,Django不会对数据库进行读写操作;
当调用save时,才与数据库有交互,将对象保存到数据库中;

注意:
        __init__() 方法已经在父类models.Model中使用,在自定义的模型中无法使用;
        
方法:
        1. 在模型类中增加一个类方法;
                class Student(models.Model):
                    # @classmethod 表明是类方法
                    @classmethod
                    def createStudents(cls, name, gender, age, contend, isD=False):
                        stu = cls(sname = name,
                                    sgender = gender,
                                    sage = age,
                                    scontend = contend,
                                    isDelete=isD)
                        return stu
            #-------------------------------------------------------------------------------
                # views.py
                def addStudent(request):
                    grade = Grade.objects.get(pk=1)
                    stu = Student.createStudents("刘德华", True, 34, '我叫刘德华', grade)
                    stu.save()
                    return HttpResponse('Yeah')
            #-------------------------------------------------------------------------------
                # urls.py
                url(r'^addstudent/$', views.addStudent),
                        
        2. 在自定义管理器中添加一个方法
                class StudentManager(models.Manager):
                    def createStudent(self, name, gender, age, contend, grade, isD=False):
                        stu = self.model()
                        stu.sname = name
                        stu.sgrade = gender
                        stu.sage = age
                        stu.scontend = contend
                        stu.sgrade = grade  
                        return stu

1.4.3 模型查询

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

查询集:
        在管理器调用过滤器方法,返回查询集;
        查询集经过过滤器筛选后,返回新的查询集,所以可以写成链式调用;
        
        惰性执行:
                创建查询集不会带来任何数据库的访问,直到调用数据时们才会访问数据;
            
        直接访问数据的情况:
                迭代
                序列化
                与if合用
                
        返回查询集的方法称为过滤器:
                all()           返回查询集中所有的数据的对象;
                
                filter()
                        返回符合条件的数据;
                        filter(键=值, 键=值)
                        filter(键=值).filter(键=值)
                        
                exclude()       过滤掉符合条件的数据
                
                order_by()      排序
                
                values()        以条数据就是一个字典,返回一个列表;
                
        返回单个数据:
                get()
                        返回一个满足条件的对象;
                        注意:
                                如果没有找到符合条件的对象,会引发 "模型类.DoesNotExist" 异常;
                                如果找到多个对象,会引发 "模型类.MultipleObjectsReturned" 异常;
                count()     返回当前查询集中的个数;
                first()     返回当前查询集中的第一个对象;
                last()      返回当前查询集中的最后一个对象;
                exists()    判断查询集中是否有数据,有则返回True;
                
        限制查询集:
                查询集返回列表,可以使用下标来进行限制,等同于 SQL 的 limit 语句;
                        def student3(request):
                            studentList = Student.stuObj.all()[0:3]
                            return render(request, 'myapp/student.html', {'student': studentList})
                
                注意:下标不能是负数;
                
                需求:分页显示学生信息
                url.py
                    url(r'^stupage/(\d)/$', views.stupage),
                    
                views.py
                    def stupage(request, page):
                        # 0-3  3-6  6-9
                        #  1    2    3
                        page = int(page)
                        studentList = Student.stuObj.all()[(page-1)*3: (page*3)]
                        return render(request, 'myapp/student.html', {'student': studentList})
        
        查询集的缓存:
                概述:
                        每个查询集都包含一个缓存,来最小化对数据库访问;
                        在新建的查询集中,缓存首次为空,第一次对查询集求值,会发生数据缓存;
                        Django会将查询的数据做一个缓存,并返回查询结果,以后查询直接使用查询集的缓存;
        
        字段查询:
                概述:
                        实现了 SQL 中的 where 语句,作为方法filter()、exclude()、get()的参数
                        语法:  
                                属性名称__比较运算符=值
                        外键:  
                                属性名_id
                        转义:  
                                like 语句使用%是为了匹配占位,匹配数据中的% (where like '\%')
                                filter(sanme_cotains='%')
                                
                比较运算符:
                        exact
                                判断,大小写敏感(区分大小写)
                                filter(isDelete=False)
                        
                        contans
                                是否包含,大小写敏感
                                studentList = Student.stuObj.all().filter(sname__contains='张')
                        
                        startswith、endswith
                                以value开头或者结尾,大小写敏感
                                studentList = Student.stuObj.all().filter(sname__startswith='张')
                        
                    以上四个在参数前加 i 就表示不区分大小写:iexact、icontans、istartswith、iendswith
                    
                        isnull、isnotnull
                                是否为空
                            
                        in
                                是否包含在范围内
                                studentList = Student.stuObj.all().filter(pk__in=[2,4,6,8])
                        
                        gt      大于
                        gte     大于等于
                        lt      小于
                        lte     小于等于
                                studentList = Student.stuObj.all().filter(sage__gt=20)
                                
                        year
                        month
                        day
                        week_day
                        hour
                        minute
                        second
                                给datetime、date、time类型的字段使用
                                
                        跨关联查询
                                处理join查询
                                        语法:
                                                模型类名__属性名__比较运算符
                                                grade = Grade.objects.filter(student__scontend__contains='刘德华')
                                                print(grade)
                                                描述中带有刘德华的班级的内容
                        
                        查询快捷
                                pk      代表主键
                    
                        
                聚合函数:
                        使用aggregate()函数返回聚合函数的值;
                        Avg
                        Count
                        Max
                        Min
                        Sum
                                from django.db.models import Max
                                def studentSearch(request):
                                    maxAge = Student.stuObj.aggregate(Max('sage'))
            
                F对象
                        可以使用模型的 A属性 与 B属性 进行比较
                                from django.db.models import F
                                def grades(request):
                                    g = Grades.object.filter(ggirlnum__gt=F('gboynum'))
                                    print(g)
                                return HttpResponse('女生比男生数多的班')
                        支持F对象的算数运算
                                g = Grades.object.filter(ggirlnum__gt=F('gboynum')+10)
                        
                        支持F对象的时间的运算
                
                Q对象
                        概述:  过滤器的方法中的关键字参数,条件为and模式
                        需求:  进行or查询
                        解决:  使用Q对象
                                studentList = Student.stuObj2.filter(Q(pk__lt=5) | Q(sage__gt=20))
                                studentList = Student.stuObj2.filter(Q(pk__lt=5))       只有一个Q对象,就是用于匹配的;
                                studentList = Student.stuObj2.filter(~Q(pk__lt=5))      ~   取反

1.4.4 删、改

删
        对象名.del()
改
        对象名.save()

相关文章

  • Django - 02-Django模型

    [toc] 1 模型 Django对各种数据库都提供了很好的支持,Django为这些数据库提供了统一的调用API,...

  • 02-django的基本使用(模型)

    ORM框架(将类和数据表进行对应起来)Object:对象-类Mapping:映射Relations 关系通过类和对...

  • 02-Django基本流程

    一、Django简介 Django是用Python开发的一个免费开源的Web框架,可以用于快速搭建高性能,优雅的网...

  • 02-Django基本流程

    一、Django简介 Django是用Python开发的一个免费开源的Web框架,可以用于快速搭建高性能,优雅的网...

  • 02-Django基本流程

    一、Django简介 Django是用Python开发的一个免费开源的Web框架,可以用于快速搭建高性能,优雅的网...

  • 02-Django基本流程

    一、Django简介 Django是用Python开发的一个免费开源的Web框架,可以用于快速搭建高性能,优雅的网...

  • Django模型之meta选项详解

    Django模型之meta选项详解 Django模型类的Meta是一个内部类,它用于定义一些Django模型类的行...

  • Python学习打call第五十七天:Django Model

    Django Model 模型 Django Model层是Django的数据模型层,每一个Model类就是数据库...

  • Django模型层基本概念

    所有Django模型继承类通过类属性定义模型字段,如:models...

  • 2019-04-03 User模型

    重写django User 模型

网友评论

      本文标题:Django - 02-Django模型

      本文链接:https://www.haomeiwen.com/subject/xlxirhtx.html