2016-07-19 6 views
6

Ich habe mehrere API, die historisch unter Verwendung von Feld id als Nachschlag arbeiten:Mehrere lookup_fields für django Rest Rahmen

/api/organization/10 

Ich habe ein Frontend jene api raubend.

Ich baue eine neue Schnittstelle und aus irgendwelchen Gründen, würde Ich mag eine Schnecke anstelle einer ID verwenden:

/api/organization/my-orga 

Die API ist mit Django Ruhe Framework integriert. Außer der Änderung des Nachschlagefeldes sollte das api-Verhalten gleich bleiben.

Gibt es eine Lösung, damit meine API sowohl mit slug als auch mit pk arbeiten kann? Die beiden Pfad sollten sie dieselben Ergebnisse geben:

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

Hier ist meine API-Definition:

# 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 

Vielen Dank für Ihre Hilfe.

+0

Dies könnte von Vorteil sein: http://www.django-rest-framework.org/api-guide/serializers/#how-hyperlinked-views-are-determined – jape

+0

Hallo Alex, hast du eine gute Lösung gefunden? dafür? – Vinch

Antwort

6

dieses in Aussicht

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) 

dann versuchen

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

Hoffnung, das hilft.

+0

Ich denke, es beantwortet die Frage nicht, da die URL in diesem Fall sowohl pk als auch das andere Feld enthalten muss. – 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

Ich denke, die grundlegende Antwort ist, dass dies nicht gut REST/API-Design wäre und ist einfach nicht etwas DRF ermöglichen würde.