2013-02-27 75 views
6

我正在使用Django Rest框架我在API的Web瀏覽部分注意到有一個名爲'options'的按鈕,點擊時顯示以下內容...在Django Rest框架選項中顯示過濾器和排序請求

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

我的問題是,有無論如何我可以列出所有的過濾器選項這個網址的其他東西?

回答

6

通過覆蓋視圖上的.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/

+0

你可以更好地解釋我怎麼能覆蓋.metadata()視圖?這個鏈接指向'340行',但我不知道你指的是什麼方法。 – ePascoal 2015-07-15 16:29:30

+1

看到我上面的更新。 – 2015-07-16 10:25:11

0

你完全可以做到這一點。這裏有一個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中其他地方處理的方式。

相關問題