文章目录
一、ORM字段类型
1.字段类型
类型含义CharFieldvarchar类型,需要指定长度IntegerField整型DecimalField浮点型,需要指定最大长度和小数点位数DateField日期,例如datetimeImageField图片ForeignKey做外键
- 一、ORM字段类型
- 1.字段类型
- 2.字段属性
- 3.元数据
- 二、ORM的单表操作
- 2.1 准备工作
- 2.2 添加数据
- 2.3 查询数据
- 2.4 修改数据
- 2.5 删除数据
- 三、多表查询(一对多)
- 1.准备工作
- 2.增加数据
- 3.查询数据
- 4.更新数据
- 5.删除数据
- 四、多表查询(多对多关系)
- 1.建表
- 2.添加
- 3.查询
- 4.修改
- 5.删除
- 五、聚合函数和F/Q对象
- 六、图片字段的配置
而ForeignKey 做外键又有以下几个参数
①to 设置关联表
②to_field 关联表要关联的键名,默认为关联表中的id,可以不写
③on_delete 当删除关联表中的数据的时候,从表做什么行为,
(1)CASCADE 当关联表中数据删除的时候,外键所在表中的数据也会被删除
(2)SET_NULL 当关联表中数据删除的时候,外键所在表中的外键设置为空
(3)SET_DEFAULT 当关联表中数据删除的时候,外键所在表中的外键设置一个默认值
(4)PROTECT 关联保护,当关联表的数据被删除的时候,报异常,
(5)DO_NOTHING 当关联表中数据删除的时候,外键所在的表不做任何事情
2.字段属性
属性备注max_length最大长度verbose_name备注,站点管理中用于显示字段为中文max_digits浮点型最大长度decimal_places小数点位数auto_now= True获取的是当前时间null= True可为空,默认是不为空
3.元数据
属性备注db_table修改表的名字长度verbose_name备注,站点管理中用于显示模型名字为中文,会出现sverbose_name_plural显示复数名称(站点管理处)ordering= [’-age’]指定排序
二、ORM的单表操作 2.1 准备工作1.数据库创建一个stu库 2.在model.py添加一个Person类
from django.db import models
# 创建学生表
class Person(models.Model):
# id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32, verbose_name='名字')
age = models.IntegerField(verbose_name='年龄')
height = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='身高', null=True) # 长度为5,两位小数
birthday = models.DateField(verbose_name='生日')
def __str__(self):
return self.name
class Meta:
db_table = 'person'
verbose_name = '用户'
verbose_name_plural = verbose_name # 显示的是后台模块的名字
3.然后在命令行进行数据迁移
python mange.py makemigrations
python mange.py migrate
4.查看mysql数据库,数据库创表成功 5.在url处配置路由,并在view处添加对应方法
def addPerson(request):
# 添加方法一:save()
person=models.Person(name='张三',age=11,birthday='1912-12-22')
person.save()
# 或者
person=models.Person()
person.name='迪迦'
person.age=22
person.birthday='1998-11-23'
person.save()
#------------------------------------------------------------------
# 添加方法二:create()
models.Person.objects.create(name='泰罗', age=76, birthday='1954-07-15')
return HttpResponse('添加数据成功')
2.3 查询数据
首先看一下查询的常用查询方法
all():查询所有结果
filter(**kwargs):它包含了与所给筛选条件相匹配的对象
get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
exclude(**kwargs):它包含了与所给筛选条件不匹配的对象
values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列
values_list(*field):它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
order_by(*field): 对查询结果排序
reverse():对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调用(在model类的Meta中指定ordering或调用order_by()方法)。
distinct(): 从返回结果中剔除重复纪录(如果你查询跨越多个表,可能在计算QuerySet时得到重复的结果。此时可以使用distinct(),注意只有在PostgreSQL中支持按字段去重。)
count(): 返回数据库中匹配查询(QuerySet)的对象数量。
first(): 返回第一条记录
last(): 返回最后一条记录
exists(): 如果QuerySet包含数据,就返回True,否则返回False
然后总结一下
类型备注返回QuerySet对象的方法all()、filter()、exelude()、order_by()、reverse()、distinct()特殊的QuerySet1.values() :返回一个可迭代的字典序列 2. values_list() 返回一个可迭代的元祖序列返回具体对象的方法get()、first()、last()返回布尔值的方法exists()返回数字的方法count() 使用举例
def getPerson(request):
# 1.all 方法
# data = models.Person.objects.all()
# print (data)
# print (data[0].name)
# print (data[0].age)
# print (data[0].height)
# for one in data:
# print('生日:', one.birthday)
# print('名字:', one.name)
# --------------------------------------------------------------------
# 2.filter()方法,筛选条件,但是返回的是一个queryset类型
# data = models.Person.objects.filter(birthday='1912-12-22')
# for i in data:
# print(i.age)
# -----------------------------------------------------------------------
# 3.exclude()方法和filter方法相反,返回的是非符合条件的
# data = models.Person.objects.exclude(birthday='1912-12-22')
# for i in data:
# print(i.name)
# --------------------------------------------------------------------
# 4.get()方法,筛选条件,一般参数为主键,只能筛选唯一符合条件的
# data=models.Person.objects.get(birthday='1912-12-22')
# print(data)
# --------------------------------------------------------------------
# 5.first()和last()方法,将选出第一条和最后一条数据
# data=models.Person.objects.filter(age=11).first()
# print(data)
# data=models.Person.objects.filter(age=11).last()
# print(data)
# --------------------------------------------------------------------
# 6.order_by 排序,默认升序,降序在参数前加-
# data=models.Person.objects.order_by('-age')
# for i in data:
# print(i.name)
# ---------------------------------------------------------------------
# 7.values,会将查询到的对象以字典形式将详细数据查询出来,并放在列表中
# data=models.Person.objects.all().values()
# print(data)
# ---------------------------------------------------------------
# 8.exists(),查询符合条件的数据是否存在,返回true或false
# data=models.Person.objects.filter(age=33).exists()
# print(data)
# -----------------------------------------------------------------
# 9.count()记录符合条件的条数
# data=models.Person.objects.all().count()
# print(data)
然后还有其他的双下划线查询方法
下划线查询法用法__gt>__lt<__gte≥__lte≤__in包含__range范围__isnull为空startswitch开始,类似 like ‘a%’endswitch结束,类似 like ‘%a’contains类似 %a% ,对大小写敏感icontains类似 %a% ,对大小写不敏感举例用法:
def getPerson(request):
#__gt大于 __lt小于 __gte大于等于 __lte 小于等于
# data=models.Person.objects.filter(age__gt=20)
# print(data[0].name)
# ---------------------------------------------------------
#__in包含,exclude不包含,range范围
# data=models.Person.objects.filter(age__in=(22,))
# for i in data:
# print(i.name)
# data = models.Person.objects.exclude(age__in=(22,))
# for i in data:
# print(i.name)
# data=models.Person.objects.filter(age__range=(15,30))
# for i in data:
# print(i.name)
# ---------------------------------------------------------
# 查询身高为__isnull
# data=models.Person.objects.filter(height__isnull=True)
# for i in data:
# i.height=1.11
# i.save()
# ---------------------------------------------------------
#查询开头的startswitch和查询结尾的endswitch
# data=models.Person.objects.filter(name__startswith='讲师')#like '讲师%'
# print(data[0].name)
# data=models.Person.objects.filter(name__endswith='罗')
# print(data[0].name)
# ---------------------------------------------------------
#包含的contains类似like %a% 对大小写敏感 icontains 对大小写不敏感
data=models.Person.objects.filter(name__contains='师')
print(data[0].name)
return HttpResponse('查询数据成功')
2.4 修改数据
def updatePerson(request):
#1.save(),先查要修改的数据,然后直接用对象.属性=修改值,如果查询的数据为多个需要用遍历修改
# data=models.Person.objects.get(id=2)
# data.height=233.34
# data.save()
#--------------------------------------------------------------
#2.update(),先查后更新
models.Person.objects.filter(id=3).update(name='孙悟空') # 更新什么写什么字段
return HttpResponse('修改数据成功')
2.5 删除数据
先查询后删除
def delPerson(request):
models.Person.objects.get(id=6).delete()
return HttpResponse('删除数据成功')
三、多表查询(一对多)
1.准备工作
创建多表,并进行数据迁移 models.py
# 方法1--------------------------------------------------
# 增加出版社
# Publish.objects.create(name='清华出版社',address = '北京')
# Publish.objects.create(name='中国出版社',address = '北京朝阳')
# Publish.objects.create(name='河南出版社',address = '洛阳')
# 增加书
# Book.objects.create(name='python入门',publish_id = 1)
# 将出版社和书关联
# publish = Publish.objects.get(name='中国出版社')
# Book.objects.create(name='python入门', publish_id=publish.id)
# 方法2--------------------------------------------------
# Book.objects.create(name='python核心编程',publish = Publish.objects.get(name='中国出版社'))
# 方法3--------------------------------------------------
# 正向操作 从外键所在的表到主表叫正向
book = Book()
book.name= '笨办法学python'
book.publish = Publish.objects.get(name='河南出版社')
book.save()
# 反向操作 从主表到从表 叫反向
publish_obj = Publish.objects.get(name="中国出版社")
publish_obj.book_set.create(name='pythonWeb开发')
3.查询数据
# 方法1--------------------------------------------------
# publish = Publish.objects.get(name="中国出版社")
# book = Book.objects.filter(publish_id=publish.id).all()
# for x in book:
# print (x.name)
# 方法2--------------------------------------------------
# 正向查询 从外键所在的表到主表叫正向
# 查询 pythonWeb开发 属于哪一个出版社
# book = Book.objects.filter(name='pythonWeb开发').first()
# print (book.name)
# print (book.publish.name)
# 方法3--------------------------------------------------
# 反向查询 从主表到从表 叫 反向查询 _set
publish = Publish.objects.get(name='中国出版社')
book = publish.book_set.all()
print (book)
4.更新数据
# 一对多更新数据
def updatemore(request):
# save
# book=models.Book.objects.get(id=2)
# book.publish=models.Publish.objects.get(name='清华出版社')
# book.save()
# #upadate
# models.Book.objects.update(name='python',publish=models.Publish.objects.get(id=3))
#set
# 反向,类似数据库中的update
publish = models.Publish.objects.get(name='蓝翔出版社')
book = models.Book.objects.get(id=2)
book2 = models.Book.objects.get(id=1)
publish.book_set.set([book, book2])
return HttpResponse('修改数据成功')
5.删除数据
# 一对多删除数据
def delmore(request):
# 一般先删除从表再删除主表,根据模型类里的外键设置决定
models.Book.get(id=2).delete()
models.Publish.get(id=2).delete()
return HttpResponse('删除数据成功')
四、多表查询(多对多关系)
1.建表
models.py
class Person(models.Model):
# id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32,verbose_name="姓名")
age = models.IntegerField(verbose_name="年龄")
height = models.DecimalField(max_digits=5,decimal_places=2,verbose_name="身高",null=True)
birthday = models.DateField(verbose_name="生日",auto_now=True)
def __str__(self):
return str(self.name)
class Meta:
db_table = 'person'
verbose_name = "用户"
verbose_name_plural = verbose_name
# ordering= ['-age','id','name']
class Teacher(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField(default=0)
gender = models.CharField(max_length=8)
person = models.ManyToManyField(to=Person)
class Meta:
db_table = 'teacher'
2.添加
# 多对多添加
def addmanytomany(request):
# 添加老师
# models.Teacher.objects.create(name='僵尸王宗涛',gender=1)
# models.Teacher.objects.create(name='僵尸张环宇',gender=0)
# models.Teacher.objects.create(name='僵尸温俊鹏',gender=1)
# 正向操作
# 添加新学生,和僵尸王宗涛关联
# teacher=models.Teacher.objects.get(name='僵尸王宗涛')
# teacher.person.create(name='孙悟空',age=3)
# 老学生关联温老师,需要将两个数据都查出来,并使用add()
# teacher=models.Teacher.objects.get(id=3)
# person=models.Person.objects.filter(name='泰罗').first()
# teacher.person.add(person)
# 反向操作
teacher = models.Teacher.objects.get(id=2)
person = models.Person.objects.get(id=1)
person.teacher_set.add(teacher)
return HttpResponse('添加成功')
3.查询
# 多对多查询
def getmanytomany(request):
# 寻找id为3的老师教的所有学生
teacher = models.Teacher.objects.get(id=3)
person = teacher.person.all()
print(person.values())
# 根据学生查老师
person = models.Person.objects.get(id=6)
teacher = person.teacher_set.all()
print(teacher.values())
return HttpResponse('查询成功')
4.修改
# 多对多修改
def updatemanytomany(request):
# 正向修改
# 将讲师王宗涛的学生改为234,set后边放列表,列表里传入更改的关联数据
# teacher=models.Teacher.objects.get(id=1)
# person1=models.Teacher.objects.get(id=2)
# person2=models.Teacher.objects.get(id=3)
# person3=models.Teacher.objects.get(id=4)
# teacher.person.set([person1,person2,person3])
# 反向
person = models.Person.objects.get(id=2)
teacher1 = models.Teacher.objects.get(id=3)
teacher2 = models.Teacher.objects.get(id=2)
person.teacher_set.set([teacher1, teacher2])
return HttpResponse('修改成功')
5.删除
# 多对多删除
def delmanytomany(request):
# remove 解除关系
# 正向
# teacher=models.Teacher.objects.get(id=1)
# person=models.Person.objects.get(id=3)
# teacher.person.remove(person)
# 反向
# person=models.Person.objects.get(id=4)
# teacher=models.Teacher.objects.get(id=1)
# person.teacher_set.remove(teacher)
# del删除
models.Person.objects.get(id=2).delete()
return HttpResponse('删除成功')
五、聚合函数和F/Q对象
# 聚合函数
from django.db.models import Max, Min, Count, Avg, Sum
def juhe(request):
data = models.Person.objects.all().aggregate(Avg('age'))
print(data) # 显示的是queryset
data = models.Person.objects.all().aggregate(Avg('age'), sum('age'))
print(data) # 显示的是queryset
return HttpResponse('聚合查询')
# --------------------------------------------------------------------python
from django.db.models import F, Q
# F和Q对象
# F对象: 用于比较同一个模型中的两个字段的值
def Ftest(request):
# 查询book中销量大于库存的
book = models.Book.objects.filter(xiaoliang__gt=F('kucun')).all()
print(book)
return HttpResponse('f对象')
# Q对象:用于处理多条件中的逻辑关系 and or not
def Qtest(request):
# and
book = models.Book.objects.filter(Q(xiaoliang=20) & Q(kucun=50))
print(book)
book = models.Book.objects.filter(xiaoliang=20, kucun=50)
print(book)
# or
book = models.Book.objects.filter(Q(xiaoliang=20) | Q(kucun=50))
print(book)
# not
book = models.Book.objects.filter(~Q(xiaoliang=20) | ~Q(kucun=50))
print(book)
return HttpResponse('q对象')
六、图片字段的配置
1.模型中添加照片字段,注意最后的null和blank的意思
photo=models.ImageField(upload_to='img',null=True,blank=True)
#null针对数据库,表示可以为空,即在数据库储存可以为空
#blank针对表单,表示在表单中该字段可以不填,但是对数据库无影响
2.在settings末尾添加
MEDIA_URL='/media/'
#指定的媒体文件上传路径
MEDIA_ROOT=os.path.join(BASE_DIR,'static')