1.表操作
基本操作:
三种增加方式
1.models.UserInfo.objects.create(username='root',password='1234',)
2.dict = {'username':'kaixin','password':'XXX'}
models.UserInfo.objects.create(**dict)
3.obj = models.UserInfo(username='lishang',password='xiaomeng',)
obj.save()
查询全部all()
result = models.UserInfo.objects.all()
result,QuerySet
条件查询filter()
result = models.UserInfo.objects.filter(username='kaixin',password='shangni')
删除delete()
models.UserInfo.objects.filter(id='4').delete()
更改update
models.UserInfo.objects.filter(username='kaixin').update(password='ailishang')
进阶操作:
获取个数count()
models.Tb1.objects.filter(name='seven').count()
大于,小于
# models.Tb1.objects.filter(id__gt=1) # 获取id大于1的值
# models.Tb1.objects.filter(id__gte=1) # 获取id大于等于1的值
# models.Tb1.objects.filter(id__lt=10) # 获取id小于10的值
# models.Tb1.objects.filter(id__lte=10) # 获取id小于10的值
# models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值
in not in
models.Tb1.objects.filter(id__in=[11, 22, 33]) #获取id等于11、22、33的数据
# models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in
# isnull
# Entry.objects.filter(pub_date__isnull=True)
# contains
# models.Tb1.objects.filter(name__contains="ven")
# models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
# models.Tb1.objects.exclude(name__icontains="ven")
# range
# models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and
# 其他类似
# startswith,istartswith, endswith, iendswith,
# order by
# models.Tb1.objects.filter(name='seven').order_by('id') # asc
# models.Tb1.objects.filter(name='seven').order_by('-id') # desc
# group by
# from django.db.models import Count, Min, Max, Sum
# models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
# SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"
# limit 、offset
# models.Tb1.objects.all()[10:20]
# regex正则匹配,iregex 不区分大小写
# Entry.objects.get(title__regex=r'^(An?|The) +')
# Entry.objects.get(title__iregex=r'^(an?|the) +')
# date
# Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
# Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))
# year
# Entry.objects.filter(pub_date__year=2005)
# Entry.objects.filter(pub_date__year__gte=2005)
# month
# Entry.objects.filter(pub_date__month=12)
# Entry.objects.filter(pub_date__month__gte=6)
# day
# Entry.objects.filter(pub_date__day=3)
# Entry.objects.filter(pub_date__day__gte=3)
# week_day
# Entry.objects.filter(pub_date__week_day=2)
# Entry.objects.filter(pub_date__week_day__gte=2)
# hour
# Event.objects.filter(timestamp__hour=23)
# Event.objects.filter(time__hour=5)
# Event.objects.filter(timestamp__hour__gte=12)
# minute
# Event.objects.filter(timestamp__minute=29)
# Event.objects.filter(time__minute=46)
# Event.objects.filter(timestamp__minute__gte=29)
# second
# Event.objects.filter(timestamp__second=31)
# Event.objects.filter(time__second=2)
# Event.objects.filter(timestamp__second__gte=31)
其他常用操作:
一、聚合查询
需要导入模块:from django.db.models import Max, Min, Sum, Count, Avg
关键语法:aggregate(聚合结果别名 = 聚合函数(参数))
查询结果:使用聚合函数,从每一个组中获取结果:字典
注意点:
1 聚合函数必须在分组之后才能使用
2 没有分组,即默认整体就是一组
3 查询结果为 普通字典
"""
聚合查询通常情况下都是配合分组一起使用的
只要是跟数据库相关的模块
基本上都在 django.db.models 里面
上述没有那么应该在 django.db里面
"""
from django.db.models import Max, Min, Sum, Count, Avg
# 1 所有书的平均价格
res = models.Book.objects.aggregate(Avg('price'))
print(res)
# 2 上述方法一次性使用
res = models.Book.objects.aggregate(Max('price'), Min('price'), Sum('price'), Count('pk'), Avg('price'))
print(res)
二、分组查询
1 关键字:annotate
2 默认以当前表 id 分组,并使用聚合函数在组内进行聚合计算,得到结果作为查询结果中组内的属性
from django.db.models import Max, Min, Sum, Count, Avg
# 1 统计每一本书的作者个数
res = models.Book.objects.annotate() # models后面点什么 就是按什么分组
res1 = models.Book.objects.annotate(author_num = Count('authors')).values('title', 'author_num')
res2 = models.Book.objects.annotate(author_num = Count('authors__nid')).values('title', 'author_num')
print(res, res1, res3)
"""
author_num 自己定义的字段 用来存储统计出来的每本书对应的作者个数
"""
# 2 统计每个出版社卖的最便宜的书的价格
res = models.Publish.objects.annotate(min_price = Min('book__price')).values('name', 'min_price')
print(res)
# 3 统计不止一个作者的图书
# 先按照图书分组 求每一本书对应的作者个数
# 过滤出不止一个作者的图书
res = models.Book.objects.annotate(author_num = Count('authors')).filter(author_num__gt = 1).values('title', 'author_num')
print(res)
# 4 查询每个作者出的书的总价格
res = models.Author.objects.annotate(sum_price = Sum('book__price')).values('name', 'sum_price')
print(res)
# 5 统计 price大于150元 的书籍的作者个数
res = models.Book.objects.filter(price__gt = 150).annotate(num_authors = Count('authors')).values('title', 'num_authors')
print(res)
三、F与Q查询
# F查询
"""
能够帮助你直接获取到表中某个字段对应的数据
"""
from django.db.models import F
# 1 将所有书籍的价格提升 10 块
models.Book.objects.update(price = F('price') + 10)
# 2 将 django 书的名称后面加上 ' web' 字
"""
在操作字符类型的数据的时候 F不能够直接做到字符串的拼接
"""
from django.db.models.functions import Concat
from django.db.models import Value
models.Book.objects.filter(title = "django").update(title = Concat(F('title'), Value(' web')))
# Q查询
"""
filter括号内多个参数是and关系
"""
from django.db.models import Q
# Q包裹逗号分割 还是and关系
res1 = models.Book.objects.filter(Q(price__lt = 300), Q(price__gt = 400))
print(res1)
# | or关系
res2 = models.Book.objects.filter(Q(pub_date__lt = '2020-01-01') | Q(price__gt = 300))
print(res2)
# ~ not关系
res3 = models.Book.objects.filter( ~ Q(pub_date__lt = '2020-01-01') | Q(price__lt = 200))
print(res3) # <QuerySet []>
# Q的高阶用法 能够将查询条件的左边也变成字符串的形式
# 提前生成 Q 对象,并使用 append方法 添加条件
q = Q()
q.connector = 'or'
q.children.append(('pub_date__lt', '2020-01-01'))
q.children.append(('price__lt', 200))
res = models.Book.objects.filter(q) # 默认是and关系
print(res)
四、特殊参数choices
1 定义字段时,指定参数 choices
2 choices 的值为元组套元组(事先定义好,一般在该表类中定义该字段之前定义)
3 每一个元组存放两个元素,形成一种对应关系
4 往数据库中存值时,该字段的值存为元组第一个元素即可
5 通过 对象.get_字段名_display() 获取对应的元组第二个元素值,当没有对应关系时,返回的是它本身
示例:
# 定义一个 UserTest 表
class UserTest(models.Model):
name = models.CharField(max_length = 64)
gender_choices = ((1, '男'),(2, '女'),(3, '其他'))
gender = models.IntegerField(choices = gender_choices)
# 同步迁移到数据库
python manage.py makemigrations
python manage.py migrate
# 在 test.py 配置测试环境
# 录入数据
models.UserTest.objects.create(name = '小微', gender = 1)
models.UserTest.objects.create(name = '小芬', gender = 2)
models.UserTest.objects.create(name = '小桃', gender = 3)
models.UserTest.objects.create(name = '小月', gender = 4)
# 验证choices
for user_obj in models.UserTest.objects.all():
print(user_obj.gender, end=' ')
print(user_obj.get_gender_display())
'''
1 男
2 女
3 其他
4 4
'''
连表操作:
利用双下划线和 _set 将表之间的操作连接起来
一对一操作
user_info_obj = models.UserInfo.objects.filter(id=1).first()
print user_info_obj.user_type
print user_info_obj.get_user_type_display()
print user_info_obj.userprofile.password
user_info_obj = models.UserInfo.objects.filter(id=1).values('email', 'userprofile__username').first()
print user_info_obj.keys() print user_info_obj.values()
一对多操作
类似一对一 1、搜索条件使用 __ 连接 2、获取值时使用 . 连接
# 方式一 传对象的形式
pub_obj = models.Publish.objects.get(pk=1)
book = models.Book.objects.create(title="独孤九剑", price=180, pub_date="2018-10-23", publish=pub_obj)
# 方式二 传对象id的形式
book = models.Book.objects.create(title="独孤九剑", price=180, pub_date="2018-10-23", publish_id=1)
多对多操作
user_info_obj = models.UserInfo.objects.get(name=u'Dave')
user_info_objs = models.UserInfo.objects.all()
group_obj = models.UserGroup.objects.get(caption='CEO')
group_objs = models.UserGroup.objects.all()
# 添加数据
#group_obj.user_info.add(user_info_obj)
#group_obj.user_info.add(*user_info_objs)
# 删除数据 #group_obj.user_info.remove(user_info_obj)
#group_obj.user_info.remove(*user_info_objs)
# 添加数据 #user_info_obj.usergroup_set.add(group_obj)
#user_info_obj.usergroup_set.add(*group_objs)
# 删除数据 #user_info_obj.usergroup_set.remove(group_obj)
#user_info_obj.usergroup_set.remove(*group_objs)
# 获取数据 #print group_obj.user_info.all()
#print group_obj.user_info.all().filter(id=1)
# 获取数据 #print user_info_obj.usergroup_set.all()
#print user_info_obj.usergroup_set.all().filter(caption='CEO')
#print user_info_obj.usergroup_set.all().filter(caption='DBA')
跨站请求伪造
django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。
全局:
中间件 django.middleware.csrf.CsrfViewMiddleware
局部:
@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
注:from django.views.decorators.csrf import csrf_exempt,csrf_protect