Как установить cookie в наборе представлений DRF?
Хотелось бы узнать, как установить cookie на Django rest framework ViewSet/ModelViewSet.
Я читал некоторые посты в SO, где говорится, что можно использовать Response({serializer.data})
, но в retrieve это может быть нормально, но для create(), как в следующем случае, не влияет ли Response() на его последующую обработку?
На самом деле, когда я использовал HttpResponse() как HttpResponse(status=401, reason="you cannot post anymore.")
, заменив строку raise PermissionDenied()
на нижеприведенную, я получил 500 ошибку (ошибка говорит AttributeError: 'collections.OrderedDict' object has no attribute 'pk'
или типа того), но не указанный 401 код.
По сути, следующее объясняет, что я хочу сделать, то есть отказывает, когда количество сообщений пользователя >= 4, но в противном случае продолжает выполнять perform_create() и следующий DRF скрипт, с прикреплением куки, который сообщает браузеру "у вас осталось n слотов для сообщений".
class PostViewSet(viewsets.ModelViewSet):
..
def perform_create(self, serializer):
role = self.request.user.userproperty.role
if role == "guest":
post_count = self.request.user.posts.count()
if post_count >= 4:
raise PermissionDenied({"message": "you cannot post anymore."})
else:
response = // anyhow gets response here //
response.set_cookie("notify", "your post slot is " + str(3 - post_count) + "left now.")
serializer.save(user=self.request.user)
Но я не знаю, как я могу получить response
от чего-то, или вызвать Response()
без ущерба для последствий скрипта.
Я пытался, но ничего не получилось (как я и ожидал):
self.request.COOKIES["new_cookie"] = "test."
self.response
Любая идея будет очень признательна. Спасибо.
Похоже, я недостаточно исследовал проблему. Я нашел решение:
def create(self, request, *args, **kwargs):
response = super().create(request, args, kwargs)
// whatever
response.set_cookie("_hoge", "hogee.")
return response
Дело в том, что perform_create() не имеет дела с Response(), а create() имеет; поскольку create() вызывает perform_create(), не было никакой проблемы перенести блок в create().