PUT и запрос на удаление в среде отдыха Django

Я новичок в Django, мне было интересно, как кодировать запрос PUT и метод Delete в моем проекте Django REST API.

Я пытался следовать многим учебникам, но ни один из них не работал с моим кодом.

Код, который я пробовал, выглядит так

def put(self, request, pk):
        snippet = self.get_object(pk)
        serializer = UserSerializers(snippet, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk):
    snippet = self.get_object(pk)
    snippet.delete()
    return Response(status=status.HTTP_204_NO_CONTENT)

Но метод получения сообщения не разрешен

Ниже приведены мои Models.py

from django.db import models


class Users(models.Model):
    user_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=50)
    profile_name = models.CharField(max_length=30)
    profile_picture = models.CharField(max_length=1000)
    phone = models.CharField(max_length=15)
    email = models.EmailField()
    password = models.CharField(max_length=25, default='')

    def __str__(self):
        return self.name

Ниже приведены мои сериализаторы.py

from rest_framework import serializers
from .models import Users
from .models import UserPost


class UserSerializers(serializers.ModelSerializer):
    class Meta:
        model = Users
        fields = '__all__'


class UserDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = Users
        fields = '__all__'


class UserPostSerializers(serializers.ModelSerializer):
    class Meta:
        model = UserPost
        fields = '__all__'

Следующий код содержит мой Views.py

from django.http import Http404
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
from .models import Users
from .models import UserPost
from .serializers import UserSerializers, UserPostSerializers


class UsersList(APIView):

    def get(self, request):
        User_details = Users.objects.all()
        serializer = UserSerializers(User_details, many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = UserSerializers(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class UserDetail(APIView):
    def get_object(self, pk):
        try:
            return Users.objects.get(pk=pk)
        except Users.DoesNotExist:
            raise Http404

    def get(self, request, pk):
        snippet = self.get_object(pk)
        serializer = UserSerializers(snippet)
        return Response(serializer.data)

    class UserViewSet(viewsets.ModelViewSet):
        queryset = Users.objects.all()
        serializer_class = UserSerializer

        @action(methods=['put'], detail=False)
        def filter_by_something(self, request):
            something = request.data.get('that_something')
            queryset = Users.objects.filter(something__exact=something)
            return Response(self.get_serializer(queryset, many=True).data)

Следующий код содержит urls.py

from sys import path

from django.urls import include
from rest_framework.urlpatterns import format_suffix_patterns
from app import views
from django.conf.urls import url
from django.contrib import admin

from rest_framework import routers
router = routers.DefaultRouter()



router.register('user_details', UserDetailViewSet)
urlpatterns = [path('api/', include(router.urls)), ...]
urlpatterns = [

    url(r'^admin/', admin.site.urls),
    url(r'^User_details/', views.UsersList.as_view()),
    url(r'^User_details/(?P<pk>[0-9]+)/', views.UserDetail.as_view()),
    url(r'^userpost_details/', views.UsersPostList.as_view()),

]
urlpatterns = format_suffix_patterns(urlpatterns)

В какое представление вы добавили PUT/DELETE? Какой URL-адрес вы выполнили PUT/DELETE для ?

Linovia 20.02.2019 17:24

@Linovia Views.py в папке приложения, URL-адрес 127.0.0.1:8000/детали_пользователя

appslet inv 21.02.2019 06:45

Ваш PUT/DELETE, скорее всего, будет работать с конкретным ресурсом, а не со списком ресурсов, поэтому вы получаете ошибку

Linovia 21.02.2019 07:56
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
11 806
2

Ответы 2

В urls.py вы должны объявить объект маршрутизатора, который сопоставляет ваши ViewSets с DRF:

from rest_framework import routers
router = routers.DefaultRouter()
router.register('user_details', UserDetailViewSet)
urlpatterns = [path('api/', include(router.urls)), ...]

UserDetailViewSet должен быть объявлен в api\views.py (api — это каталог для приложения DRF)

from rest_framework.decorators import action
from rest_framework import viewsets
from rest_framework.response import Response

class UserDetailViewSet(viewsets.ModelViewSet):
    queryset = UserDetail.objects.all()
    serializer_class = UserDetailSerializer

    @action(methods=['put'], detail=False)
    def filter_by_something(self, request):
        something = request.data.get('that_something')
        queryset = UserDetail.objects.filter(something__exact=something)
        return Response(self.get_serializer(queryset, many=True).data)

Затем вы будете делать запросы PUT на http:\\your_website\api\user_details\filter_by_something

Попробуйте что-нибудь вроде этого. Он должен работать!

Я добавил код в URLs.py(папка проекта) и views.py(папка приложения), и мне пришлось создать новый класс сериализатора в serializers.py(папка приложения), его код выглядит так class UserDetailSerializer(serializers.ModelSerializer): class Meta: model = Users fields = '__all__' Теперь, где и как я должен размещать объявление и УДАЛИТЬ код запроса в коде?

appslet inv 21.02.2019 06:42

а у меня ошибка in UserDetailViewSet queryset = UserDetail.objects.all() AttributeError: type object 'UserDetail' has no attribute 'objects'

appslet inv 21.02.2019 08:59

UserDetail — это модель, объявленная в вашем приложении: class UserDetail(models.Model): ..... Вы импортируете его в api\views.py следующим образом: from your_app.models import UserDetail. В вашем случае, я думаю, это не UserDetail, это просто Users

Tavy 21.02.2019 10:01

Я отредактировал вопрос и код, как вы сказали, но получаю сообщение об ошибке в классе UserDetail UserViewSet (viewsets.ModelViewSet): NameError: имя «viewsets» не определено. Можете ли вы проверить этот отредактированный код в моем вопросе?

appslet inv 22.02.2019 06:59

просто вставьте: from rest_framework import viewsets

Tavy 22.02.2019 17:32

Определите методы put и delete в классе UsersDetail.

class UsersDetail(APIView):
 def put(self, request, pk):
   // code

 def delete(self, request, pk):
   //code

Если вышеперечисленное не работает, также добавьте http_method_names

class UsersDetail(APIView):
 http_method_names = ['GET', 'PUT', 'DELETE']

класс APIView наследуется от класса View, определенного в базовом файле Django. dispatch метод проверит http_method_names допустимый метод. PUT и DELETE перечислены как допустимые методы наряду с другими.

Ссылка: django/views/generic/base.py

  class View(object):
    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)

    def http_method_not_allowed(self, request, *args, **kwargs):
        logger.warning('Method Not Allowed (%s): %s', request.method, request.path,
            extra = {
                'status_code': 405,
                'request': request
            }
        )
        return http.HttpResponseNotAllowed(self._allowed_methods())

Другие вопросы по теме