django基础

    科技2026-10-02  1

    Day02

    学习目标

    修改数据库Django shell数据级联(一对多)元信息定义字段模型过滤创建对象4种方式查询集 过滤器获取单个对象字段查询时间聚合函数跨关系查询F对象Q对象

    学习课程

    1.修改数据库

    ① 在settings中的DATABASES中进行修改
    ‘ENGINE’: ‘django.db.backends.mysql’,’NAME‘ : 数据库名字’USER‘: 用户名字’PASSWORD‘:密码’HOST‘: 主机’PORT‘: 端口号 注意:引号加不加“”都可以 注意迁移时驱动问题: mysqlclient:python2,3都能直接使用,致命缺点-对mysql安装有要求,必须指定位置存在配置文件 mysql-python:- python2 支持很好,- python3 不支持。 pymysql:会伪装成mysqlclient和mysql-python,- python2, python3都支持init中 import pymysql pymysql.install_as_mysqldb()

    2.Django Shell

    了解(当项目较大时运行不方便可以使用django shell) 使用:django 终端,python manager.py shell 集成了django环境的python 终端 通常用来调试 from Two.models import Student students = Student.objects.all() for student in students: print(students.name)

    3.数据级联

    一对多

    添加数据时先添加主表的数据,然后再添加从表的数据, 删除数据的时候先删除从表的数据,再删除主表的数据。 dept 部门表:主表 emp 员工表:从表 两张中有级联关系 带主键的表是主表 带外键的表是从表 关联关系放在从表 (团员找班长--> 快) sql的优化 一对多模型关系: class Grade(models.Model): g_name = models.CharField(max_length=32) class Student(models.Model): s_name =models.CharField(max_length=16) s_grade=models.ForeignKey(Grade) 案例:(1).多方获取一方,根据学生找班级名字 显性属性:就是你可以在中直接观察到的属性---》通过多方获取一方 那么可以使用多方调用显性属性直接获取一方数据 student = Student.objects.get(pk=2) grade = student.s_grade return HttpResponse(grade.g_name) (2).一方获取多方,根据班级 找所有的学生 隐性属性:就是我们在类中观察不到的,但是可以使用的属性---》通过一方获取多方 那么可以使用一方数据的隐性属性 获取多方数据 grade = Grade.objects.get(pk=2) students = grade.sutdent_set.all() content = { 'students':students } return render(request,'students_list.html',content)
    各大框架filter的数据返回类型
    # flask(BaseQuery) tornado(Query) django(QuerySet) django中的filter结果 <QuerySet [<Emp: Emp object>]> 是一个列表 def getDname(rquest): emp = Emp.objects.filter(name='迪丽热巴')[0] print(emp.e_dept.name) # 拿到员工所对应的主表中的部门的名称 return HttpResponse('查询成功')
    一对多的查询
    # 主表 class Dept(models.Model): name = models.CharField(max_length=32) # 从表 class Emp(models.Model): name = models.CharField(max_length=32) e_dept = models.ForeignKey(Dept) 1. 通过从表查询主表的数据,显性属性 使用从表的对象emp 调用e_dept属性 2. 通过主表查询从表的数据,隐性属性 使用主表的对象dept 调用 emp_set(从表的模型的小写_set)属性 # 通过从表查询主表 def getDname(rquest): emp = Emp.objects.filter(name='迪丽热巴')[0] print(emp.e_dept.name) return HttpResponse('查询成功') # 通过主表查询从表 def getEname(request): dept = Dept.objects.filter(name='开发部门')[0] emps = dept.emp_set.all() for emp in emps: print(emp.name) print(emp.id) return HttpResponse('查询成功')

    4.元信息

    class Meta:指定表名和字段名字 db_table = '表名' 注意:表的字段一般都是下划线 eg:s_name 类的属性一般都是驼峰式 eg: sName

    5.定义字段

    字段类型:CharField,TextField,IntegerField,FloatField,BooleanField,DecimalField,NullBooleanrField,AutoField,FileField,ImageField 字段约束:max_length,default,unique,index,primary_key,db_column
    模型属性类型
    定义属性 概述 ·django根据属性的类型确定以下信息 ·当前选择的数据库支持字段的类型 ·渲染管理表单时使用的默认html控件 ·在管理站点最低限度的验证 ·django会为表增加自动增长的主键列,每个模型只能有一个主键列, 如果使用选项设置某属性为主键列后, 则django不会再生成默认的主键列 ·属性命名限制 ·遵循标识符规则 ·由于django的查询方式,不允许使用连续的下划线 库 ·定义属性时,需要字段类型,字段类型被定义在 django.db.models.fields目录下,为了方便使用, 被导入到django.db.models中 ·使用方式 ·导入from django.db import models ·通过models.Field创建字段类型的对象,赋值给属性 逻辑删除 ·对于重要数据都做逻辑删除,不做物理删除, 购物车使用物理删除 实现方法是定义isDelete属性,类型为BooleanField,默认值为False 字段类型 ·AutoField(IntegerField的子类 6) ·一个根据实际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 上两个字段依赖pillow 字段选项 ·概述 ·通过字段选项,可以实现对字段的约束 ·在字段对象时通过关键字参数指定 ·null ·如果为True,Django 将空值以NULL 存储到数据库中,默认值是 False ·blank ·如果为True,则该字段允许为空白,默认值是 False ·注意 ·null是数据库范畴的概念,blank是表单验证证范畴的 ·db_column ·字段的名称,如果未指定,则使用属性的名称 ·db_index ·若值为 True, 则在表中会为此字段创建索引 ·default ·默认值 ·primary_key ·若为 True, 则该字段会成为模型的主键字段 ·unique ·如果为 True, 这个字段在表中必须有唯一值 关系 ·分类 ·ForeignKey:一对多,将字段定义在多的端中 ·ManyToManyField:多对多,将字段定义在两端中 ·OneToOneField:一对一,将字段定义在任意一端中 ·用一访问多 ·格式 ·对象.模型类小写_set ·示例 grade.students_set ·用一访问一 ·格式 ·对象.模型类小写 ·示例 ·grade.students ·访问id ·格式 ·对象.属性_id ·示例 ·student.sgrade_id

    6.模型过滤(查询)

    Django默认通过模型的objects对象实现模型数据查询。 Django有两种过滤器用于筛选记录: filter:返回符合筛选条件的数据集 exclude :返回不符合筛选条件的数据集 链式调用: 多个filter和exclude可以连接在一起查询 Person.objects.filter().filter().xxxx.exclude().exclude().yyyy Person.objects.filter(p_age__gt=50).filter(p_age__lt=80)注意数据类型(Queryset) Person.objects.exclude(p_age__gt=50) Person.objects.filter(p_age__in=[50,60,61])

    7.创建对象的方式

    创建对象的方式 (1)创建对象1 常用 person = Person() person.p_name='zs' person.p_age=18 (2)创建对象2 直接实例化对象,设置属性 创建对象,传入属性 使用person = Model.objects.create(p_name='zs',p_age=18) person.save() 自己封装类方法创建 在Manager中封装方法创建 (3)创建对象3 person = Person(p_age=18) (4)创建对象4 注意:__init__已经在父类models.Model中使用,在自定义的模型中无法使用 在模型类中增加类方法去创建对象 @classmethod def create(cls,p_name,p_age=100): return cls(p_name=p_name,p_age=p_age) person = Person.create('zs')

    8.查询集

    概念:查询集表示从数据库获取的对象集合,查询集可以有多个过滤器。 过滤器:过滤器就是一个函数,基于所给的参数限制查询集结果,返回查询集的方法称为过滤器。 查询经过过滤器筛选后返回新的查询集,所以可以写成链式调用。 获取查询结果集 QuerySet all 模型.objects.all() filter 模型.objects.filter() exclude 模型.objects.exclude() order_by persons= Person.objects.order_by('id') 默认是根据id排序 注意要写的是模型的属性 values persons= Person.objects.order_by('id') persons.values() 注意方法的返回值类型 切片 限制查询集,可以使用下标的方法进行限制 左闭右开区间 不支持负数 下标没有负数 实际上相当于 limit offset studentList = Student.objects.all()[0:5] 第一个参数是offset 第二个参数是limit 懒查询/缓存集 查询集的缓存:每个查询集都包含一个缓存,来最小化对数据库的访问 在新建的查询集中,缓存首次为空,第一次对查询集求值,会发生数据缓存,django会将查询出来的数据做 一个缓存,并返回查询结果,以后的查询直接使用查询集的缓存。 - 都不会真正的去查询数据库 - 懒查询 - 只有我们在迭代结果集,或者获取单个对象属性的时候,它才会去查询数据 - 为了优化我们结果和查询 获取单个对象: get 不存在会抛异常 DoesNotExist 存在多于一个 MultipleObjectsReturned 使用这个函数 记得捕获异常 last 返回查询集种的最后一个对象 first 需要主动进行排序 persons=Person.objects.all().first() 内置函数:框架自己封装得方法 帮助我们来处理业务逻辑 count 返回当前查询集中的对象个数 eg:登陆 exists 判断查询集中是否有数据,如果有数据返回True没有反之 字段查询: 对sql中where的实现,作为方法filter(),exclude(),get()的参数 语法:属性名称__比较运算符=值 Person.objects.filter(p_age__gt=18) 条件 属性__操作符=临界值 gt great than gte great than equals lt less than lte less than equals gt,gte,lt,lte:大于,大于等于,小于小于等于filter(sage__gt=30) in in:是否包含在范围内,filter(pk__in=[2,4,6,8]) 单引号可以使用 exact******* exact:判断,大小写不敏感,filter(isDelete = False) startswtith 类似于 模糊查询 like endswith 以 xx 结束 也是like contains contains:是否包含,大小写敏感,filter(sname__contains='赵') isnull,isnotnull isnull,isnotnull:是否为空,filter(sname__isnull=False) ignore 忽略大小写 iexact******************** icontains istartswith iendswith 以上四个在运算符前加上 i(ignore)就不区分大小写了 iexact... 时间 models.DateTimeField(auto_now_add=True) year month 会出现时区问题 需要在settings中的USE-TZ中设置为 False day week_day hour minute second orders = Order.objects.filter(o_time__month=9) 有坑:时区问题 关闭django中自定义的时区 USE-TZ=False 在数据库中创建对应的时区表 注意:mysql oracle中所说的聚合函数 多行函数 组函数 都是一个东西 max min avg sum count 聚合函数 模型: class Customer(models.Model): c_name = models.CharField(max_length=16) c_cost = models.IntegerField(default=10) 使用: 使用aggregate()函数返回聚合函数的值 Avg:平均值 Count:数量 Max:最大 Min:最小 Sum:求和 eg:Student.objects.aggregate(Max('age')) 跨关系查询: 模型: class Grade(models.Model): g_name = models.CharField(max_length=16) class Student(models.Model): s_name = models.CharField(max_length=16) s_grade = models.ForeignKey(Grade) 使用: 模型类名__属性名__比较运算符,实际上就是处理的数据库中的join Grade ---g_name Student---》s_name s_grade(外键) gf = Student.objects.filter(name='凤姐') print(gf[0].s_grade.name) grades = Grade.objects.filter(student__s_name='Jack') 查询jack所在的班级 F对象 eg:常适用于表内属性的值的比较 模型: class Company(models.Model): c_name = models.CharField(max_length=16) c_gril_num = models.IntegerField(default=5) c_boy_num = models.IntegerField(default=3) F: 获取字段信息,通常用在模型的自我属性比较,支持算术运算 eg:男生比女生少的公司 companies = Company.objects.filter(c_boy_num__lt=F('c_gril_num')) eg:女生比男生多15个人 companies = Company.objects.filter(c_boy_num__lt=F('c_gril_num')-15) Q对象 eg:常适用于逻辑运算 与或或 年龄小于25: Student.objects.filter(Q(sage__lt=25)) eg:男生人数多余5 女生人数多于10个: companies = Company.objects.filter(c_boy_num__gt=1).filter(c_gril_num__gt=5) companies = Company.objects.filter(Q(c_boy_num__gt=5) | Q(c_gril_num__gt=10)) 支持逻辑运算: 与或非 & | ~ 年龄大于等于的: Student.objects.filter(~Q(sage__lt=25))
    定义属性
    定义属性 get---><class 'Count.models.Account'> 得到模型对象,有save属性,获取一条数据 filter---> <class 'django.db.models.query.QuerySet'> 得到的是查询集合,queryset没有save属性,获取所有数据 概述 ·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_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 字段选项 ·概述 ·通过字段选项,可以实现对字段的约束 ·在字段对象时通过关键字参数指定 ·null ·如果为True,Django 将空值以NULL 存储到数据库中,默认值是 False ·blank ·如果为True,则该字段允许为空白,默认值是 False ·注意 ·null是数据库范畴的概念,blank是表单验证证范畴的 ·db_column ·字段的名称,如果未指定,则使用属性的名称 ·db_index ·若值为 True, 则在表中会为此字段创建索引 ·default ·默认值 ·primary_key ·若为 True, 则该字段会成为模型的主键字段 ·unique ·如果为 True, 这个字段在表中必须有唯一值 关系 ·分类 ·ForeignKey:一对多,将字段定义在多的端中 ·ManyToManyField:多对多,将字段定义在两端中 ·OneToOneField:一对一,将字段定义在任意一端中 ·用一访问多 ·格式 ·对象.模型类小写_set ·示例 grade.students_set ·用一访问一 ·格式 ·对象.模型类小写 ·示例 ·grade.students ·访问id ·格式 ·对象.属性_id ·示例 ·student.sgrade_id

    总结

    项目和app的生成
    django-admin startproject Demo django-admin startapp App / python manager.py startapp App
    数据库的表的生成和数据迁移
    python manager.py makemigrations python manager.py migrate
    Processed: 0.014, SQL: 9