2021-09-14

本文详细介绍了Django框架如何与数据库交互,包括Django对多种数据库的支持、配置数据库、开发流程、ORM概念及优势。重点讲解了模型定义、字段类型、查询集的使用以及如何进行数据的增删改查。同时,提到了模型元选项、自定义管理器、查询字段的各种操作,如过滤、排序、聚合函数等。此外,还讨论了索引的创建和数据的修改与删除操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、Django对各种数据库提供了很好的支持

Django为这些数据库提供了统一的调用API,可以根据不同的业务需求选择不同的数据库

2、配置数据库

1. 修改工程目录下的__init__.py文件
import pymysql
pymysql.install_as_MySQLdb()

3、开发流程

1.配置数据库
2.定义模型类--一个模型对应一张数据表
3.生成迁移文件
4.执行迁移生成数据表
5.使用模型类进行增删改查操作

4、ORM

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0KIOgy28-1631578012064)(C:\Users\My\AppData\Roaming\Typora\typora-user-images\image-20210815104825780.png)]

1.定义:对象-关系-映射
2.任务:
	a、根据对象的类型生成表结构
    b、将对象、列表的操作转换为sql语句
    c、将sql语句查询到的结果转换为对象、列表
3.优点:极大减轻了开发人员的工作量,不需要面对因数据库的变更而修改代码

5、定义模型

模型、属性、表、字段间的关系:一个模型类在数据库中对应一张表,在模型类中定义的属性,对应该模型对照表中的一个字段
定义属性:
    概述
        -django根据属性的类型确定以下信息
            ·当前选择的数据库支持字段的类型
            ·渲染管理表单时使用的默认html控件
            ·在管理站点最低限度的验证
        -django会为表增加自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后,则django不会再生成默认的主键列
        -属性命名限制
            ·遵循标识符规则
            ·由于django的查询方式,不允许使用连续的下划线
    库
    	-定义属性时,需要字段类型,字段类型被定义在django.db.models.fields目录下,为了方便使用,被导入到django.db.models中
        -使用方式
            ·导入from django.db import models
            ·通过models.Field创建字段类型的对象,赋值给属性
	逻辑删除
		-对于重要数据都做逻辑删除,不做物理删除,实现方法是定义isDelete属性,类型为BooleanField,默认值为False
	字段类型
		-AutoField
			·一个根据实际ID自动增长的IntegerField,通常不指定如果不指定,
			·一个主键字段将自动添加到模型中
		-CharField(max_length字符长度)
            ·字符串,默认的表单样式是TextInput
        -TextField
            ·大文本字段,一殷超过4000使用,默认的表单控件是Textarea
        -IntegerField
        	·整数
        -DecimalField(max _digits None,decimal placesNone)
            ·使用python的Decimal实例表示的十进制浮点数
            ·参数说明
            	·DecimalField.max digits
    				·位数总数
            	·DecimalField.decimal_places
                	.小数点后的数字位数
        -FloatField
        	·用Python的float实例来表示的浮点数
        -BooleanField
        	·true/false字段,此字段的默认表单控制是CheckboxInput
        -Nul1BooleanField
        	·支持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这些设置是相i排斥的,他们之间的任何组合将会发生错误的结果
        -TimeField
        	·使用Python的datetime.time实例表示的时间,参数同DateField
        -DateTimeField
        	·使用Python的datetime.
			datetime实例表示的日期和时间,参数同DateField
        -FileField
        	.一个上传文件的字段
        -ImageField
        	·继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image
    字段选项
        概述
        	-通过字段选项,可以实现对字段的约束
        	·在字段对象时通过关键字参数指定
        -null
        	·如果为True,Django将空值以NULL存储到数据库中,默认值是False
        -blanke
        	-如果为True,则该字段允许为空自,默认值是 False
        -注意
        	-null是数据库范畴的概念,blank是表单验证证范畴的
        -db_column
        	·字段的名称,如果未指定,则使用属性的名称
        -db_index
        	·若值为True,则在表中会为此字段创建索引
        -default
        	·默认值
        -primary key
        	·若为True;则该字段会成为模型的主键字段
        -unique
        	-如果为True,这个字段在表中必须有唯一值
    关系
        ·分类
            -ForeignKey一对多,将字段定义在多的端中
            -ManyToManyField:多对多,将字段定义在两端中
            -Oneto0neField:一对一,将字段定义在任意一端中
        -用一访问多
            -格式
            	·对象.模型类小写_set
            ·示例
            	grade.students_set !
        ·用一访问一
            -格式
            	-对象.模型类小写
            ·示例
            	-grade.students
        ·访问id
            -格式
            	-对象.属性_id
            -示例
            	-student.sgrade_id

