做一个网站的流程,手机建站平台可上传自己视频,自己做的网站点进去很卡,学校网站开发系统的背景Django提供了一套非常方便的类似SqlAlchemy ORM的通过对象调用的方式操作数据库表的ORM框架。
Django ORM操作主要分为以下几类#xff1a;
增#xff1a;向表内插入一条数据删#xff1a;删除表内数据#xff08;物理删除#xff09;改#xff1a;update操作更新某条数…Django提供了一套非常方便的类似SqlAlchemy ORM的通过对象调用的方式操作数据库表的ORM框架。
Django ORM操作主要分为以下几类
增向表内插入一条数据删删除表内数据物理删除改update操作更新某条数据查基本的表查询包括多表、跨表、子查询、联表查询
其中比较复杂的是表查询。下面分类讲解这几种操作方式。
1 增 – 向表内插入一条数据
关于新增记录的操作这里分为两种方式:
第一种方式通过模型对象的save()方法
userObjUser()
userObj.username request.data.get(username)
# userObj.password make_password(request.POST.get(password),None,pbkdf2_sha256) # 创建django密码第三个参数为加密算法
userObj.set_password(request.data.get(password)) # 创建django密码第三个参数为加密算法
userObj.name request.data.get(name)
userObj.phone request.data.get(phone)
userObj.email request.data.get(email)
userObj.create_name request.data.get(create_name)
userObj.update_name request.data.get(update_name)
userObj.is_superuser 0
print(userObj.username)
print(username %s % (userObj.username))
print(password %s % (userObj.password))
userObj.save()
这种方式通过线创建一个模型对象赋值最后调用模型的 .save()方法的方式向数据库插入一条数据。
第二种方式通过objects.create的方式直接新增类似一种缩略的方式比较简单
res models.User.objects.create(usernameadmin,make_password123456,register_timedatetime.datetime.now())
print(res)2 删 – 删除表内数据物理删除
django删除表数据是通过.delete()方法举例 如果我们只删除 user表 主键为1的记录 ret models.User.objects.get(pk1).delete() 上述是只删一条记录删除多条记录类似 ret models.User.objects.filter(pk__gt1).delete() 这样我们可以批量删除user表中主键值大于1的其他所有记录。
需要提醒的是这种方式属于物理删除删除后不可恢复如需逻辑删除参考下面 update的方式。
3 改 – update操作更新某条数据
django ORM 的改操作这里分为三种方式。我们先按单记录的更新讲解批量更新类似
第一种指定更新字段更新
ret models.User.objects.get(pk1).update(usernameadmin,password123456)第二种通过 Json 更新
object {username:admin,password:123456}
ret models.User.objects.get(pk1).update(**object)第三种类似增操作直接通过.save()方法更新整条记录
userObjUser()
userObj.id request.data.get(id)
userObj.username request.data.get(username)
# userObj.password make_password(request.POST.get(password),None,pbkdf2_sha256) # 创建django密码第三个参数为加密算法
userObj.set_password(request.data.get(password)) # 创建django密码第三个参数为加密算法
userObj.name request.data.get(name)
userObj.phone request.data.get(phone)
userObj.email request.data.get(email)
userObj.create_name request.data.get(create_name)
userObj.update_name request.data.get(update_name)
userObj.is_superuser 0
print(userObj.username)
print(username %s % (userObj.username))
print(password %s % (userObj.password))
userObj.save()这种方式不太建议用需要注意数据的完整性。
4 查 – 基本的表查询包括多表、跨表、子查询、联表查询
4.1 基本查询
需要了解如下方法的使用
all() 查询所有数据filter() 带有过滤条件的查询 whereget() 获取单条查询不到会报错first() 取queryset里第一条记录last() 取queryset里最后一条记录values() 指定要获取的字段
models.User.objects.filter(pk1).values(username,phone)
# 返回 QuerySet [{username: admin, phone: 176****}]values_list() 列表套元祖 models.User.objects.filter(pk1).values_list(username,phone)
# 返回 QuerySet [(admin,176***)]distinct() 去重
ret models.User.objects.filter(pk1).distinct()需要注意这里去重是针对整条数据的去重主键不一样也不会去重
order_by() 排序
ret models.User.objects.order_by(username)# 默认升序
ret models.User.objects.order_by(-username)# 降序reverse() 反转前提已排序
ret models.User.objects.order_by(username).reverse()# 默认升序
ret models.User.objects.order_by(-username).reverse()# 降序count() 当前查询条件的记录数
ret models.User.objects.filter(pk1).count()exclude() 排除 相当于查询条件不等于
ret models.User.objects.exclude(pk1)exists() 记录是否存在不太实用不过多讲 4.2 双下划线查询条件
django不支持 类似,等查询判断方式但提供了一套很好用的方法 __gt 大于: ret models.User.objects.filter(id__gt1)#查询id1的记录 __lt 小于: ret models.User.objects.filter(id__lt1)#查询id1的记录 __gte 大于等于: ret models.User.objects.filter(id__gte1)#查询id1的记录 __lte 小于等于: ret models.User.objects.filter(id__lte1)#查询id1的记录 __in 条件是否归属所给的选择: ret models.User.objects.filter(id__in[1,2])#查询id1或id2的记录 __range 范围: ret models.User.objects.filter(id__range[1,3])#查询1id3的记录 __contains 模糊查询 ,区分大小写: ret models.User.objects.filter(username__containsa)#查询 username like %a%的记录 __icontains 模糊查询 ,不区分大小写: ret models.User.objects.filter(username__icontainsa)#查询 username like %a%的记录 __startswith 模糊查询 ,指定内容开始: ret models.User.objects.filter(username__icontainsa)#查询 username like a%的记录 __endswith 模糊查询 ,指定内容结束: ret models.User.objects.filter(username__icontainsa)#查询 username like %a的记录
注意__contains、__icontains、__startswith、__endswith这些模糊查询性能很低生产环境不建议使用。 4.3 逻辑查询or、and、not
涉及概念Django的Q对象
4.3.1 Q对象
Q对象实例化后能够增加各个条件之间的关系而且这种写法用在你不知道用户到底传入了多少个参数的时候很方便。
比如默认情况下filter()里面每个字段的连接都是我们使用Q对象通常都是让它变成|来进行查询 。
from django.db.models import Qquery Q()
q1 Q()
q1.connector AND # 连接的条件是AND 代表就是
q1.children.append((email, 280773872qq.com)) # email代表的是数据库的字段
q1.children.append((password, 666))# 等同于email280773872qq.com password666
q2 Q()
q2.connector AND # 同样q2对象连接条件也是AND
q2.children.append((username, fe_cow)) # 同样数据库里username字段
q2.children.append((password, fe_cow666))# 等同于usernamefe_cow passwordfe_cow666
query.add(q1, OR)
query.add(q2, OR)# query目前里面的符合条件结果就是: email280773872qq.com password666 | usernamefe_cow passwordfe_cow666
userinfo_obj models.UserInfo.objects.filter(query).first()
filter()过滤器的方法中关键字参数查询会合并为And(),需要进行or查询使用Q()对象Q对象django.db.models.Q用于封装一组关键字参数这些关键字参数与比较运算符中的相同。
Q对象可以使用(and)、|(or)操作符组合起来当操作符应用在两个Q对象时会产生一个新的Q对象。
list.filter(pk__lt6).filter(bcomment__gt10)
list.filter(Q(pk__lt6) | Q(bcomment__gt10))使用~操作符在Q对象前表示取反: list.filter(~Q(pk__lt6)) 可以使用|~结合括号进行分组构造出复杂的Q对象
4.3.2 or、and、not
import os
import djangoos.environ.setdefault(DJANGO_SETTINGS_MODULE, salary.settings)
django.setup(set_prefixFalse)from employee.models import Employees # 这一行必须在os.environ.setdefault之后先把配置、环境变量准备好后才能import
from django.db.models import Q
# emps Employees.objects.all() # 懒查询只有后面对查询结构有引用时才会驱动真正的查询
# print(emps) # 查询集mgr Employees.objects
# AND查询 五种方式
x mgr.filter(pk__gt10005, pk__lt10010)
print(x)
y mgr.filter(pk__gt10005).filter(pk__lt10010)
print(y)
z mgr.filter(pk__gt10005) mgr.filter(pk__lt10010)
print(z)
# Django的Q对象
xx mgr.filter(Q(pk__gt10005) Q(pk__lt10010))
yy mgr.filter(Q(pk__gt10005), Q(pk__lt10010))# OR查询: 三种方式
x mgr.filter(pk__in[10005, 10010])
print(x)
y mgr.filter(pk10005) | mgr.filter(pk10010)
print(y)
z mgr.filter(Q(pk10005) | Q(pk10010))# NOT查询
x mgr.exclude(pk10005)
print(x)
y mgr.filter(~(Q(pk__gt10005) Q(pk__lt10010)))
print(y)4.3.3 集合查询
# 聚合
from django.db.models import Max, Min, Count, Sum, Avg
x mgr.filter(pk__gt10008).count() # 将所有数据看做一行出结构
print(x) # 单值
# aggregate聚合函数出统计函数的结果返回字典默认key命名为字段名_聚合函数名
y mgr.filter(pk__gt10008).aggregate(Count(pk), Max(pk), Min(pk), sm_pkSum(pk), avg_pkAvg(pk)) # 可以给聚合查询结果起别名
print(y)
# 结果{sm_pk: 120174, avg_pk: 10014.5, pk__count: 12, pk__max: 10020, pk__min: 10009}
# annotate聚合函数这个聚合函数会分组没有指定分组使用pk分组行行分组。返回结果集
z mgr.filter(pk__gt10013).annotate(Count(pk), Max(pk), Min(pk), sm_pkSum(pk), avg_pkAvg(pk))
print(z)
xx mgr.filter(pk__gt10013).values(gender).annotate(cCount(pk)).values(c) # 第一个values控制分组第二个values控制投影
print(xx)4.4 多表查询
4.4.1 多对多查询
我们先定义两张表User表用户表Artile表文章表一篇文章可以被多个用户关注一个用户也可以关注多篇文章,二者是多对多的关系。
from django.db import models
import datetimeclass Artile(models.Model):title: 标题sub_title: 子标题content: 内容def __str__(self):return self.titletitle models.CharField(max_length250,default,verbose_name标题)sub_title models.CharField(max_length250,default,verbose_name子标题)content models.CharField(max_length2000,default,blankTrue,verbose_name内容)# 与User表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个自动创建第三张表users models.ManyToManyField(toUser, )create_time models.DateTimeField(defaultdatetime.datetime.now(),verbose_name创建时间)create_name models.CharField(max_length20,verbose_name创建人)update_time models.DateTimeField(defaultdatetime.datetime.now(),blankTrue,verbose_name更新时间)update_name models.CharField(max_length20,verbose_name更新人,blankTrue,)is_delete models.IntegerField(default0,verbose_name删除状态,blankTrue,) # 逻辑删除 0 正常 1:删除class Meta:verbose_name 文章verbose_name_plural verbose_nameapp_label webApi
from django.db import models
import datetime
#引入系统用户的分类
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.hashers import make_password #密码加密#userProfile继承AbstractUser分类进行拓展
class User(AbstractUser):name: 昵称account: 用户名pwd: 密码phone:手机号email:邮箱avator:头像group_id:归属组def __str__(self):return self.accountname models.CharField(max_length20,default,verbose_name昵称)phone models.CharField(max_length20,default,blankTrue,verbose_name手机号)email models.CharField(max_length20,default,blankTrue,verbose_name邮箱)avator models.CharField(max_length200,default,blankTrue,verbose_name头像)group_id models.CharField(max_length50,default,blankTrue,verbose_name组)create_time models.DateTimeField(defaultdatetime.datetime.now(),verbose_name创建时间)create_name models.CharField(max_length20,verbose_name创建人)update_time models.DateTimeField(defaultdatetime.datetime.now(),blankTrue,verbose_name更新时间)update_name models.CharField(max_length20,verbose_name更新人,blankTrue,)is_delete models.IntegerField(default0,verbose_name删除状态,blankTrue,) # 逻辑删除 0 正常 1:删除# blankTrue, 可选字段class Meta:verbose_name 用户verbose_name_plural verbose_namedef __str__(self):return self.username# 明文密码转加密def set_password(self, password):print(set_password %s % (password))self.password make_password(password,jxy,pbkdf2_sha256)# 验证密码是否匹配def check_password(self, password):print(password: %s % (password))print(check_password: %s % (make_password(password,jxy,pbkdf2_sha256)))print(self.password: %s % (self.password))return self.password make_password(password,jxy,pbkdf2_sha256)
注意我们在Artile表中定义的users models.ManyToManyField(toUser)通过这种定义方式我们在 Artile表与User表之间创建了一个针对这两张表的关系表。 接下来我们向这张关系表中添加几条关系。比如我们将 Artile表主键为1的一条记录添加User表 主键为12两条关系。
user1 models.User.object.filter(pk1).first()
user2 models.User.object.filter(pk2).first()artile1 models.Artile.object.filter(pk1).first()
artile1.users.add(user1,user2)# 方法二
userSet models.User.object.filter(pk__in[1,2]).all()
artile1.users.add(*userSet)这样便在关系表中创建了 Artile表主键为1的记录 与 User表 主键为12的两条关系。 另外清除关系绑定用法类似使用remove替代add:
artile1 models.Artile.object.filter(pk1).first()
userSet models.User.object.filter(pk__in[1,2]).all()
artile1.users.remove(*userSet) #解绑指定关系
artile1.users.clear() #清空所有关系
多对多查询
正向查询例如查询Artile表第一条记录有哪些用户关注:
artile1 models.Artile.object.filter(pk1).first()
print(artile1.users.all().values(username)) # 打印关注Artile表第一条记录的用户名称逆向查询例如查询User表第一条记录关注过哪些Artile:
user1 models.User.object.filter(pk1).first()
print(user1.artile__set.all().values(title)) # 打印User表第一条记录关注的文章名称4.4.2 一对多查询
参考 https://juejin.cn/post/6974298891353063431