Django ORM查询

问题描述

我也是djangosql的新手。 我需要列出供应商产品的清单,这些清单具有相对便宜的产品,然后再登录(使用相同的product_id)才能从其他供应商处获得。 要求:Django=2.2 Postgresql=9.6 让我知道如何通过django-ORM来执行此操作,以及仅使用sql语言来编写什么代码 这是模型。

Models.py
class Product(models.Model):
    name = models.CharField('product name',max_length=50)
    product = models.CharField('vendor code',default=None,max_length=50,unique=True)

class supplier(models.Model):
    name = models.CharField('supplier name',default='',max_length=50)

Class supplierProduct(models.Model): 
    supplier = models.ForeignKey(supplier,on_delete=models.CASCADE)
    product = models.ForeignKey(Product,on_delete=models.CASCADE)
    product_price = models.DecimalField('Price',max_digits=11,decimal_places=2)
    availability = models.BooleanField(default=False)

Views.py
def foo(request):
    user = request.user

解决方法

您可以使用Exists subquery [Django-doc]

from django.db.models import Exists,OuterRef,Q

SupplierProduct.objects.filter(
    Exists(SupplierProduct.objects.filter(
        ~Q(supplier_id=OuterRef('supplier_id')),product_id=OuterRef('product_id'),product_price__lt=OuterRef('product_price')
    ))
)

因此,我们保留了SupplierProduct,其中存在SupplierProduct,其中supplier不同,product_id相同且价格较低。

之前,您先注释,然后过滤:

Django-2.2 and older

from django.db.models import Exists,Q

SupplierProduct.objects.annotate(
    has_cheaper=Exists(SupplierProduct.objects.filter(
        ~Q(supplier_id=OuterRef('supplier_id')),product_price__lt=OuterRef('product_price')
    ))
).filter(has_cheaper=True)
,
SupplierProduct.objects.annotate(
    has_cheaper=Exists(SupplierProduct.objects.filter(
        Q(supplier__name=user),~Q(supplier_id=OuterRef('supplier_id')),product_price__gt = OuterRef('product_price')
        )
    )
).filter(availability=True,has_cheaper=True)