6、创建模型类

7、元选项Meta类

1. 在模型类中创建Meta类,用于设置元选项
2. db_table:定义数据库表名
3. ordering:['id']   ['-id']根据某字段排序,排序会增加资源使用率

8、模型成员

1、模型类的属性:

  1. objects:默认管理器
    1. 是Manager类型的一个对象,作用是与数据库交互
    2. 当定义模型类没有指定管理器,则Django为模型创建一个名为objects的管理器

  2. 自定义管理器

    class Students(models.Model):
    	# 当为模型指定模型管理器,Django就不在为模型类生成objects模型管理器
        # 自定义管理器
        stuObj = models.Manager()
    
  3. 自定义管理器Manager类

    1. 模型管理器是Django的模型进行与数据库进行交互的接口,一个模型可以有多个模型管理器
    2. 作用:
      1. 向管理器类中添加额外的方法
      2. 修改管理器返回的原始查询集,重写get_queryset()方法
class StudentsManager(models.Manager):
    def get_queryset(self):
        # super()方法是调用父类的方法
		return super(StudentsManager,self).get_queryset().filter(idDelete=False)
class Students(models.Model):
    #自定义模型管理
    #当自定义模型管理器,objects就不存在了
    stuObj = models.Manager()
    stuObj2 = StudentsManager()

2、创建对象

  1. 创建对象目的:向数据库中添加数据

  2. 当创建对象时,django不会对数据库进行读写操作,当调用save()方式时才与数据库交互,讲对象保存到数据库表中

  3. 创建对象注意:

    __init__方法已经在父类models.Model中使用,在自定义的模型中无法使用
    
  4. 创建对象方法(两种方法)

    1. 在模型类中增加一个类方法# 需要在函数上加装饰器@classmethod,注明是类方法

      class Students(models.Model):
      	@classmethod
          def createStudent(cls,name,age,gender,contend,grade,lastTime,createTime,
          isDelete=False): # cls就相当于是Students类
              stu = cls(sname = name,sage = age,sgender = gender,
              scontend = contend,sgrade = grade,supdateTime = lastTime,
              screateTime = createTime,isDelete = isDelete)
              return stu
      
    2. 在自定义管理器中添加方法

      class StuManager(models.Manager):# 自定义Students管理器
          def createStudent(self,name,age,gender,contend,grade,updateTime,
          createTime,isDelete=False):
              stu = self.model() # 实例对象,Students对象
              stu.sname=name
              stu.sage = age
              stu.sgender = gender
              stu.scontend = contend
              stu.sgrade = grade
              stu.supdateTime = updateTime
              stu.screateTime = createTime
              stu.isDelete =isDelete
              return stu
      
      

9、模型查询

1、概述

  1. 查询集表示从数据库获取的对象集合
  2. 查询集可以有多个过滤器
  3. 过滤器就是一个函数
  4. 从sql的角度来说,查询集合select语句等价,过滤器就等价于where条件

2、查询集

1、在管理器上调用过滤方法,返回查询集

2、查询集经过过滤器筛选后,返回新的查询集,所以可以写成链式调用

3、惰性执行

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

    # 这里只是创建了查询集,不会访问数据库
    books = BookInfo.objects.all()
    # 遍历books的时候才会访问数据库查询
    for book in books:
    	print(book.name)
    

4、如下情况才会直接访问数据库

  1. 迭代
  2. 序列号
  3. 与if合用

5、返回查询集的方法成为过滤器(返回多条数据)

  1. all()

    1. 返回查询集中的所有数据,返回的是一个对象

      Grades.objects.all()
      
  2. filter()

    1. 保留符合条件的数据

    2. filter(键=值)

    3. filter(键=值,键=值)----或

    4. filter(键=值).filter(键=值)-----且

      Grades.objects.filter(gname='class01')
      
  3. exclude() # 过滤掉符合条件的数据

    Grades.objects.exclude(gname='class01')
    
  4. order_by() # 排序

    Grades.objects.order_by('pk')
    
  5. values()

    1. 一条数据就是一个对象(字典),返回一个列表
    2. 用法与all()差不多,返回的是具体的值,all()是一个对象,看不到具体的值

