如何在响应中添加额外字段以了解哪个项目触发了搜索结果

Posted

技术标签:

【中文标题】如何在响应中添加额外字段以了解哪个项目触发了搜索结果【英文标题】:How can I add an extra field in the response to understand which item triggered the search result 【发布时间】:2022-01-11 09:51:26 【问题描述】:

我有两个简单的配方和配料模型。

class Ingredient(models.Model):
    id = models.UUIDField(default=uuid.uuid4, primary_key=True, editable=False)
    name = models.CharField(db_column='name', max_length=200, blank=False, null=False, unique=True)

class Recipe(models.Model):
    id = models.UUIDField(default=uuid.uuid4, primary_key=True, editable=False)
    name = models.CharField(db_column='name', max_length=200, blank=False, null=False, unique=True)
    ingredients = models.ManyToManyField(Ingredient, related_name='recipe_ingredients')

我为食谱搜索添加了一个过滤器,我可以在其中添加成分 ID 作为参数。它返回包含这些成分的食谱。过滤器如下,

class RecipeFilter(django_filters.FilterSet):
    ingredient_have = django_filters.CharFilter(method='filter_ingredient_have')

    def filter_ingredient_have(self, queryset, name, value):
        if value:
            ids = value.split(',')
            return queryset.filter(Q(ingredients__id__in=ids))
        return queryset


    class Meta:
        model = Recipe
        fields = []

网址是这样的

/recipes/?ingredient_have=id1,id2

响应类似于


    "items": [
        
            "id": "13261f0d-408d-4a51-9cc2-cb69ee72fe24",
            "name": "Curry",
            "ingredients": [
                
                    "id": "08089ff8-03fb-4946-be61-659d799ca996",
                    "name": "oil"
                ,
                
                    "id": "dc9cb6f2-1810-48eb-b7a7-52a4bd9fdccb",
                    "name": "water"
                
            ]
        
    ]

目前,如果任何成分的 id(任何食谱)是 id1 或 id2,则 url 会为我提供食谱列表。现在我想标记该特定成分(id1/id2),以便前端了解配方在响应中的成分。我想添加一个额外的字段(在成分中),以便我可以在前端了解哪个成分触发了食谱出现在搜索结果中,例如,


    "id": "08089ff8-03fb-4946-be61-659d799ca996",
    "name": "oil",
    "highlight": false/true

“highlight”字段在这里是虚构的,这就是我想要实现的。

我希望我把问题说清楚了。您能给我一些建议/解决方案吗?

提前致谢。

【问题讨论】:

显示您的序列化程序以及突出显示与成分的关系如何? @Sumithran “highlight”字段在最后一个 json 中是虚构的,这就是我想要实现的。 不清楚你想要达到什么目的.. 目前,如果任何成分的 id 是 id1 或 id2,问题中的 url 就会给我食谱。现在我想标记那个特定的成分 (id1/id2),以便前端了解配方在响应中的成分。 【参考方案1】:

您可以通过简单地修改 Ingredients() 类在“成分”模型中添加另一个字段。在您的情况下,您需要BooleanField

class Ingredient(models.Model):
    id = models.UUIDField(default=uuid.uuid4, primary_key=True, editable=False)
    name = models.CharField(db_column='name', max_length=200, blank=False, null=False, unique=True)
    highlight = models.BooleanField(default=False)

不要忘记使用迁移命令,以便将这些更改应用到数据库。

此外,添加诸如default=False 之类的字段可以防止已添加到数据库中的对象出现任何问题。您无需手动为每个添加 ingredients 值,因为它们将被自动分配一个 False 值。

【讨论】:

好的...现在什么时候该值为真? 嗯,添加到某个Recipe 的成分将构建成分列表。因此,您可以做的只是遍历整个列表并检查成分是否与您搜索的 id 匹配。如果是,请尝试突出显示它。 其实这是我的问题,我想在后端而不是前端。 @sadat 您可以遍历所有参数,并尝试使用诸如 Ingredients.objects.filter(id=id1).update(highlight = True) 之类的东西,但之后很难将其设置为 false,因为您正在更改你的数据库。我认为前端将是做你想做的最有效的方式。 请再次阅读问题。我很抱歉发音不好【参考方案2】:

我在序列化器中解决了这个问题,

class IngredientSerializer(BaseSerializer):
    isHighlight = serializers.SerializerMethodField()
    def get_isHighlight(self, obj):
        ids = []
        if 'request' in self.context and 'ingredient_have' in self.context['request'].query_params:
            ingredient_have = self.context['request'].query_params['ingredient_have']
            if ingredient_have:
                ids.extend(ingredient_have.split(','))
        if str(obj.id) in ids:
            return True
        return False

这就是我如何获取查询参数并突出显示成分以指示此食谱为何出现在搜索结果中的方式。

【讨论】:

以上是关于如何在响应中添加额外字段以了解哪个项目触发了搜索结果的主要内容,如果未能解决你的问题,请参考以下文章

Symfony 2.1.11 图像数据响应在响应正文的开头添加了额外的字节

如何在 django 注册表单中添加额外的字段?

如何知道触发了哪个 QMenu 的动作

React 转换服务器响应(向对象添加额外字段)

Loki 分别显示日志消息和额外字段

Rails - 如何在索引控制器方法中使用额外字段渲染json