如何将指定SQL查询转为Django ORM语句(使用select_related)
正确的Django ORM实现方式
首先纠正你代码里的核心错误:select_related()的参数是关联模型的字段名(字符串),用来指定要预加载的关联对象,不能直接传入id=request.user这类参数。
前提确认模型关联
假设你的模型定义如下(对应原SQL的关联逻辑):
# models.py from django.contrib.auth.models import User from django.db import models class SUbPlans(models.Model): empId = models.CharField(unique=True, max_length=64) # 对应SQL中的SUbPlans.empId # 其他字段... class Orders(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, db_column='user_id') # 外键关联SUbPlans的empId字段,对应SQL中的orders.selected_id selected_sub_plan = models.ForeignKey( SUbPlans, on_delete=models.CASCADE, db_column='selected_id', to_field='empId', related_name='orders' # 自定义反向关联名称,方便调用 ) # 其他字段...
对应原SQL的ORM查询
原SQL是SUbPlans LEFT JOIN orders并过滤orders.user_id=2,如果需要严格匹配左连接逻辑(保留无对应Orders的SUbPlans,同时仅保留属于当前用户的Orders记录),写法如下:
from django.db.models import Q # 获取当前用户关联的SUbPlans(含无对应Orders的记录) user_sub_plans = SUbPlans.objects.select_related('orders').filter( Q(orders__user=request.user) | Q(orders__isnull=True) ).all()
如果你的需求等价于仅获取有对应当前用户Orders的SUbPlans(原SQL中WHERE orders.user_id=2会自动过滤掉无Orders的记录,等价于内连接),可以简化为:
# 获取有当前用户Orders关联的SUbPlans user_sub_plans = SUbPlans.objects.select_related('orders').filter(orders__user=request.user).all()
关键说明
select_related('orders'):这里的orders是Orders模型中外键字段设置的related_name,如果没有设置related_name,默认的反向关联名称是orders_set,需要写成select_related('orders_set')。filter(orders__user=request.user):通过双下划线__跨表过滤Orders的user字段等于当前登录用户。
内容的提问来源于stack exchange,提问作者ReaL_HyDRA
相关产品推荐
相关产品推荐

