2013-09-23 9 views
22

पर अधिक विचार जोड़ना अनिवार्य रूप से, मैं कस्टम राउटर के बिना राउटर को और अधिक दृश्य संलग्न करने का एक अच्छा तरीका खोजने का प्रयास कर रहा हूं। इसे पूरा करने का एक अच्छा तरीका क्या है?राउटर या व्यूसेट (Django-Rest-Framework)

यहां कुछ ऐसा है जो मैं पूरा करने की कोशिश कर रहा हूं। परिवर्तनीय नाम बदल दिए गए हैं और मैं जिस उदाहरण विधि को पेश करना चाहता हूं वह इस प्रश्न के लिए बेहद सरल है।

रूटर:

router = routers.SimpleRouter(trailing_slash=False) 
router.register(r'myobjects', MyObjectViewSet, base_name='myobjects') 
urlpatterns = router.urls 

ViewSet एक और तरीका प्रकार मैं शामिल करने की ज़रूरत की

class MyObjectsViewSet(viewsets.ViewSet): 
""" Provides API Methods to manage MyObjects. """ 

def list(self, request): 
    """ Returns a list of MyObjects. """ 
    data = get_list_of_myobjects() 
    return Response(data) 

def retrieve(self, request, pk): 
    """ Returns a single MyObject. """ 
    data = fetch_my_object(pk) 
    return Response(data) 

def destroy(self, request, pk): 
    """ Deletes a single MyObject. """ 
    fetch_my_object_and_delete(pk) 
      return Response() 

एक उदाहरण। (इनमें से कई हैं):

def get_locations(self, request): 
    """ Returns a list of location objects somehow related to MyObject """ 
    locations = calculate_something() 
    return Response(locations) 

अंत परिणाम यह है कि निम्नलिखित यूआरएल सही तरीके से काम करेगा और इसे 'साफ' लागू किया जाएगा।

GET example.com/myobjects/123/locations 

उत्तर

23

ऊपर answer given by mariodev सही है, जब तक आप केवल GET अनुरोध करने के लिए देख रहे हैं। /myobjects/123/update_location/

: आप POST एक यूआरएल के लिए की तरह स्वरूपित हैं

from rest_framework.decorators import action, link 
from rest_framework.response import Response 

class MyObjectsViewSet(viewsets.ViewSet): 

    # For GET Requests 
    @link() 
    def get_locations(self, request): 
     """ Returns a list of location objects somehow related to MyObject """ 
     locations = calculate_something() 
     return Response(locations) 

    # For POST Requests 
    @action() 
    def update_location(self, request, pk): 
     """ Updates the object identified by the pk """ 
     location = self.get_object() 
     location.field = update_location_field() # your custom code 
     location.save() 

     # ...create a serializer and return with updated data... 

तब:

आप एक समारोह आप एक ViewSet को जोड़ रहे हैं करने के लिए POST करना चाहते हैं, तो आप action डेकोरेटर उपयोग करने की आवश्यकता

http://www.django-rest-framework.org/api-guide/viewsets/#marking-extra-actions-for-routing यदि आप रुचि रखते हैं तो अधिक जानकारी है!

+1

मैं एक कस्टम विधि में एक फ़ाइल अपलोड करने की कोशिश कर रहा हूँ। क्या आप जानते हैं कि मैं इसे कैसे प्राप्त कर सकता हूं? – psychok7

+7

'@ action' बहिष्कृत है - लिंक' @ detail_route' सजावटकर्ता के तर्क के रूप में विधियों को सुझाता है। – rtindru

8

आप विधि को परिभाषित की तरह तुम अब क्या, लेकिन इतना के लिए

/myobjects/123/locations/ 

आप इस

@link(permission_classes=[...]) 
def locations(self, request, pk=None): 
    ... 
की तरह विधि जोड़ने आप, विधि नाम के समान यूआरएल का उपयोग करें और लिंक डेकोरेटर जोड़ने की जरूरत

और राउटर स्वचालित रूप से इसे ले जाएगा।

+1

त्वरित और बहुत ही सटीक जवाब। केवल एक चीज जो मैं जोड़ूंगा वह है "rest_framework.decorators आयात लिंक से"। धन्यवाद! – Kurtis

+0

यदि संभव हो, तो क्या आप (या कोई भी) मुझे राउटर में एक विधि जोड़ने का एक उदाहरण दिखा सकते हैं जो मेरे व्यूसेट में 'निहित' नहीं है? – Kurtis

3

Routing to extra methods on a ViewSet से:

मैं तुम्हें विधि हाथ से है, यानी पुराने तरीके से रूट करने के लिए आवश्यकता हो सकती है लगता है ™।

पहले एक अलग दृश्य के रूप में विधि बाहर खींच:

set_password_view = UserViewSet.as_view({'post': 'set_password'}) 

(या इस तरह के)

फिर अपने URL आवंटित:

url(r'^users/username_available/$', set_password_view, name-=...) 

(या इस तरह के)

एक related question on SO है।

14

अब आप list_route और detail_route सज्जाकार के साथ ऐसा कर सकते हैं: http://www.django-rest-framework.org/api-guide/viewsets/#marking-extra-actions-for-routing

उदाहरण के लिए:

from rest_framework.decorators import list_route 
from rest_framework.response import Response 
... 

class MyObjectsViewSet(viewsets.ViewSet): 
    ... 

    @list_route() 
    def locations(self, request): 
     queryset = get_locations() 
     serializer = LocationSerializer(queryset, many=True) 
     return Response(serializer.data) 
+0

हाय मैं django के लिए नया हूँ, इसके लिए अंत बिंदु क्या होगा? धन्यवाद! –

+0

@ ShiftN'Tab यदि आपके पास 'myobjects-list' और' myobjects-detail 'है, तो यह' myobjects-locations 'होगा। – cezar

संबंधित मुद्दे