ViewSet, django-rest-Framework में एक विधि को अक्षम करें


124

ViewSets सूची बनाने, बनाने, अद्यतन करने, हटाने, हटाने, के लिए स्वचालित तरीके हैं ...

मैं उनमें से कुछ को अक्षम करना चाहूंगा, और जो समाधान मैं लेकर आया हूं वह शायद एक अच्छा नहीं है, क्योंकि OPTIONSअभी भी उन लोगों को अनुमति दी गई है।

यह कैसे सही तरीके से करने के लिए कोई विचार?

class SampleViewSet(viewsets.ModelViewSet):
    queryset = api_models.Sample.objects.all()
    serializer_class = api_serializers.SampleSerializer

    def list(self, request):
        return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)
    def create(self, request):
        return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)

जवाबों:


250

की परिभाषा ModelViewSetहै:

class ModelViewSet(mixins.CreateModelMixin, 
                   mixins.RetrieveModelMixin, 
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet)

इसलिए विस्तार करने के बजाय ModelViewSet, आपको जो कुछ भी चाहिए, उसका उपयोग क्यों नहीं करना चाहिए? उदाहरण के लिए:

from rest_framework import viewsets, mixins

class SampleViewSet(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    viewsets.GenericViewSet):
    ...

इस दृष्टिकोण के साथ, राउटर को केवल शामिल विधियों के लिए मार्ग उत्पन्न करना चाहिए।

संदर्भ :

ModelViewSet


@SunnySydeUp अभी यह कोशिश कर रहा है और ऐसा लगता है कि राउटर एक सूची दृश्य के लिए मार्ग उत्पन्न करता है, लेकिन यह 404 है क्योंकि व्यूसेट अनुरोध को संभालना नहीं जानता है। क्या आपसे यही उम्मीद थी?
स्टीव जालिम

3
केवल उन मिश्रणों का उपयोग करके जिनकी आपको आवश्यकता है वे GET, POST, PUT, DELETE मेथड्स को डिसेबल कर सकते हैं लेकिन मुझे यह पता लगाने में सक्षम नहीं था कि यदि आप राउटर्स का उपयोग कर रहे हैं तो विशेष रूप से PATCH मेथड को कैसे निष्क्रिय करें।
मुनीब अहमद

3
@MuneebAhmad PATCH विधि से सक्षम है UpdateModelMixin। यदि आप अपडेट का उपयोग करना चाहते हैं, लेकिन पैच नहीं, तो मैं वर्तमान में दो तरीकों के बारे में सोच सकता हूं। आप या तो दृश्य में अनुमत विधियों को ओवरराइड कर सकते हैं और "पैच" को हटा सकते हैं या आप partial_updateविधि और कॉल को ओवरराइड कर सकते हैं http_method_not_allowed(request, *args, **kwargs)। मैंने इसका परीक्षण नहीं किया है इसलिए मुझे यकीन नहीं है कि यह काम करता है
सनीसयदीप

1
@JulioMarins मैंने एक संदर्भ जोड़ा है। मुझे यकीन नहीं है कि यह वही है जो आप चाहते थे।
सनीसयदीप

1
यदि कोई केवल पढ़ने योग्य विचार बनाना चाहता है तो वे उपयोग कर सकते हैं class SampleViewSet(viewsets.ReadOnlyModelViewSet)
बिकाश खलार

133

आप अपने ViewSet का उपयोग करके उसे viewsets.ModelViewSetपरिभाषित कर सकते हैं http_method_names

उदाहरण

class SampleViewSet(viewsets.ModelViewSet):
    queryset = api_models.Sample.objects.all()
    serializer_class = api_serializers.SampleSerializer
    http_method_names = ['get', 'post', 'head']

एक बार जब आप जोड़ http_method_namesलेंगे, तो आप नहीं कर पाएंगे putऔर patchअब और नहीं।

यदि आप चाहते putहैं patch, लेकिन नहीं चाहते हैं , तो आप रख सकते हैंhttp_method_names = ['get', 'post', 'head', 'put']

आंतरिक रूप से, DRF व्यूज Django CBV से विस्तारित होते हैं। Django CBV में http_method_names नामक एक विशेषता है। तो आप DRF विचारों के साथ http_method_names का भी उपयोग कर सकते हैं।

[बेशर्म प्लग]: यदि यह उत्तर मददगार था, तो आप https://Fagiliq.com/blog/2019/04/drf-polls/ पर DRF की मेरी श्रृंखला पसंद करेंगे ।


16
इस तरह से समस्या या तो सूची को अक्षम करने या पुनर्प्राप्त करने का कोई तरीका नहीं है। दोनों को या न ही अक्षम करना है
फुआद

1
यह मेरे लिए काम नहीं करता है, मिल और सिर के बाद मैं अभी भी एक पोस्ट करने में सक्षम था
RunLoop

यह मेरे लिए django 1.9 पर काम करता है। महान समाधान। क्या कोई जोखिम उपयोगकर्ता एक अन्य तरीके से एक GET अनुरोध कर सकता है?
यॉन

