Python 如何使用generics.ListAPIView和serializers.ModelSerializer在Django Rest框架中复制此SQL查询
实际上,我找不到任何类似于我试图使用DRF Django Rest框架来使用用例语句和左连接的方法,是的,这可以在我正在处理的项目的前端完成,但我宁愿不让前端在加载产品列表时潜在地发送100个请求 没有什么我可以真正添加到这一点,但我已经尝试了许多不同的方式做下面Python 如何使用generics.ListAPIView和serializers.ModelSerializer在Django Rest框架中复制此SQL查询,python,django,python-3.x,django-rest-framework,Python,Django,Python 3.x,Django Rest Framework,实际上,我找不到任何类似于我试图使用DRF Django Rest框架来使用用例语句和左连接的方法,是的,这可以在我正在处理的项目的前端完成,但我宁愿不让前端在加载产品列表时潜在地发送100个请求 没有什么我可以真正添加到这一点,但我已经尝试了许多不同的方式做下面 SELECT p.itemno, CASE WHEN cp.price IS NULL THEN p.HighSell ELSE cp.price END AS price F
SELECT
p.itemno,
CASE
WHEN cp.price IS NULL THEN p.HighSell
ELSE cp.price
END AS price
FROM
api_product AS p
LEFT JOIN
api_customerprices AS cp ON p.itemno = cp.itemno
AND cp.customerno = 'Examplecust'
WHERE
p.FreeStock > 0
or restockDate > '1900-01-01'
以下是我的模型:
class Product(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
itemno = models.CharField(max_length=100)
description = models.TextField(null=True)
colour = models.CharField(max_length=100, null=True)
manufacturerCode = models.CharField(max_length = 100, null=True)
RRP = models.DecimalField(max_digits=6, decimal_places=2, null=True)
SSP = models.DecimalField(max_digits=6, decimal_places=2,null=True)
FreeStock = models.IntegerField(null=True)
ItemSpec1 = models.CharField(max_length=100, null=True)
ItemSpec2 = models.CharField(max_length=100, null=True)
ItemSpec3 = models.CharField(max_length=100, null=True)
ItemSpec4 = models.CharField(max_length=100, null=True)
ItemSpec5 = models.CharField(max_length=100, null=True)
ItemSpec6 = models.CharField(max_length=100, null=True)
ItemSpec7 = models.CharField(max_length=100, null=True)
ItemSpec8 = models.CharField(max_length=100, null=True)
ItemSpec9 = models.CharField(max_length=100, null=True)
ItemSpec10 = models.CharField(max_length=100, null=True)
TI = models.IntegerField(null=True)
HI = models.IntegerField(null=True)
Item_Height = models.DecimalField(max_digits=6, decimal_places=2, null=True)
Item_Length = models.DecimalField(max_digits=6, decimal_places=2, null=True)
Item_Width = models.DecimalField(max_digits=6, decimal_places=2, null=True)
ProductPaging_Height = models.DecimalField(max_digits=6, decimal_places=2, null=True)
ProductPaging_Length = models.DecimalField(max_digits=6, decimal_places=2, null=True)
ProductPaging_Width = models.DecimalField(max_digits=6, decimal_places=2, null=True)
CartonHeight = models.DecimalField(max_digits=6, decimal_places=2, null=True)
CartonLength = models.DecimalField(max_digits=6, decimal_places=2, null=True)
CartonWidth = models.DecimalField(max_digits=6, decimal_places=2, null=True)
palletQty = models.IntegerField(null=True)
cartonQty = models.IntegerField(null=True)
restockDate = models.DateField(null=True)
IPG = models.CharField(max_length=100, null=True)
CatalogueTheme = models.CharField(max_length=100, null=True)
Analysis2 = models.CharField(max_length=100, null=True)
Electrical_or_Housewares = models.CharField(max_length=100, null=True)
HighSell = models.DecimalField(max_digits=6, decimal_places=2, null=True)
Analysis1 = models.CharField(max_length=100, null=True)
Image = models.TextField(null=True, blank=True)
MarketingText = models.TextField(null=True, blank=True)
SearchTerms = models.TextField(null=True, blank=True)
ItemVariant = models.CharField(max_length=100)
Categories = models.CharField(max_length=249, null=True)
def __str__(self):
return self.itemno
class CustomerPrices(models.Model):
customerNo = models.CharField(max_length=20)
itemno = models.CharField(max_length=20)
price = models.DecimalField(max_digits=6, decimal_places=2)
startDate = models.DateField()
endDate = models.DateField()
def __str__(self):
return self.customerNo
这是我的序列化程序
class OauthProdListSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = (
'id',
'itemno',
'description',
'colour',
'RRP',
'SSP',
'manufacturerCode',
'FreeStock',
'restockDate',
'Image',
'HighSell',
'ItemVariant',
'Categories'
)
class OCustomerPricesSerializer(serializers.ModelSerializer):
class Meta:
model = CustomerPrices
fields = (
'id',
'customerNo',
'itemno',
'price'
)
我只是把它写在我的头上,所以你需要一些努力才能让它工作 您的产品和客户价格之间没有关系。您需要在两个表之间直接添加Foreignkey,或者需要在它们之间添加一个带有Foreignkey的中间表。 您的查询将类似于:
Q
是django查询对象-请参阅
results=CustomerPrices.objects.filter(
Q(itemno_uufreestock_uugt=0)| Q(itemno_urestockdate_uugt='1900-0-01'),
customerno='Examplecust'
)
#您的case语句可以在代码逻辑中处理:
def case_声明(结果):
如果不是结果价格:
返回结果。HighSell
返回结果。价格
我不太清楚您的意思,但您可以通过运行以下命令获取应用程序中所有表的SQL:
python manage.py sqlall your_app
或者要将sql转换为django,请使用:
Person.objects.raw('your_sql_query')
找到了一种方法来执行我想要的,结果发现我缺少了SerializerMethodField()方法的知识,一旦我发现我很快就得到了它
class ProdListSerializer(ModelSerializer):
price = SerializerMethodField()
class Meta:
model = Product
fields = [
'id',
'itemno',
'description',
'colour',
'RRP',
'SSP',
'manufacturerCode',
'FreeStock',
'restockDate',
'Image',
'ItemVariant',
'Categories',
'price'
]
def get_price(self, obj):
itemno = obj.itemno
customerNo = self._context['view'].request.query_params.get('customerNo', '')
if customerNo:
customerPrice = CustomerPrices.objects.filter(
Q(customerNo=customerNo) &
Q(itemno=itemno)
).values('price').first()
if customerPrice:
return customerPrice
else:
return Product.objects.filter(itemno=itemno).values('HighSell').first()
else:
return Product.objects.filter(itemno=itemno).values('HighSell').first()
您在django中已经有一些模型了吗,还是只想执行原始sql?是的,这些模型已经存在于我的项目中,我想知道如何使用这些模型在DRF中执行等效的代码到目前为止,您在代码中尝试了哪些方法?有多种方法我没有代码,但实际上我找不到任何关于如何复制case语句或左连接这样简单的东西的文档,如果你知道一种做上述事情的方法,那将非常有帮助。请你发布你的模型。希望这有帮助,如果有,请友好地投票并接受我的答案。谢谢你的回复,但我仍然不确定我将如何在DRF中使用该代码,部分原因是经验。这比单张stackoverflow罚单的范围稍大一些。我建议你花点时间了解django和DRF的基本知识,否则你会经常被卡住。*谢谢你的回复,但我仍然不确定我将如何在DRF中使用这些代码,部分原因是我的经验,比如如何在视图中应用每行逻辑我的意思是我想向通过Django Rest框架访问数据的任何人返回该查询的结果,但也就是说有使用objects.raw()的功能但是,当通过序列化程序运行时,它不会显示联接表中的字段,或者如果尝试在序列化程序中指定字段,它将失败,因为联接表中指定的字段在模型中不存在,我将更新问题以包括序列化程序