Django ORM高级应用方法详解

自定义查询方法

Django ORM提供了很多内置的查询方法,但是有时候我们需要自定义一些特殊的查询方法。这时可以使用queryset.annotate()queryset.filter()方法来实现自定义查询。

from django.db.models import Count, Q

# 自定义查询方法
def get_custom_queryset(self):
    queryset = self.annotate(
        num_comments=Count('comments', distinct=True),
        num_likes=Count('likes', distinct=True),
    ).filter(
        Q(num_comments__gte=10) | Q(num_likes__gte=10)
    )
    return queryset

数据库分组查询

Django ORM支持使用annotate()方法实现分组查询,并且支持使用aggregation函数进行统计。

from django.db.models import Count

# 查询每个tag下有多少篇文章
queryset = Article.objects.annotate(num_articles=Count('tags')).values('tags__name', 'num_articles')

跨表关联查询

Django ORM支持通过外键和多对多关系进行跨表查询,可以使用related_namerelated_query_name来指定关联名称和查询名称。

from django.db.models import Q

# 查询所有用户发布的文章
queryset = Article.objects.filter(user__username='admin')

# 查询所有评论过的文章
queryset = Article.objects.filter(comments__user__username='admin')

# 查询所有被喜欢过的文章
queryset = Article.objects.filter(likes__user__username='admin')

# 查询所有tag为'Python'的文章
queryset = Article.objects.filter(tags__name='Python')

# 查询当前用户关注的用户发布的文章
queryset = Article.objects.filter(
    user__in=User.objects.filter(followers__follower=request.user)
)

使用子查询查询

Django ORM支持使用子查询查询,并且可以使用SubqueryOuterRef来引用外层的查询。

from django.db.models import OuterRef, Subquery

# 查询每个用户评论数量排名前三的文章
top3_query = Comment.objects.filter(
    article=OuterRef('pk')
).order_by('-id')[:3].values('id')
queryset = Article.objects.annotate(
    num_comments=Count('comments', distinct=True)
).annotate(
    top3_comments=Subquery(top3_query)
).order_by('-num_comments')

使用MySQL专有方法

虽然Django ORM是支持多种数据库的,但是不同的数据库具有不同的特性和功能。如果要使用MySQL专有的方法,可以通过Func函数来实现。

from django.db.models import F, Func

# 查询每个用户发布的文章数量
queryset = Article.objects.annotate(
    num_articles=Func(
        F('user_id'),
        function='COUNT',
        distinct=True,
        output_field=models.IntegerField(),
    )
)

使用F()函数更新数据

Django ORM支持使用F()函数来实现对数据库的原子更新操作。这样可以避免并发更新数据出现的问题。

from django.db.models import F

# 对数据进行原子更新,使点赞数加1
Article.objects.filter(id=1).update(likes=F('likes')+1)

批量插入数据

Django ORM支持使用bulk_create()方法批量插入数据。这样可以极大地提高插入数据的效率。

Article.objects.bulk_create([
    Article(title='title1', content='content1', user_id=1),
    Article(title='title2', content='content2', user_id=2),
    Article(title='title3', content='content3', user_id=3),
])

执行原生SQL查询

虽然Django ORM提供了许多便捷的方法,但是有些复杂的查询可能无法使用ORM来实现。这时可以使用RawSQL来执行原生SQL查询。

from django.db import connection
from django.db.models import Value
from django.db.models.functions import Coalesce

cursor = connection.cursor()
cursor.execute('SELECT COUNT(*) FROM myapp_articles WHERE is_published = 1')
num_published = cursor.fetchone()[0]

queryset = Article.objects.annotate(
    num_published=Value(num_published, output_field=models.IntegerField())
).annotate(
    num_unpublished=Coalesce('num_articles')-F('num_published')
)

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Django ORM高级应用方法详解 - Python技术站

(0)
上一篇 2023年3月12日
下一篇 2023年3月12日

相关文章

  • django+celery +rabbitmq

    celery是一个python的分布式任务队列框架,支持 分布的 机器/进程/线程的任务调度。采用典型的生产者-消费者模型 包含三部分:1. 队列 broker :可使用redis ,rabbitmq ,或关系数据库作为broker 2.处理任务的消费者workers : 队列中有任务时就发出通知,worker收到通知就去处理 3.任务结果存储 backen…

    Django 2023年4月13日
    00
  • Django模板系统

    Django 的模板系统是一个强大的工具,它提供了一种将数据和 HTML 页面分离的方法,从而让开发人员可以更容易地维护和修改代码。在本文中,我们将深入了解 Django 模板系统的各个方面,包括模板语法、模板继承和模板标签等。 模板语法 Django 模板系统使用类似于 Jinja2 的模板语法。模板语法的主要特点是使用双大括号 {% … %} 和单大…

    Django 2023年3月12日
    00
  • DRF (Django REST framework) 框架介绍(3)

    1. Request REST framework 传入视图的request对象不再是Django默认的HttpRequest对象,而是REST framework提供的扩展了HttpRequest类的Request类的对象。 REST framework 提供了Parser解析器,在接收到请求后会自动根据Content-Type指明的请求数据类型(如JSO…

    Django 2023年4月10日
    00
  • 在Ubuntu里如何创建Django超极用户?

    创建Django超级用户可以通过以下步骤实现: 确认Django已经安装,并且已经创建了project和app 在Ubuntu里面可以使用以下命令来安装Django: sudo apt install python3-django 使用以下命令创建一个Django项目(project): django-admin startproject myproject…

    Django 2023年5月15日
    00
  • [django]模板template原理

    django 中的render和render_to_response()和locals(): http://www.cnblogs.com/wangchaowei/p/6750512.html 什么是contetxt https://www.zhihu.com/question/26387327 context可以理解为环境变量,不同的环境中意义不同 tem…

    Django 2023年4月10日
    00
  • Django中Middleware中间件

    Django中Middleware中间件 1 Middleware中间件概述 django中间middleware实质就是一个类,django会根据自己的规则在合适的时机执行中间件相应的方法。实际上当我们想在发起请求到服务器views处理函数,我们想对请求做一些提前处理,此时中间件就上场了。 django在settings模块中,有一个MIDDLEWARE_…

    Django 2023年4月10日
    00
  • 详解Django admin高级用法

    详解Django admin高级用法 Django admin是Django自带的管理员后台管理系统,可以方便地进行数据库管理,数据展示,数据处理等功能。本文将详细讲解如何使用Django admin的高级用法。 1. 自定义管理器 在Django admin中,如果希望对某个Model进行管理时,需要先创建一个管理器类,例如: from django.co…

    Django 2023年5月16日
    00
  • Django学习报错记录

    1. 运行manage.py任务  makemigrations时,报错: doesn’t declare an explicit app_label and isn’t in an application in INSTALLED_APPS. 解决:在全局setting.py的 INSTALLED_APPS中 添加 app的名字,如   2. 在添加一个生…

    2023年4月10日
    00
合作推广
合作推广
分享本页
返回顶部