用 django orm 写 exists 条件过滤

本文详细介绍了如何在Django中使用ORM表达SQL的exists子查询,通过两步操作:定义子查询条件和使用annotate及filter实现子查询过滤,解决复杂查询难题。

要用django的orm表达sql的exists子查询,是个比较麻烦的事情,需要做两部来完成

from django.db.models import Exists, OuterRef


# 1. 定义子查询条件
relative_comments = Comment.objects.filter(
    post=OuterRef('pk'),  # 注意外键关联方式:post为Comment表的字段,pk表示关联另一表主键
)

# 2. 使用annotate和filter共同定义子查询
Post.objects.annotate( # 使用exists定义一个额外字段
    recent_comment=Exists(recent_comments),
).filter(recent_comment=True)  # 在条件中通过检查额外字段实现exists子查询过滤


这种方式比较麻烦,有其它简便方式的欢迎分享

官网参考: https://docs.djangoproject.com/en/2.1/ref/models/expressions/#filtering-on-a-subquery-expression

### 使用 Django ORM 进行数据导出 为了利用 Django ORM 实现数据导出功能,通常会结合 Python 的第三方库 `openpyxl` 来处理 Excel 文件的生成。下面展示了一个完整的流程来说明如何从数据库中提取数据并将其转换成 Excel 表格文件。 #### 准备工作 确保安装了必要的依赖项: ```bash pip install openpyxl ``` #### 定义模型类 假设有一个名为 `BookInfo` 和 `HeroInfo` 的两个模型类用于表示书籍及其英雄角色的信息[^3]。 ```python from django.db import models class BookInfo(models.Model): bid = models.AutoField(primary_key=True) btitle = models.CharField(max_length=200) class HeroInfo(models.Model): hid = models.AutoField(primary_key=True) hname = models.CharField(max_length=200) hbook = models.ForeignKey(BookInfo, on_delete=models.CASCADE) ``` #### 编视图函数 在视图层编逻辑以响应用户的请求并将数据导出为 Excel 文件。这里定义了一个简单的 API 接口 `/export_excel/` 用来触发导出操作[^4]。 ```python import os from django.http import HttpResponse from django.views.decorators.csrf import csrf_exempt from .models import BookInfo, HeroInfo import openpyxl as op @csrf_exempt def export_excel(request): response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') filename = "books_and_heroes.xlsx" response['Content-Disposition'] = f'attachment;filename={os.path.basename(filename)}' # 创建一个新的工作簿对象 wb = op.Workbook() # 处理 BookInfo 数据 book_ws = wb.active book_ws.title = 'Books' books_data = BookInfo.objects.values('bid', 'btitle') if books_data.exists(): titles = ['ID', 'Title'] book_ws.append(titles) for item in books_data: row = [item[field] for field in titles] book_ws.append(row) # 处理 HeroInfo 数据 hero_ws = wb.create_sheet(title="Heroes") heroes_data = HeroInfo.objects.select_related('hbook').values( 'hid', 'hname', 'hbook__btitle') if heroes_data.exists(): titles = ['ID', 'Name', 'Belongs To Book Title'] hero_ws.append(titles) for item in heroes_data: row = [ item['hid'], item['hname'], item.get('hbook__btitle', '') ] hero_ws.append(row) wb.save(response) return response ``` 这段代码实现了以下几点: - 设置 HTTP 响应头部信息以便浏览器识别这是一个下载链接。 - 利用 `openpyxl` 库创建新的 Excel 工作簿,并分别向其中的工作表添加来自不同模型的数据集。 - 对于外键字段(如 `HeroInfo.hbook`),使用 `select_related()` 方法优化查询性能,减少 SQL 查询次数。 - 将最终的结果保存至内存中的文件流而非磁盘上实际存在的文件路径,从而可以直接返回给客户端作为附件下载。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值