【问题标题】:Show Filters and Ordering in Django Rest Framework Options Request在 Django Rest Framework 选项请求中显示过滤器和排序
【发布时间】:2013-02-13 12:42:44
【问题描述】:

我正在使用 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."
} 

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

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

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

    请看这里: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/

    【讨论】:

    • 您能否更好地解释一下如何在视图上覆盖 .metadata()?此链接指向“第 340 行”,但我不知道您指的是什么方法。
    【解决方案2】:

    你完全可以做到这一点。这是custom metadata class,我一直在 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 中其他地方的处理方式。

    【讨论】:

      猜你喜欢
      • 2014-10-03
      • 2017-01-23
      • 2014-06-06
      • 2016-03-31
      • 2013-05-21
      • 2016-02-15
      • 1970-01-01
      • 1970-01-01
      • 2018-02-02
      相关资源
      最近更新 更多