sergey_1990
@sergey_1990
1

Как изменить метод при redirect() если метод PUT?

Коллеги кто сталкивался с необходимостью редиректа при работе с DRF! после def update(self,..) редирект идёт с методом PUT, ранее не было необходимости применить редирект при DRF, сейчас столкнулся с этим вопросом и тупик!
class PersonalBalanceViewSet(viewsets.ViewSet):
    # permission_classes = [permissions.IsAuthenticated]

    def retrieve(self, request, pk=None):
        instance = PersonalBalance.objects.filter(user_id=self.request.user.id).get()
        serialized_data = PersonalBalanceSerializer(instance).data
        used_workspaces = PersonalWorkspace.objects.filter(owner_id=request.user.id).count()
        used_projects = PersonalProject.objects.filter(workspace__owner_id=request.user.id).count()
        serialized_data['used_workspaces'] = used_workspaces
        serialized_data['used_projects'] = used_projects
        return Response(serialized_data)
    
    def update(self, request, pk=None):
        personel_balans_to_edit = PersonalBalance.objects.filter(user_id=self.request.user.id).get()
        plan = Plan.objects.filter(type=request.data.get('tarif')).get() 
        next_plan_prolongation_date=datetime.date.today() + datetime.timedelta(days=31),
        if personel_balans_to_edit is None:
            raise NotFound("Couldn't find an instance with specified id")
        
        ser = PersonalBalanceSerializer(personel_balans_to_edit, data={'plan_pk':plan.pk,
                                                                       'next_plan_prolongation_date':datetime.date.today()},
                                                                       partial=True)
        ser.is_valid(raise_exception=True)
        personel_balans = ser.save()
        transaction = PersonalBalanceTransaction(
            personal_balance=personel_balans_to_edit,
            cause = 'BUY',
            workspaces_additional = 0,
            projects_additional = 0,
            credits = plan.initial_bonus_credits + plan.credits_per_month,
            antiplagiarism_checks = plan.anti_plagiarism_checks,
        ).save()
        
        return HttpResponseRedirect(redirect_to='/workspaces')
        # return Response(PersonalBalanceSerializer(personel_balans).data)
на выходе

URL запроса: localhost:1337/workspaces
Метод запроса: PUT ----- КАК СЮДА GET ДАТЬ ????
Код статуса: 405 Not Allowed
Удаленный адрес: [::1]:1337
Правило для URL перехода: same-origin
  • Вопрос задан
  • 134 просмотра
Пригласить эксперта
Ответы на вопрос 1
@breaden
Дефолтное поведение предполагает (rfc7231) следующее:

Если POST запрос возвращается с кодом 301, в таком случае follow_redirect приведет к GET запросу нового адреса.
В случае curl, это происходит автоматически, при наличии флага -L и пейлоада (без явного указания типа запроса) (аналогично allow_redirect=True в requests)

В данном примере, есть вьюха POST /test возвращающая HttpResponsePermanentRedirect (с кодом 301), с редиректом на /test2.
curl 'http://127.0.0.1:8000/test' -v -L -d '{}'
*   Trying 127.0.0.1:8000...
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
> POST /test HTTP/1.1
> Host: 127.0.0.1:8000
> User-Agent: curl/7.79.1
> Accept: */*
> Content-Length: 2
> Content-Type: application/x-www-form-urlencoded
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Date: Mon, 01 May 2023 14:10:33 GMT
< Server: WSGIServer/0.2 CPython/3.9.6
< Content-Type: text/html; charset=utf-8
< Location: test2
< Vary: Accept, Cookie
< Allow: OPTIONS, POST
< X-Frame-Options: DENY
< Content-Length: 0
< X-Content-Type-Options: nosniff
< Referrer-Policy: same-origin
< Cross-Origin-Opener-Policy: same-origin
<
* Connection #0 to host 127.0.0.1 left intact
* Issue another request to this URL: 'http://127.0.0.1:8000/test2'
* Switch from POST to GET
* Found bundle for host 127.0.0.1: 0x600003424030 [serially]
* Can not multiplex, even if we wanted to!
* Re-using existing connection! (#0) with host 127.0.0.1
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
> GET /test2 HTTP/1.1
> Host: 127.0.0.1:8000
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Mon, 01 May 2023 14:10:33 GMT
< Server: WSGIServer/0.2 CPython/3.9.6
< Content-Type: application/json
< Vary: Accept, Cookie
< Allow: OPTIONS, GET
< X-Frame-Options: DENY
< Content-Length: 22
< X-Content-Type-Options: nosniff
< Referrer-Policy: same-origin
< Cross-Origin-Opener-Policy: same-origin
<
* Connection #0 to host 127.0.0.1 left intact
{"redirect":"success"}


По хорошему, тип запроса при редиректе меняться не должен. То есть, PUT не должен резко менять своё поведение на GET в случае редиректа.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы