web-dev-qa-db-fra.com

Obtenir l'utilisateur actuel dans Model Serializer

Est-il possible d'obtenir l'utilisateur actuel dans un sérialiseur modèle? J'aimerais le faire sans avoir à m'éloigner des génériques, car c'est une tâche par ailleurs simple qui doit être effectuée.

Mon modele:

class Activity(models.Model):
    number = models.PositiveIntegerField(
        blank=True, null=True, help_text="Activity number. For record keeping only.")
    instructions = models.TextField()
    difficulty = models.ForeignKey(Difficulty)
    categories = models.ManyToManyField(Category)
    boosters = models.ManyToManyField(Booster)

    class Meta():
        verbose_name_plural = "Activities"

Mon sérialiseur:

class ActivitySerializer(serializers.ModelSerializer):

    class Meta:
        model = Activity

Et mon point de vue:

class ActivityDetail(generics.RetrieveUpdateDestroyAPIView):

    queryset = Activity.objects.all()
    serializer_class = ActivityDetailSerializer

Comment puis-je obtenir le modèle retourné, avec un champ supplémentaire user tel que ma réponse ressemble à ceci:

{
    "id": 1, 
    "difficulty": 1, 
    "categories": [
        1
    ], 
    "boosters": [
        1
    ],
    "current_user": 1 //Current authenticated user here
}
32
Jamie Counsell

J'ai trouvé la réponse en parcourant le code source DRF.

class ActivitySerializer(serializers.ModelSerializer):

    # Create a custom method field
    current_user = serializers.SerializerMethodField('_user')

    # Use this method for the custom field
    def _user(self, obj):
        request = getattr(self.context, 'request', None)
        if request:
            return request.user

    class Meta:
        model = Activity
        # Add our custom method to the fields of the serializer
        fields = ('id','current_user')

La clé est le fait que les méthodes définies dans un ModelSerializer ont accès à leur propre contexte, qui inclut toujours la requête (qui contient un utilisateur quand un est authentifié). Étant donné que mes autorisations ne concernent que les utilisateurs authentifiés, il devrait toujours y avoir quelque chose ici.

Cela peut également être fait dans d'autres sérialiseurs djangorestframework intégrés.

Comme l'a souligné Braden Holt, si votre user est toujours vide (c'est-à-dire _user renvoie None), il se peut que le sérialiseur n'ait pas été initialisé avec la requête dans le contexte. Pour résoudre ce problème, ajoutez simplement le contexte de la demande lors de l'initialisation du sérialiseur:

serializer = ActivitySerializer(
    data=request.data,
    context={
        'request': request
    }
)
44
Jamie Counsell

Un contexte est passé au sérialiseur dans REST, qui contient la requête par défaut. Vous pouvez donc simplement utiliser self.context['request'].user dans votre sérialiseur.

37
codwell