如何用Django ORM复现指定左连接SQL查询?附模型代码
Django ORM 实现指定左连接查询
先修正你模型里的拼写错误(这些错误会导致代码无法正常运行):
class Product(models.Model): name = models.CharField(max_length=255) # 修正`mdoels`为`models`,补充必填的`max_length`参数 class ProductCharacteristics(models.Model): # 修正`Charateristics`为`Characteristics` name = models.CharField(max_length=255) description = models.TextField() class ProductCharacteristicValues(models.Model): product_characteristic = models.ForeignKey(ProductCharacteristics, on_delete=models.CASCADE) value = models.IntegerField() product = models.ForeignKey(Product, on_delete=models.CASCADE) # 修正`prduct`为`product`
针对你要实现的左连接查询,以下是几种符合Django ORM规范的实现方式:
方法一:用Prefetch精准预取关联数据(推荐)
这种方式先筛选出目标产品的特性值,再关联查询所有特性,既符合ORM最佳实践,又能高效获取数据:
from django.db.models import Prefetch # 先筛选产品ID为1的特性值集合 target_product_values = ProductCharacteristicValues.objects.filter(product_id=1) # 左连接查询所有特性,并预取对应产品1的特性值 characteristics = ProductCharacteristics.objects.prefetch_related( Prefetch('productcharacteristicvalues_set', queryset=target_product_values, to_attr='product_1_values') ).all()
后续可通过characteristic.product_1_values直接访问该特性对应产品1的所有值。
方法二:用FilteredRelation实现带条件的左连接
这种写法更贴近原生SQL的左连接逻辑,在查询阶段直接完成关联筛选:
from django.db.models import FilteredRelation, Q characteristics = ProductCharacteristics.objects.annotate( product_1_values=FilteredRelation( 'productcharacteristicvalues_set', condition=Q(productcharacteristicvalues__product_id=1) ) ).select_related('product_1_values').all()
方法三:直接执行原生SQL
如果想完全复用原SQL语句,可使用raw()方法执行原生查询(注意修正Django自动生成的外键列名):
characteristics = ProductCharacteristics.objects.raw(''' SELECT * FROM ProductCharacteristics as pc LEFT JOIN ProductCharacteristicValues as pcv ON pc.id = pcv.product_characteristic_id WHERE pcv.product_id = 1 ''')
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

