8

我正在使用 Django Rest Framework,我注意到在 API 的 Web 可浏览部分有一个名为“选项”的按钮,单击它会显示以下内容...

HTTP 200 OK Vary: Accept Content-Type: text/html Allow: HEAD, GET, OPTIONS
{
    "parses": [
        "application/json", 
        "application/x-www-form-urlencoded", 
        "multipart/form-data"
    ], 
    "renders": [
        "application/json", 
        "text/html"
    ], 
    "name": "Products", 
    "description": "API endpoint."
} 

我的问题是,无论如何我可以在这里列出所有过滤器选项以及此网址的其他内容吗?

4

2 回答 2

8

您可以OPTIONS通过覆盖.metadata()视图上的方法来返回任何您想要的东西。

见这里:https ://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/views.py#L340


截至 2015 年的更新:我们现在有一个可定制的元数据 API,使这更容易: http: //www.django-rest-framework.org/api-guide/metadata/

于 2013-02-27T16:43:56.557 回答
4

你完全可以做到这一点。这是一个自定义元数据类,我一直在 StackOverflow 上保持最新状态。这只是列出了所有可用的过滤器、它们的类型和它们的选择。它还列出了类中可用的排序字段:

class SimpleMetadataWithFilters(SimpleMetadata):

    def determine_metadata(self, request, view):
        metadata = super(SimpleMetadataWithFilters, self).determine_metadata(request, view)
        filters = OrderedDict()
        if not hasattr(view, 'filter_class'):
            # This is the API Root, which is not filtered.
            return metadata

        for filter_name, filter_type in view.filter_class.base_filters.items():
            filter_parts = filter_name.split('__')
            filter_name = filter_parts[0]
            attrs = OrderedDict()

            # Type
            attrs['type'] = filter_type.__class__.__name__

            # Lookup fields
            if len(filter_parts) > 1:
                # Has a lookup type (__gt, __lt, etc.)
                lookup_type = filter_parts[1]
                if filters.get(filter_name) is not None:
                    # We've done a filter with this name previously, just
                    # append the value.
                    attrs['lookup_types'] = filters[filter_name]['lookup_types']
                    attrs['lookup_types'].append(lookup_type)
                else:
                    attrs['lookup_types'] = [lookup_type]
            else:
                # Exact match or RelatedFilter
                if isinstance(filter_type, RelatedFilter):
                    model_name = (filter_type.filterset.Meta.model.
                                  _meta.verbose_name_plural.title())
                    attrs['lookup_types'] = "See available filters for '%s'" % \
                                            model_name
                else:
                    attrs['lookup_types'] = ['exact']

            # Do choices
            choices = filter_type.extra.get('choices', False)
            if choices:
                attrs['choices'] = [
                    {
                        'value': choice_value,
                        'display_name': force_text(choice_name, strings_only=True)
                    }
                    for choice_value, choice_name in choices
                ]

            # Wrap up.
            filters[filter_name] = attrs

        metadata['filters'] = filters

        if hasattr(view, 'ordering_fields'):
            metadata['ordering'] = view.ordering_fields
        return metadata

把它放在你的项目中的某个地方,然后设置你的DEFAULT_METADATA_CLASS,你应该已经准备好了,你的OPTIONS请求上有一个新的键,如下所示:

"filters": {
    "sub_opinions": {
        "type": "RelatedFilter"
    },
    "source": {
        "type": "MultipleChoiceFilter",
        "choices": [
            {
                "display_name": "court website",
                "value": "C"
            },
        ]
    }
    ...more...
}

这也将显示choices,反映它在 DRF 中其他地方的处理方式。

于 2015-12-23T00:55:34.120 回答