6、返回单个数据

  1. get():只能返回一个值,为空或者返回多个都会报错
    1. 返回一个满足条件的对象(返回对象中定义__str__方法的内容)
    2. 注意:
      1. 如果没有找到符合条件的对象,模型类会引发异常(DoesNotExist)
      2. 如果找到多个对象,模型类也会引发异常(MultipleObjectsReturned)
  2. count()
    1. 返回当前查询集对象的个数
  3. first()
    1. 返回查询集中的第一个对象
  4. last()
    1. 返回查询集中的最后一个对象
  5. exists()
    1. 判断查询集中是否有数据,有数据返回True

7、限制查询集

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

  2. 下标不能是负数

    def stufenye1(request, page):  # 分页显示学生
        print(stufenye1)
        page = int(page)
        stu = Students.stuObj.all()[(page - 1) * 5:page * 5]
        return render(request, 'myApp/students.html', {'students': stu})
    

8、查询集的缓存(需要看看开发文档)

  1. 概述:
    1. 每个查询集都包含一个缓存,来最小化的对数据库访问
    2. 在新建的查询集中,缓存首次为空,第一次对查询集求值,会发生缓存,django会将查询出来的数据做一个缓存,并返回查询结果,以后的查询直接使用查询集的缓存
  2. 参考:https://blog.youkuaiyun.com/weixin_43835542/article/details/108379434

9、字段查询

  1. 概述
    1. 实现了sql中的where语句,方法filter(),exclude(),get()的参数
    2. 语法:属性名称_比较运算符=值
    3. 外键:属性名_id
    4. 转义:
      1. 类似SQL中的like语句
  2. 比较运算符
    1. exact

      1. 全匹配,判断,大小写铭感
      2. 例如:filter(isDelete=True) filter(isDelete__exact=True)
    2. contains:是否包含,大小写敏感 filter(sname__contains=‘王’)

    3. startswith、endswith:以value开头或者结尾的,如:

      filter(sname__startswith='刘')   filter(sname__endswith='凡')
      
    4. 以上四个在前面加上i,就表示不区分大小写:iexact、icontains、istartswith、iendswith

    5. isnull、isnotnull:是否为空,如filter(sname__isnull=False)

      只有数据库保存null时,判断结果才为True
      
    6. in:包含在list里面,如filter(sname__in=[‘王伟’,‘王一凡’])

    7. gt/gte/lt/lte:大于/大于等于/小于/小于等于,如filter(pk__gt=10)

    8. year/month/day/week_day/hour/minute/second:时间,如filter(createtime__year=2017)

    9. 跨关联查询–处理join查询–语法:

    10. 查询快捷:pk代表主键

  3. 聚合函数,需要引入包from django.db.models import Avg,Count,Max,Min,Sum
    1. 使用aggregate()函数返回的值,如

      Grades.objects.aggregate(Avg(ggrilnum))
      
    2. Avg

    3. Count

    4. Max

    5. Min

    6. Sum

  4. F对象,需要引入包from django.db.models import F
    1. 可以使用模型的A属性和B属性做比较,如查询女生数量大于男生数量的数据filter(ggirlnum__gt=F(‘gboynum’))
    2. 支持F对象的算数运算,如如查询女生数量大于(男生数量加2)的数据filter(ggirlnum__gt=F(‘gboynum’)+2)
    3. 可以做一个时间的加减
  5. Q对象,需要引入包from django.db.models import Q
    1. 概述:过滤器的方法中的关键字参数,条件为And模式

    2. 需求:进行or查询

    3. 解决:使用Q对象

      def qqq(request):
          # stu = student.stuobj.get(Q(sname__startswith='t') & Q(sage=18)) # and
          # stu = student.stuobj.get(Q(sname__startswith='t') , Q(sage=18)) # and
          stu = student.stuobj.filter(Q(sname__startswith='t') | ~Q(sage=18) ) # or 非
          return render(request,'index.html',{'stu':stu})
      

10、模型字段索引

  1. 概述:索引就像是文档目录,方便快速查找到相应数据,但是添加索引会占用资源,增加服务器压力

  2. 字段选项添加

    	title = models.CharField('标题', max_length=200, db_index=True)
    
  3. Meta元数据中添加

    class Meta:        
    		indexes = [models.Index(fields=['title']),]
    

11、修改和删除数据

  1. 查询出数据直接修改(update())、删除(delete())

        Students.stuObj1.get(pk = num).delete()
    
  2. 查询出数据,然后实例化,修改、删除

        stu = Students.stuObj1.get(pk = num).delete()
        stu.delete()
    
  3. 注意:update的时候,不能用get筛选数据,可以用filter

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值