J'ai essayé quelque chose comme ça, ça ne marche pas.
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
def save(self):
user = self.context['request.user']
title = self.validated_data['title']
article = self.validated_data['article']
J'ai besoin d'un moyen de pouvoir accéder à request.user à partir de ma classe de sérialiseur.
Vous ne pouvez pas accéder au request.user
directement. Vous devez accéder à l'objet de requête, puis récupérer l'attribut utilisateur.
Comme ça:
user = self.context['request'].user
Ou pour être plus en sécurité,
user = None
request = self.context.get("request")
if request and hasattr(request, "user"):
user = request.user
En fait, vous n'avez pas à vous soucier du contexte. Il y a une bien meilleure façon de le faire:
from rest_framework.fields import CurrentUserDefault
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
def save(self):
user = CurrentUserDefault() # <= magic!
title = self.validated_data['title']
article = self.validated_data['article']
Comme Igor l'a mentionné dans une autre réponse, l'utilisation peut utiliser CurrentUserDefault. Si vous ne voulez pas remplacer la méthode save uniquement pour cela, utilisez doc :
from rest_framework import serializers
class PostSerializer(serializers.ModelSerializer):
user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())
class Meta:
model = Post
Vous avez besoin d'une petite édition dans votre sérialiseur:
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
def save(self):
user = self.context['request'].user
title = self.validated_data['title']
article = self.validated_data['article']
Voici un exemple d'utilisation de modèles de vues de mélange de modèles. Dans la méthode create
, vous pouvez trouver le bon moyen d'appeler le sérialiseur. La méthode get_serializer remplit correctement le dictionnaire de contexte. Si vous devez utiliser un autre sérialiseur défini dans le jeu de vues, reportez-vous à la méthode update
pour savoir comment initialiser le sérialiseur avec le dictionnaire de contexte, qui transmet également l'objet de la demande au sérialiseur.
class SignupViewSet(mixins.UpdateModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet):
http_method_names = ["put", "post"]
serializer_class = PostSerializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
instance = self.get_object()
kwargs['context'] = self.get_serializer_context()
serializer = PostSerializer(instance, data=request.data, partial=partial, **kwargs)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
return Response(serializer.data)