我有以下型号:
模型
class Item(SafeDeleteModel):
code = models.CharField(max_length=50, null=True, blank=True)
name = models.CharField(max_length=500)
description = models.TextField(blank=True)
category = models.ForeignKey(Category, on_delete=models.PROTECT, null=True, blank=True)
price = models.DecimalField(max_digits=18, decimal_places=6, default=0.0)
class PriceList(SafeDeleteModel):
friendly_id = models.CharField(unique=True, max_length=6, null=True, blank=True, editable=False)
code = models.CharField(max_length=10, null=True, blank=True)
name = models.CharField(max_length=100, null=True)
class PriceListRelation(SafeDeleteModel):
price_list = models.ForeignKey(PriceList, on_delete=models.CASCADE, related_name='price_list', null=False)
item = models.ForeignKey(Item, on_delete=models.CASCADE, related_name='prices_list', null=False, blank=True)
price = models.DecimalField(max_digits=18, decimal_places=6, default=0.0)
一个商品有多个价目表关系,每个价目表关系属于一个价目表。
序列化器
class ItemSerializer(serializers.ModelSerializer):
prices_list = PriceListRelationsSerializer(many=True, read_only=False)
def update(self, instance, validated_data):
if 'prices_list' in validated_data:
prices_list = validated_data.pop('prices_list')
else:
prices_list = None
instance = super().update(instance, validated_data)
for price_list in prices_list:
#code to update/create/delete price lists, this part works fine
#Without this functionality it still duplicates the queries
return instance
class PriceListRelationsSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(read_only=False, required=False)
name = serializers.ReadOnlyField(source='price_list.name')
price_list_id = serializers.PrimaryKeyRelatedField(queryset = PriceList.objects.all(), source='price_list')
视图集
class ItemsViewSet(viewsets.ModelViewSet):
queryset = Item.objects.all().order_by('-id')
serializer_class = ItemSerializer
def partial_update(self, request, pk=None):
item = Item.objects.filter(id = pk).select_related('category').prefetch_related(
Prefetch('prices_list', queryset = PriceListRelation.objects.select_related('price_list').all()),
).get()
serializer = ItemSerializer(item, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_202_ACCEPTED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
问题 我正在尝试使用以下示例数据 PUT/PATCH 到 ItemsViewSet:
/项目/37/
{
"name": "Item 0037",
"price": 10,
"category":2,
"prices_list": [
{
"id": 192,
"price_list_id": 1,
"price": 999.97
},
{
"price_list_id": 2,
"price": 888.99
},
{
"price_list_id": 2,
"price": 234.99
}
]
}
但是,可以看出,对于添加到项目的 3 个价目表,它执行 3 个查询。如何优化?所以当元素多的时候,查询就会多
我正在使用fetch_related来优化查询(GET),有没有类似于update的东西?
额外的
我明白Django验证
price_list_id
存在,我也尝试修改PriceListRelationsSerializer
中的验证但它仍然没有优化。
以下代码执行单个查询并验证
price_list_id
,但不会删除其他单个查询
class PriceListRelationsSerializer(serializers.ModelSerializer):
....
def __init__(self, *args, **kwargs):
self.prices_list = PriceList.objects.all()
self.prices_list = list(self.prices_list)
super().__init__(*args, **kwargs)
def validate_price_list_id(self, value):
try:
price_list = next(item for item in self.prices_list if item.name == value.name)
except StopIteration:
raise serializers.ValidationError('No price list'+ value)
return price_list
任何帮助表示赞赏。 谢谢。