使您的API仅返回所需字段
#python #django #api #elasticsearch

嘿,

在此博客中,我将向您展示如何仅返回用户通过在URL中作为参数传递的API中的那些字段。这样,您的API用户只能请求他们需要的那些字段,这将消除您的API响应中的一些不必要的混乱。

如果您对URL参数不了解,请前往this link for some reference.

如果您是视觉学习者,请查看此博客的视频版本。

https://www.youtube.com/watch?v=ClB97LGuipU

供参考,我将使用我在上一个博客中创建的演示API。您可以找到该API here的代码。

Image description

现在,首先在浏览器的URL栏中传递一些参数,然后按Enter。

Image description

您可以看到,即使在URL栏中通过了一些字段,API仍在返回所有字段。这很明显,因为我们尚未实现任何逻辑。

现在,让我们实现该逻辑。为此,我们将使用以前的博客代码中的MovieHaystackSerializer
现在,您将看到与通常在序列化器中写的不同的代码。截至目前,请忽略新事物,并且仅关注我们序列化器的__init__fields。因此,首先,我们将通过越过__init__方法编辑MovieHayStackSerializer

# 3rd party imports
from drf_haystack.serializers import HaystackSerializer

# local imports
from .search_indexes import MovieIndex


class MovieHayStackSerializer(HaystackSerializer):
    class Meta:
        # The `index_classes` attribute is a list of which search indexes
        # we want to include in the search.
        index_classes = [MovieIndex]

        # The `fields` contains all the fields we want to include.
        # NOTE: Make sure you don't confuse these with model attributes. These
        # fields belong to the search index!
        fields = [
            "title",
            "description",
            "year",
            "rating",
            "global_ranking",
            "length",
            "revenue",
            "genre",
            "country",
            "director",
        ]

    def __init__(self, *args, **kwargs):
        super(MovieHayStackSerializer, self).__init__(*args, **kwargs)
        # get the query params
        fields_in_url_params = self.context["request"].GET.get("fields", None)
        if fields_in_url_params:
            # split the params from comma to make a list
            fields_in_url_parmas_list = fields_in_url_params.split(",")
            existing_fields = set(self.fields)  # -> keys of all fields

            # get all the fields which are not in params but declared in meta class above
            # our_fields = {'title', 'description', 'year', '....'}
            # fields_from_urls = {'title', 'year'}
            # operation = our_fields - fields_from_url => {'description', '.....'}
            fields_to_remove = existing_fields - set(fields_in_url_parmas_list)

            # now since we have fields 
            for field in fields_to_remove:
                self.fields.pop(field)  # remove this field

现在,让我们看看我们在这里做了什么。首先,我们覆盖了序列化器的__init__方法。在这种方法中,我们从URL获取查询参数,然后我们通过逗号将它们分开以列出列表。之后,我们获得了在Meta类中声明的所有字段。现在,我们正在获得这两个列表之间的区别。区别将是我们必须从序列化器中删除的字段。之后,我们从序列化器中删除了这些字段。

现在,让我们看看当我们通过URL栏中的某些字段时会发生什么。

Image description

Image description

您可以看到,现在我们只获取了在URL栏中通过的那些字段。这就是您只能从API中返回用户通过以参数传递的API的那些字段。
链接repo -https://github.com/selftaughtdev-me/movie-search-api

Image description

如果您有任何疑问或建议,请随时在下面发表评论。我很乐意为您提供帮助。另外,如果您喜欢此博客,请与您的朋友和同事分享。您也可以在TwitterLinkedIn上关注我,以获取有关我的新博客的最新信息。