काल्पनिक समाधान। पर काम करता है python3और Django 1.10बस ठीक है।
उरेडा

2
मैं इस दृष्टिकोण को पसंद करता हूं क्योंकि मैं PATCH को शामिल करने के लिए mixins.UpdateModelMixin
मिश्रणों

5

हालाँकि इस पोस्ट के लिए कुछ समय हो गया है, लेकिन मुझे अचानक पता चला कि वास्तव में यह उन फ़ंक्शन को अक्षम करने का एक तरीका है, आप इसे सीधे व्यूफ्रेम में संपादित कर सकते हैं।

स्रोत: https://www.django-rest-framework.org/api-guide/viewsets/#viewset-actions

from rest_framework import viewsets, status
from rest_framework.response import Response

class NameWhateverYouWantViewSet(viewsets.ModelViewSet):

    def create(self, request):
        response = {'message': 'Create function is not offered in this path.'}
        return Response(response, status=status.HTTP_403_FORBIDDEN)

    def update(self, request, pk=None):
        response = {'message': 'Update function is not offered in this path.'}
        return Response(response, status=status.HTTP_403_FORBIDDEN)

    def partial_update(self, request, pk=None):
        response = {'message': 'Update function is not offered in this path.'}
        return Response(response, status=status.HTTP_403_FORBIDDEN)

    def destroy(self, request, pk=None):
        response = {'message': 'Delete function is not offered in this path.'}
        return Response(response, status=status.HTTP_403_FORBIDDEN)

यह एक बेहतर तरीका होना चाहिए।
5

मुझे लगता है कि अगर यह संबंधित नहीं है तो HTTP_400_BAD_REQUEST यहां अधिक उपयुक्त होगा।
सैंटियागो मागियोनोस

4

यदि आप DRF व्यूसेट से PUT विधि को अक्षम करने का प्रयास कर रहे हैं, तो आप एक कस्टम राउटर बना सकते हैं:

from rest_framework.routers import DefaultRouter

class NoPutRouter(DefaultRouter):
    """
    Router class that disables the PUT method.
    """
    def get_method_map(self, viewset, method_map):

        bound_methods = super().get_method_map(viewset, method_map)

        if 'put' in bound_methods.keys():
            del bound_methods['put']

        return bound_methods

राउटर पर विधि को अक्षम करने से, आपका एपीआई स्कीमा प्रलेखन सही हो जाएगा।


चूंकि डीआरएफ के भीतर आंशिक पैच को सही ढंग से लागू नहीं किया गया है, इसलिए इसे यहां बताए गए तरीके से विश्व स्तर पर हटाने के लिए समझदारी होगी
ओडेन

1

DRF में ViewSet के लिए "DELETE" विधि को कैसे निष्क्रिय करें

class YourViewSet(viewsets.ModelViewSet):
    def _allowed_methods(self):
        return [m for m in super(YourViewSet, self)._allowed_methods() if m not in ['DELETE']]

PS यह सभी आवश्यक विधियों को स्पष्ट रूप से निर्दिष्ट करने की तुलना में अधिक विश्वसनीय है, इसलिए कुछ महत्वपूर्ण तरीकों को भूलने की संभावना कम है, विकल्प, HEAD, आदि।

डिफ़ॉल्ट डीआरएफ द्वारा पीपीएस http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']


आप superकक्षा स्तर पर कॉल नहीं कर सकते , कोई भी नहीं है self
वैध नाम

0

Django रेस्ट फ्रेमवर्क 3.xx में आप हर उस विधि को सक्षम कर सकते हैं, जिसे आप चाहते हैं कि आप ModelViewSetएक डिक्शनरी बनाकर एक डिक्शनरी बना सकें as_view। इस शब्दकोश में, कुंजी में अनुरोध प्रकार (GET, POST, DELETE, आदि) और मान होना चाहिए जिसमें विधि नाम (सूची, पुनः प्राप्त, अद्यतन, आदि) शामिल होना चाहिए। उदाहरण के लिए मान लें कि आप Sampleमॉडल बनाना या पढ़ना चाहते हैं, लेकिन आप इसे संशोधित नहीं करना चाहते हैं। तो इसका मतलब है कि आप चाहते हैं list, retrieveऔर createसक्षम होने के लिए विधि (और आप चाहते हैं कि अन्य विकलांग हों।)

आपको बस urlpatternsइन जैसे रास्तों को जोड़ना है :

path('sample/', SampleViewSet.as_view({
    'get': 'list',
    'post': 'create'
})),
path('sample/<pk>/', SampleViewSet.as_view({  # for get sample by id.
    'get': 'retrieve'
}))

जैसा कि आप देख सकते हैं कि ऊपर की रूटिंग सेटिंग्स में कोई deleteऔर putअनुरोध नहीं है , इसलिए उदाहरण के लिए यदि आप puturl को अनुरोध भेजते हैं , तो यह आपको 405 के लिए प्रतिक्रिया देता है Method Not Allowed:

{
    "detail": "Method \"PUT\" not allowed."
}

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.