相关模型上的Django注释

相关模型上的Django注释,django,django-queryset,models,calculated-field,django-related-manager,Django,Django Queryset,Models,Calculated Field,Django Related Manager,拥有这些模型(简化): 在某些情况下,我需要得到一份食谱列表,在每种配料上标记“是否是用户拥有该产品”。根据给定的用户,可能还有其他计算字段。 我想要的示例: >>> Recipe.objects.get_for_user(user=user)[0].ingredients[0].is_user_have >>> True 但是,当然,在其他情况下,我不希望这个字段附加到配料上 我知道我需要定制经理。但简单的解决方案——将“is_user_have”添加为成

拥有这些模型(简化):

在某些情况下,我需要得到一份食谱列表,在每种配料上标记“是否是用户拥有该产品”。根据给定的用户,可能还有其他计算字段。 我想要的示例:

>>> Recipe.objects.get_for_user(user=user)[0].ingredients[0].is_user_have
>>> True
但是,当然,在其他情况下,我不希望这个字段附加到配料上

我知道我需要定制经理。但简单的解决方案——将“is_user_have”添加为成分模型的属性,使用get_for_user方法定义自定义管理器,调用base get_queryset,然后在for循环中填充该字段——不起作用

更新1
我找到了如何获得我想要的注释,这是我的配料定制管理器:

class UserIngredientsManager(models.Manager):
    def get_queryset(self):
    result = super(UserIngredientsManager, self).get_queryset()

    return (result
        .annotate(
            user_have_count=models.Count(
                models.Case(
                    models.When(
                        # Hardcoded !!!
                        product__userproduct__user_id=1,
                        then=True),
                    output_field=models.IntegerField())))
        .annotate(
            is_user_have=models.Case(
                models.When(
                    user_have_count__gt=0,
                    then=models.Value(True)),
                output_field=models.BooleanField(),
                default=models.Value(False))))
但有两个问题:

  • 我无法将用户传递给此管理器(其硬编码用于测试)
  • 当我需要这个注释时,我不能为情境创建代理模型(见下文),它只在我替换成分模型上的默认管理器时才起作用
  • 此代码不起作用,因为使用了与配料默认相关的管理器:

    class RecipeWithUserInfo(Recipe):
        class Meta:
            proxy = True
    
        objects = UserRecipesManager()
        ingredients = UserIngredientsManager()
    
    仅当我替换成分模型上的默认管理器时(但这不是我想要的):


    您介意在添加属性和自定义后显示代码吗?您介意在添加属性和自定义后显示代码吗?
    class RecipeWithUserInfo(Recipe):
        class Meta:
            proxy = True
    
        objects = UserRecipesManager()
        ingredients = UserIngredientsManager()
    
    class Ingredient(models.Model):
        ...
        objects = UserIngredientsManager()