2016-07-19 214 views
6

ho API multipla che funziona storicamente utilizzando id come il campo di ricerca:lookup_fields multiple per Django quadro riposo

/api/organization/10 

Ho un frontend consumando quelle api.

Sto costruendo una nuova interfaccia e per qualche motivo, vorrei usare una lumaca invece un id:

/api/organization/my-orga 

L'API è costruito con Django Riposo Framework. Tranne il cambio del campo di ricerca, il comportamento delle API dovrebbe rimanere lo stesso.

Esiste una soluzione per consentire alla mia API di funzionare sia con uno slug sia con uno pk? Quei due percorso dovrebbe dare loro stessi risultati:

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

Ecco la mia definizione 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 

Grazie per il vostro aiuto.

+0

Questo potrebbe essere utile: http://www.django-rest-framework.org/api-guide/serializers/#how-hyperlinked-views-are-determined – jape

+0

Ciao Alex, sei riuscito a trovare una buona soluzione per questo? – Vinch

risposta

6

Prova questa

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) 

Poi in vista

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

Spero che questo aiuti.

+0

Penso che non risponda alla domanda in quanto l'URL deve contenere sia pk che l'altro campo in quel caso. – 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

Penso che la risposta fondamentale è che questo non sarebbe un buon design REST/API e proprio non è qualcosa DRF consentirebbe.