在Django Rest框架选项请求中显示过滤器和排序

时间:2013-02-27 16:03:07

标签: django django-rest-framework

我正在使用Django Rest Framework我注意到在Web上可浏览的部分API中有一个名为'options'的按钮,当点击它时会显示以下内容...

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."
} 

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

2 个答案:

答案 0 :(得分:6)

您可以通过覆盖视图上的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/

答案 1 :(得分:0)

你可以完全做到这一点。这是我在StackOverflow上保持最新的custom metadata class。这只列出了所有可用的过滤器,它们的类型和选择。它还列出了类中可用的排序字段:

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其他地方的处理方式。