04 Django模子基础
1. models字段范例概述
django根据属性的范例确定以下信息
[*]当前选择的数据库支持字段的范例
[*]渲染管理表单时使用的默认html控件
[*]在管理站点最低限度的验证
django会为表增加自动增长的主键列,每个模子只能有一个主键列,如果使用选项设置某属性为主键列后则django不会再天生默认的主键列
属性定名限制
[*] 遵循标识符规则
[*] 由于django的查询方式,不答应使用一连的下划线界说属性时,
需要字段范例,字段范例被界说在diango.db.models.fields目录下,为了方便使用被导入到django.db.models中
使用方式
[*]导入from django.db import models
[*]通过models.Field创建字段范例的对象,赋值给属性
逻辑删除和物理删除
对于紧张数据都做逻辑删除,不做物理删除,实现方法是界说is_delete属性,范例为BooleanField,默认值为False
is_delete = models.BooleanField(default=False)
常用字段范例
[*] AutoField: 一个根据实际ID自动增长的IntegerField,通常不指定,如果不指定,主键字段id将自动添加到模子中
[*] CharField(max_length=字符长度)
[*]字符串,默认的表单样式是 Input
[*] 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
[*] DateField()
[*]使用Python的datetime.date实例表示的日期参数说明
[*]参数说明
[*]DateField.auto_now
每次生存对象时,自动设置该字段为当前时间,用于**“最后一次修改”**的时间戳,它总是使用当前日期,默以为false
[*]DateField.auto_now_add
当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用创建时的日期,默以为false
[*]注意:auto_now_add,auto_now,and_default 这些设置是相互排斥的他们之间的任何组合将会发生错误的效果
[*] TimeField: 使用Python的datetime.time实例表示的时间,参数同DateField
[*] DateTimeField: 使用Python的datetime.datetime实例表示的日期和时间,参数同DateField
[*] FileField
[*]一个上传文件的字段
[*] ImageField:
[*]继承了FileField的全部属性和方法,但对上传的对象举行校验,确保它是个有效的image
[*]需要安装Pillow: “pip install Pillow”
2. 常用字段参数
# 常用字段选项(通过字段选项,可以实现对字段的约束)
1. null=True
数据库中字段是否可以为空
2. blank=True
django的 Admin 中添加数据时是否可允许空值
一般null=True & blank=True 搭配着用,出现null=True就用上blank=True
3. primary_key = True
主键,对AutoField设置主键后,就会代替原来的自增id列
4. auto_now和auto_now_add
auto_now 自动创建 --- 无论添加或修改,都是当前操作的时间
auto_now_add 自动创建 --- 永远是创建时的时间
5. choices (后台admin下拉菜单)
USER_TYPE_LIST =(
(1,'超级用户'),
(2,'普通用户'),
)
user_type = models.IntegerField(choices=USER_TYPE_LIST,default=1,,verbose_name='用户类型')
6. max_length 最大长度
7. default 默认值
8. verbose_name Admin(后台显示的名称)中字段的显示名称
9. name|db_column 数据库中的字段名称
10. unique=True 不允许重复
11. db_index = True 数据库索引,例如:如果你想通过name查询的更快的话,给他设置为索引即可
12. editable=True 在Admin里是否可编辑,不可编辑则不显示
13. 设置表名
class Meta:
db_table ='person'
在创建模子迁移之时,常常会碰到以下问题,这是以为原先数据库中已经有数据,这时创建新的数据字段,原先的记录不知道填充什么内容进新增字段(假设不是全部新增字段都有默认值)
模子在admin背景默认的html控件 --> 渲染管理表单时使用的默认html控件
https://i-blog.csdnimg.cn/direct/a39d946a21974ecd841c82714b660a71.png#pic_center
3.迁移怎么回滚
完成迁移之后,会在应用文件夹App/migrations文件夹下创建迁移文件,而且在数据库表django_migrations中创建对应记录
想要回滚,可以删除对应的迁移python文件以及对应数据库记录
https://i-blog.csdnimg.cn/direct/72f5d81d89584e29adfa301db619c4e3.png#pic_center
https://i-blog.csdnimg.cn/direct/5ca003e228ed417bbf1220793e8f3d82.png#pic_center
https://i-blog.csdnimg.cn/direct/4bca99219a18405db0ee61b5f0c79fea.png#pic_center
4. models基本操作
一样平常的数据库操作流程:
[*]创建数据库,计划表结构和字段
[*]连接Mysql数据库,并编写数据访问层代码
[*]业务逻辑层去调用数据访问层实验数据库操作
Django通过Model操作数据库,不管你数据库的范例是MySql大概Sqlite,Django自动帮你天生相应数据库范例的SQL语句,所以不需要关注SQL语句和范例,对数据的操作Django帮我们自动完成。
只要会写Model就可以了。django使用对象关系映射(Object Relational Mapping,简称ORM)框架去操控数据库。ORM(Object Relational Mapping)对象关系映射,是一种步调技术,用于实现面向对象编程语言里差别范例体系的数据之间的转换。
在Django模子中可以使用内部类Meta为模子提供选项,具体请见文档
增删改查
ORM
[*]模子 <=> 表
[*]类结构 -> 表结构
[*]对象 -> 表的一条数据
[*]类属性 -> 表的字段
模子基本操作
[*] 增: (假设模子是Author)
[*]创建对象实例,然后调用save方法
obj = Author()
obj.first_name = "zhang"
obj.last_name = 'san'
obj.save()
[*]创建对象并初始化,在调用save方法
obj = Author(first_name = "zhang",last_name = 'san')
obj.save()
[*]使用create方法
Author.objects.create(first_name = "zhang",last_name = 'san')
[*]使用get_or_create方法,可以防止重复
Author.objects.get_or_create(first_name = "zhang",last_name = 'san')
https://i-blog.csdnimg.cn/direct/b0134abc15bc4118b64961e6caf1c374.png#pic_center
注意: 添加失败是由于PersonModel模子中name属性设置的是unique
# 增加数据
def add_person(request):
# # 方式1
# try:
# p = PersonModel(name='张三', age=20)
# p.save()
# except Exception as e:
# print(e)
# return HttpResponse('添加失败')
# return HttpResponse('添加成功')
# 方式2
# PersonModel.objects.create(name='李四', age=25)
# return HttpResponse('添加成功')
# 方式3
ret = PersonModel.objects.get_or_create(name='李四', age=25)
print("ret",ret)
# ret:(<PersonModel:PersonModelobject(2)>,True)
# 如果是第一次创建: 则是True,如果已经存在则是False
return HttpResponse('添加成功')
[*] 删:
[*]获取单个对象并调用Queryset的delete()方法
p = PersonModel.objects.first() # 获取第一个数据
p.delete()
p = PersonModel.objects.get(name="李四") # 根据对应的id获取数据
p.delete()
注意: objects不能直接调用delete()方法
[*]使用模子过滤filter(),再对过滤效果举行删除
# 使用过滤器
PersonModel.objects.filter(age__gt = 15).delete() # 删除年龄大于15的数据
[*] 改:
[*]直接使用对象.属性修改
# 获取数据
p = PersonModel.objects.first()
p.age = 25
p.save()
# 修改多条数据
p_list = PersonModel.objects.all()
for p in p_list:
p.age = 25
p.save()
[*]修改多条数据
PersonModel.objects.all().update(age=25)# 修改所有数据
save()更新时,会对全部字段举行更新操作,如果想要只更新某个字段,减少数据库操作,可以这么做:
obj.first_name = "zhang"
obj.save(update_fields = ['first_name'])
[*] 查:
对查询集可使用的函数
[*] get():获取单条数据 Author.objects.get(id=123)
[*]如果没有找到符合条件的对象,会引发模子类.DoesNotExist非常
[*]如果找到多个,会引发模子类.MultipleObjectsReturned非常
[*] first():返回査询集(Queryset)中的第一个对象
[*] last():返回查询会合的最后一个对象
[*] count():返回当前查询会合的对象个数
[*] exists():判定查询会合是否有数据,如果有数据返回True没有反之
[*] all()获取全部数据: Author.objects.all()
[*] values():获取指定列的值,可以传多个参数! 返回包罗字典的列表(生存了字段名和对应的值) —>
Author.objects.all().values(‘password’)
[*] values_list():获取指定列的值,可以传多个参数! 返回包罗元组列表(只生存值) —>
Author.objects.all().values_list(‘password’)
[*] filter()
查询集可以被链式调用,Author.objects.filter(name="seven").filter(age=18)
进阶操作
# 获取个数
Author.objects.filter(name="seven").count()
# 获取id大于1的值
Author.objects.filter(id__gt=1) # SELET * FROM Author WHERE id > 1
# 获取id大于或等于1的值
Author.objects.filter(id__gte=1) # SELET * FROM Author WHERE id >= 1
# 获取id小于10的值
Author.objects.filter(id__lt=10) # SELET * FROM Author WHERE id < 10
# 获取id小于或等于10的值
Author.objects.filter(id__lte=10) # SELET * FROM Author WHERE id >= 1
# 获取id大于1且小于10的值
Author.objects.filter(id__lt=10,id__gt=1) # SELET * FROM Author WHERE id > 1 AND id < 10
# 获取id在11,22,33的数据
Author.objects.filter(id__in=) # SELET * FROM Author WHERE id IN (11,22,33)
# 获取id`不在`11,22,33的数据
Author.objects.exclude(id__in=) # SELET * FROM Author WHERE id NOT IN (11,22,33)
# 获取name包含"ven"的数据 (和数据库中like语法相似)
Author.objects.filter(name__contains="ven") # SELET * FROM Author WHERE name LIKE '%ven%'
# icontains()大小写不敏感
Author.objects.filter(name__icontains="ven")
Author.objects.filter(name_regex="^ven") # 正则匹配
Author.objects.filter(name_iregex="^ven") # 正则匹配,忽略大小写
Author.objects.filter(age_range=) # 范围bettwen and
# startswith,istartswith,endswith,iendswith:
# 以什么开始,以什么结束,和上面一样带i的是大小写不敏感的, 其实不带i的也忽略大小写
Author.objects.filter(name='seven').order_by('id','age') # asc升序, 多个属性->id相同时,按照age来排序
Author.objects.filter(name='seven').order_by('-id') # desc降序
Author.objects.all() # 切片,取所有数据的18条到20条,分页的时候用的到
# 下标从0开始,不能为负数,可以实现分页
# 手动分页
page 页码
per_page 每页数量 = 5
第1页(page=1): 0-4 =>
第2页(page=2): 5-9 =>
第3页(page=3): 10-14 =>
第4页(page=4): 15-19 =>
每一页数据范围:[(page-1) * per_page : page * per_page]
# 聚合
使用aggregate()函数返回聚合函数的值
- Avg:平均值
- Count:数量
- Max:最大
- Min:最小
- Sum:求和
from django.db.models import Count,Min,Max,Sum
Author.objects.aggregate(Max('age'))
5. views.py
from django.http import HttpResponsefrom django.shortcuts import renderfrom django.db.models import Avg, Max, Min, Sum# Create your views here.from App.models import *# 增加数据def add_person(request): # # 方式1 # try: # p = PersonModel(name='张三', age=20) # p.save() # except Exception as e: # print(e) # return HttpResponse('添加失败') for i in range(10): p = PersonModel(name='张三'+str(i), age=20+i) p.save() # return HttpResponse('添加乐成') # 方式2 # PersonModel.objects.create(name='李四', age=25) # return HttpResponse('添加乐成') # 方式3 # ret = PersonModel.objects.get_or_create(name='李四', age=26) # print("ret",ret) # ret:(<PersonModel:PersonModelobject(5)>,True) # 如果是第一次创建: 则是True,如果已经存在则是False return HttpResponse('添加乐成')# 删除数据def del_person(request): try: # p = PersonModel.objects.first() # 获取第一个数据 # p = PersonModel.objects.get(name="李四") # 根据对应的id获取数据 # p.delete() # 使用过滤器 PersonModel.objects.filter(age__gt = 15).delete() # 删除年龄大于15的数据 except Exception as e: print(e) return HttpResponse('删除失败') return HttpResponse('删除乐成')# 修改数据def update_person(request): try: # 获取数据 # p = PersonModel.objects.first() # p.age = 25 # p.save() # 修改多条数据 p_list = PersonModel.objects.all() # PersonModel.objects.all().update(age=25)# 修改所有数据
for p in p_list: p.age = 25 p.save() except Exception as e: print(e) return HttpResponse('修改失败') return HttpResponse('修改乐成') def get_person(response): # get() 方法获取单个数据 # p = PersonModel.objects.get(id=1) # p = PersonModel.objects.get(pk=18) # primary key等于18 # p = PersonModel.objects.get(age=100)# 找不到对应的数据时会报错,找到多条数据时也会报错 # print(p,type(p)) # <PersonModel: PersonModelobject(1)> <class 'App.models.PersonModel'> # print(p.name,p.age) # all() 方法返回全部数据 p_list = PersonModel.objects.all() print(p_list,type(p_list))#<PersonModel: PersonModel object (25)>]> <class 'django.db.models.query.QuerySet'> 查询集,可以遍历 # first() 方法获取第一个数据 # p = PersonModel.objects.first() # last() 方法获取最后一个数据 # p = PersonModel.objects.last() # exists() 方法判定命据是否存在 # if PersonModel.objects.filter(name='张三').exists(): # print('存在') # else: # print('不存在') # values() 方法返回指定字段的数据 # p_list = PersonModel.objects.values('name','age') #返回包罗字典的列表 p_list = PersonModel.objects.values_list('name','age') # 返回包罗元组列表 print(p_list,type(p_list)) # filter() 方法过滤数据,返回一个```查询集````,参数为空时返回全部数据 # p_list = PersonModel.objects.filter(age__gt=15) # 年龄大于15的数据 # p_list = PersonModel.objects.filter(name__contains='三') # 名字包罗'三'的数据 # p_list = PersonModel.objects.filter(name__startswith='张') # 名字以'张'开头的数据 # exclude() 方法排除数据,返回一个```查询集````,参数为空时返回全部数据 # p_list = PersonModel.objects.exclude(age__gt=15) # 年龄不大于15的数据 # order_by() 方法排序数据,返回一个```查询集````,参数为空时返回全部数据 # p_list = PersonModel.objects.order_by('age') # 按年龄排序 # p_list = PersonModel.objects.order_by('-age') # 按年龄倒序排序 # contains() 方法查找字符串是否在指定字段中,返回一个```查询集````,参数为空时返回全部数据 p_list = PersonModel.objects.filter(name__contains='三') # 名字包罗'三'的数据 print(p_list,type(p_list)) # regex() 方法查找正则表达式是否匹配指定字段,返回一个```查询集````,参数为空时返回全部数据 # p_list = PersonModel.objects.filter(name__regex=r'^张') # 名字以'张'开头的数据 # 聚合函数 # count() 方法计算数据条数 # count = PersonModel.objects.count() # print(count) # max() 方法获取最大值 # max_age = PersonModel.objects.all().aggregate(Max('age')) # print(max_age) # min() 方法获取最小值 # min_age = PersonModel.objects.all().aggregate(Min('age')) # print(min_age) # sum() 方法求和 # total_age = PersonModel.objects.all().aggregate(Sum('age')) # print(total_age) # avg() 方法求均匀值 result = PersonModel.objects.all().aggregate(Avg('age')) print(result) return HttpResponse('获取乐成')# 分页数据def paginate(request,page=1): # 页码: page # 每页显示条数: per_page per_page = 10 # 数据范围的计算公式 -> (页码-1)*每页显示条数 ~ 页码*每页显示条数 all = PersonModel.objects.all() start = (page-1) * per_page end = page * per_page p_list = all return render(request,"page_list.html",{'p_list':p_list})# 自动分页器def auto_paginate(request): # 自动分页器 from django.core.paginator import Paginator # 实例化分页器 paginator = Paginator(PersonModel.objects.all(), 10) page = 1 persons = paginator.page(page) # 获取第page页的数据 paginator.page_range # 页码范围,可以遍历
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]