2016-07-19 21 views
6

Mam kilka API, które historycznie pracować używając id w polu wyszukiwania:Wiele lookup_fields dla django ramach odpoczynku

/api/organization/10 

Mam frontend spożywania tych API.

Buduję nowy interfejs i jakichś powodów, chciałbym użyć pocisk zamiast id:

/api/organization/my-orga 

API zbudowany jest z Django Rest Framework. Oprócz zmiany pola odnośnika zachowanie api powinno pozostać niezmienione.

Czy istnieje rozwiązanie pozwalające interfejsowi API współpracować zarówno z slug, jak i pk? Tych dwóch ścieżka powinna dać im takie same wyniki:

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

Oto moja definicja 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 

Dzięki za pomoc.

+0

To może być korzystne: http://www.django-rest-framework.org/api-guide/serializers/#how-hyperlinked-views-are-etetined – jape

+0

Witaj Alex, czy byłeś w stanie znaleźć dobre rozwiązanie dla tego? – Vinch

Odpowiedz

6

Spróbuj

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) 

Następnie w widoku

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

nadzieję, że to pomaga.

+0

Myślę, że nie odpowiada na pytanie, ponieważ adres URL musi zawierać zarówno pk, jak i inne pole w tym przypadku. – 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

Myślę, że podstawową odpowiedzią jest, że to nie byłby dobry projekt REST/API i po prostu nie jest coś DRF umożliwiłoby.