聚合查询函数是对一组值执行计算, 并返回单个值 。
Django 使用聚合查询前要先从 django.db.models 引入 Avg、Max、Min、Count、Sum (首字母大写)。
Django
django.db.models
Avg、Max、Min、Count、Sum
计算所有图书的平均价格:
12345
from django.db.models import Avg,Max,Min,Count,Sum # 引入函数...res = models.Book.objects.aggregate(Avg("price"))print(res, type(res))...
12
res=models.Book.objects.aggregate(c=Count("id"),max=Max("price"),min=Min("price"))print(res,type(res)
1
from django.db.models import Avg,Max,Min,Count,Sum # 引入函数
MySQL 中的 limit 相当于 ORM 中的 QuerySet 数据类型的切片。
annotate 里面放聚合函数。
1234
res = models.Publish.objects.values("name").annotate(in_price = Min("book__price"))print(res)<QuerySet [{'name': '菜鸟出版社', 'in_price': Decimal('100.00')}, {'name': '明教出版社', 'in_price': Decimal('300.00')}]>
res = models.Book.objects.annotate(c = Count("authors__name")).values("title","c")print(res)<QuerySet [{'title': '菜鸟教程', 'c': 1}, {'title': '吸星大法', 'c': 1}, {'title': '冲灵剑法', 'c': 1}]>
res = models.Book.objects.filter(title__startswith="菜").annotate(c = Count("authors__name")).values("title","c")print(res)
res = models.Book.objects.annotate(c = Count("authors__name")).filter(c__gt=0).values("title","c")print(res)<QuerySet [{'title': '菜鸟教程', 'c': 1}, {'title': '吸星大法', 'c': 1}, {'title': '冲灵剑法', 'c': 1}]>
res = models.Book.objects.annotate(c = Count("authors__name")).order_by("-c").values("title","c")print(res)
res = models.Author.objects.annotate(all = Sum("book__price")).values("name","all")print(res)
F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值
F 动态获取对象字段的值,可以进行运算。
Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取余的操作。
修改操作(update)也可以使用 F() 函数。
from django.db.models import F...book=models.Emp.objects.filter(salary__gt=F("age")).values("name","age")...
res = models.Book.objects.update(price=F("price")+100)print(res)
之前构造的过滤器里的多个条件的关系都是 and,如果需要执行更复杂的查询(例如 or 语句),就可以使用 Q 。
Q 对象可以使用 & | ~ (与 或 非)操作符进行组合。优先级从高到低:~ & |。
from django.db.models import Qres=models.Book.objects.filter(Q(price__gt=350)|Q(title__startswith="菜")).values("title","price")print(res)
res = models.Book.objects.filter(Q(title__endswith="菜") | ~Q(Q(pub_date__year=2010) & Q(pub_date__month=10)))print(res)
res = models.Book.objects.filter(Q(pub_date__year=2004) | Q(pub_date__year=1999), title__contains="菜")print(res)
Q 对象和关键字混合使用,Q 对象要在所有关键字的前面:
StudyDjanog/TestModel/model.py
class Users(models.Model): name = models.CharField(max_length=32) pwd = models.CharField(max_length=32)
python manage.py makemigrations TestModel python manage.py migrate TestModel
TestModel\views.py
1234567891011121314151617
def user_login(request): if request.method != "POST": return JsonResponse({'code': -1, 'msg': 'method must is POST'}) data = json.loads(request.body) user_name = data.get('username') pwd = data.get("pwd") print(data) try: user_entry = Users.objects.get(name=user_name, pwd=pwd) if user_entry: # 设置登录的session request.session["user"] = user_name return JsonResponse({'code': 1, 'msg': 'login is success'}) except ObjectDoesNotExist: return JsonResponse({'code': -1, 'msg': 'login is fail111'})
TestModel\middleware\authen.py
12345678910111213141516171819202122232425
from django.http import JsonResponsefrom django.shortcuts import redirect,renderfrom django.utils.deprecation import MiddlewareMixinimport re#白名单#将登陆、登出、验证登陆请求设为白名单,不进行用户验证。#这里设置了/static/静态文件,因为我这个项目静态文件没走nginx,如果静态文件通过nginx访问,可以不需要设置exclued_path = ["/login/","/testModel/login/","/logout/","/login_ajax_check","/static/"]#用来验证用户是否有权限登陆的中间件class AuthenticationMiddle(MiddlewareMixin): def process_request(self, request): url_path = request.path #如果不在请求在白名单里 if url_path not in exclued_path: #如果未登陆,则调转到登陆页面,将请求的url作为next参数 # if not request.user.is_authenticated: if not request.session.get("user"): # return redirect("/login/?next={url_path}".format(url_path=url_path)) return JsonResponse({'code': -1, 'msg': 'login is failed2222'}) #如果已经登陆,则通过 else: pass
StudyDjanog\StudyDjanog\settings.py
1234567891011
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'TestModel.middleware.authen.AuthenticationMiddle', # 引用自定义中间件]
123456789101112131415
import requestsdata ={"username": "admin", "pwd": "123456"}rs = requests.session()resp = rs.post("http://127.0.0.1:8000/testModel/login/", json=data)print(resp.text)resp1 = rs.get("http://127.0.0.1:8000/testModel/userQuery")print(resp1.text){"code": 1, "msg": "login is success"}<p>runoob runoob </p>