ViewSet, django-rest-framework'te bir yöntemi devre dışı bırakın


125

ViewSets listelemek, almak, oluşturmak, güncellemek, silmek için otomatik yöntemler var ...

Bunlardan bazılarını devre dışı bırakmak istiyorum ve bulduğum çözüm muhtemelen iyi bir çözüm değil, çünkü OPTIONShala izin verilenleri belirtiyor.

Bunu doğru şekilde nasıl yapacağınıza dair bir fikriniz var mı?

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)

Yanıtlar:


250

Tanımı ModelViewSetşudur:

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

Öyleyse ModelViewSet, genişletmek yerine , neden ihtiyacınız olanı kullanmayasınız? Yani mesela:

from rest_framework import viewsets, mixins

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

Bu yaklaşımla, yönlendirici yalnızca dahil edilen yöntemler için yollar oluşturmalıdır.

Referans :

ModelViewSet


@SunnySydeUp Bunu şimdi deniyor ve yönlendirici bir liste görünümü için rota oluşturuyor gibi görünüyor, ancak bu 404s çünkü ViewSet isteği nasıl ele alacağını bilmiyor. Beklediğin bu muydu?
Steve Jalim

3
Yalnızca ihtiyacınız olan karışımları kullanarak GET, POST, PUT, DELETE Yöntemlerini devre dışı bırakabilirsiniz, ancak yönlendiriciler kullanıyorsanız PATCH yöntemini özel olarak nasıl devre dışı bırakacağımı bulamadım.
Muneeb Ahmad

3
@MuneebAhmad PATCH yöntemi UpdateModelMixin,. Güncellemeyi kullanmak istiyor ancak yamayı kullanmıyorsanız, şu anda iki yol düşünebilirim. Görünümde izin verilen yöntemleri geçersiz kılabilir ve "yamayı" kaldırabilir veya partial_updateyöntemi ve çağrıyı geçersiz kılabilirsiniz http_method_not_allowed(request, *args, **kwargs). Bunu test etmedim, bu yüzden çalışıp çalışmadığından emin değilim
SunnySydeUp

1
@JulioMarins Bir referans ekledim. Yine de istediğin bu muydu emin değilim.
SunnySydeUp

1
Birisi salt okunur görünüm kümesi yapmak isterse, kullanabilir class SampleViewSet(viewsets.ReadOnlyModelViewSet).
Bikash kharel

133

ViewSet'inizi kullanmaya viewsets.ModelViewSetve tanımlamaya http_method_namesdevam edebilirsiniz.

Misal

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

Eğer ekledikten sonra http_method_names, yapmanız mümkün olmayacaktır putve patchartık.

Eğer istiyorsan putama istemiyorsan patch, tutabilirsinhttp_method_names = ['get', 'post', 'head', 'put']

DRF Görünümleri dahili olarak Django CBV'den uzanır. Django CBV, http_method_names adlı bir niteliğe sahiptir. Dolayısıyla, http_method_names'i DRF görünümleriyle de kullanabilirsiniz.

[Utanmaz Eklenti]: Bu cevap yardımcı olduysa, https://www.agiliq.com/blog/2019/04/drf-polls/ adresindeki DRF'deki yazı dizimi beğeneceksiniz .


16
Bu yolla ilgili sorun, listeyi devre dışı bırakmanın veya geri almanın bir yolu değildir. İkisini birden devre dışı bırakmak zorunda
Fuad

1
Bu benim için işe yaramadı,
başla

Bu benim için django 1.9'da çalışıyor. Harika çözüm. Kullanıcıların GET talebini başka bir şekilde yapma riski var mı?
Ycon

FANTASTİK çözüm. Çalışıyor python3ve Django 1.10gayet iyi.
Urda

2
Onların bir uygulama hem çünkü PUT PATCH'i içerecek şekilde Mixins mirasını değiştirmek değil, olamazdı çünkü bu yaklaşım tercih mixins.UpdateModelMixin
ThatsAMorais

5

Bu gönderi için biraz zaman geçmesine rağmen, aniden onların bu işlevi devre dışı bırakmanın bir yolu olduğunu öğrendim, doğrudan views.py içinde düzenleyebilirsiniz.

Kaynak: 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)

Bu, tercih edilen bir yol olmalıdır.
58'de digitake

Doğrulama ile ilgili değilse HTTP_400_BAD_REQUEST'in burada daha uygun olacağını düşünüyorum.
Santiago Magariños

4

DRF görünüm kümesinden PUT yöntemini devre dışı bırakmaya çalışıyorsanız, özel bir yönlendirici oluşturabilirsiniz:

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

Yönlendiricide yöntemi devre dışı bıraktığınızda, api şema belgeleriniz doğru olacaktır.


Kısmi yama DRF içinde doğru bir şekilde uygulanmadığından, onu burada açıklanan şekilde global olarak kaldırmak akıllıca olacaktır
oden

1

DRF'de ViewSet için "DELETE" yöntemi nasıl devre dışı bırakılır

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

Not: Bu, gerekli tüm yöntemleri açıkça belirtmekten daha güvenilirdir, bu nedenle SEÇENEKLER, BAŞLIK vb. Bazı önemli yöntemleri unutmak için daha az şans vardır.

Varsayılan olarak PPS DRF'de http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']


Sen diyemezsin supersınıf düzeyinde, hiçbir var self.
validname

0

Django Rest Framework 3.xx'de ModelViewSet, bir sözlüğü as_viewyönteme aktararak, etkinleştirilmesini istediğiniz her yöntemi etkinleştirebilirsiniz . Bu sözlükte, anahtar istek türünü (GET, POST, DELETE, vb.) İçermeli ve değer, karşılık gelen yöntem adını (liste, alma, güncelleme, vb.) İçermelidir. Örneğin, Samplemodelin oluşturulmasını veya okunmasını istediğinizi ancak değiştirilmesini istemediğinizi varsayalım. Eğer istediğiniz anlamına Yani list, retrieveve createyöntem etkinleştirmek olmak (ve engelli olmak başkalarına istiyorum.)

Tek yapmanız gereken, bunları urlpatternsbeğenmek için yollar eklemektir :

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

Gördüğünüz gibi yukarıdaki yönlendirme ayarlarında hiç deleteve putistek yok , bu nedenle örneğin puturl'ye bir istek gönderirseniz , size 405 ile yanıt verir Method Not Allowed:

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.