我正在尝试为包含一系列成分的食谱建模。在这些成分中,价格字段取决于另一个模型的值(供应商的位置)。例如,我的食谱可能包含:水、牛肉和盐。
每种成分都有一个价格,这取决于用户所在的位置。 IE。如果我的用户来自德克萨斯州,牛肉和水的价格可能会发生变化,因此食谱的总价也会发生变化。
现在我正在使用以下方法:
class Product(models.Model):
name = models.CharField(_('Name'), max_length=255, help_text=_('Product name'))
price = models.FloatField(_('Sale price'), default=0)
supplier = models.ForeignKey(Supplier, blank=True, null=True, related_name='supplier_products',
on_delete=models.CASCADE)
class IngredientRecipe(models.Model):
product_name = models.CharField(_('Name'), max_length=255, help_text=_('Product name'), blank=True)
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE, related_name='ingredients')
quantity = models.FloatField(_('Quantity'))
class Recipe(models.Model):
user = models.ForeignKey(User, null=True, on_delete=models.CASCADE, related_name='user_recipes')
title = models.CharField(_('Recipe title'), max_length=255, help_text=_('Recipe. Example: american chicken salad'),
blank=True)
我使用此模型和序列化程序来显示与所选位置对应的价格:
class VerySimpleRecipeSerializer(serializers.ModelSerializer):
cost = serializers.SerializerMethodField(read_only=True)
class Meta:
model = Recipe
fields = ['id', 'title', 'cost',]
def get_cost(self, obj):
ingredients_names = obj.ingredients.values('product_name', 'quantity')
total_price = 0
try:
location_id = self.context['request'].query_params.get('location', None)
products = Product.objects.annotate(min_price=Min('price')).filter(
Q(supplier__location_id=location_id) & Q(name__in=[x.get('product_name', None) for x in ingredients_names]),
is_active=True, min_price__lte=F('price')).order_by()
except KeyError:
products = Product.objects.annotate(min_price=Min('price')).filter(
Q(name__in=[x.get('product_name', None) for x in ingredients_names]), is_active=True
min_price=F('price')).order_by()
for ingredient in ingredients_names:
product = products.filter(name=ingredient.get('product_name', None)).last()
if product:
total_price += ingredient.get('quantity', 0) * product.price
return total_price
似乎可以,但是当我添加更多 SerializerMethods 来计算基于供应商位置的其他字段时,性能会受到很大影响。此外,我在使用 @cached_properties 时遇到问题,因为我无法在模型的方法中获取 self.context['request'].query_params.get('location', None)
。
我希望有人能给我另一个观点来解决这个问题。
先谢谢你!