2016-07-19 316 views
6

多lookup_fields我有多個API,這在歷史上使用id作爲查找領域的工作:Django的REST框架

/api/organization/10 

我有一個前端消耗的API。

我建立一個新的界面,因爲某些原因,我想用一塞,而不是一個id:

/api/organization/my-orga 

的API與Django的REST框架構建。除了查找字段的變化之外,api行爲應該保持不變。

有沒有解決方案可以讓我的API與slugpk一起工作?這兩個路徑應該給他們同樣的結果:

/api/organization/10 
/api/organization/my-orga 

這裏是我的API定義:

# urls.py 
router = DefaultRouter() 
router.register(r'organization', Organization) 
urlpatterns = router.urls 

#view.py 
class Organization(viewsets.ModelViewSet): 
    queryset = OrganisationGroup.objects.all() 
    serializer_class = OrganizationSerializer 

# serializer.py 
class OrganizationSerializer(PermissionsSerializer): 
    class Meta: 
     model = Organization 

感謝您的幫助。

+0

這可能是有益的:http://www.django-rest-framework.org/api-guide/serializers/#how-hyperlinked-views-are-determined – jape

+0

嗨,亞歷克斯,你能找到一個很好的解決方案爲了這? – Vinch

回答

6

試試這個

from django.db.models import Q 
import operator 
class MultipleFieldLookupMixin(object): 
    def get_object(self): 
     queryset = self.get_queryset()    # Get the base queryset 
     queryset = self.filter_queryset(queryset) # Apply any filter backends 
     filter = {} 
     for field in self.lookup_fields: 
      filter[field] = self.kwargs[field] 
     q = reduce(operator.or_, (Q(x) for x in filter.items())) 
     return get_object_or_404(queryset, q) 

然後在視圖

class Organization(MultipleFieldLookupMixin, viewsets.ModelViewSet): 
    queryset = OrganisationGroup.objects.all() 
    serializer_class = OrganizationSerializer 
    lookup_fields = ('pk', 'another field') 

希望這有助於。

+0

我認爲它不回答這個問題,因爲在這種情況下,URL必須包含pk和其他字段。 – Vinch

0

class MultipleFieldLookupMixin(object): 
 
    """ 
 
    Apply this mixin to any view or viewset to get multiple field filtering 
 
    based on a `lookup_fields` attribute, instead of the default single field filtering. 
 
    """ 
 

 
    def get_object(self): 
 
     queryset = self.get_queryset() # Get the base queryset 
 
     queryset = self.filter_queryset(queryset) 
 
     filter = {} 
 
     for field in self.lookup_fields: 
 
      if self.kwargs[field]: # Ignore empty fields. 
 
       filter[field] = self.kwargs[field] 
 
     return get_object_or_404(queryset, **filter) # Lookup the object 
 

 

 
class RetrieveUserView(MultipleFieldLookupMixin, generics.RetrieveAPIView): 
 
    queryset = User.objects.all() 
 
    serializer_class = UserSerializer 
 
    lookup_fields = ('account', 'username')

0

我認爲根本的答案是,這不會是很好的休息/ API的設計,只是是不是DRF將使。