J'ai un cas où les valeurs d'un champ de sérialiseur dépendent de l'identité de l'utilisateur actuellement connecté. J'ai vu comment ajouter l'utilisateur au contexte lors de l'initialisation d'un sérialiseur, mais je ne suis pas sûr de savoir comment procéder lors de l'utilisation d'un ViewSet, car vous ne fournissez que la classe de sérialiseur et non l'instance de sérialiseur.
En gros, j'aimerais savoir comment aller de:
class myModelViewSet(ModelViewSet):
queryset = myModel.objects.all()
permission_classes = [DjangoModelPermissions]
serializer_class = myModelSerializer
à:
class myModelSerializer(serializers.ModelSerializer):
uploaded_by = serializers.SerializerMethodField()
special_field = serializers.SerializerMethodField()
class Meta:
model = myModel
def get_special_field(self, obj):
if self.context['request'].user.has_perm('something.add_something'):
return something
Désolé si ce n'était pas clair, d'après les DOC: Ajout d'un contexte supplémentaire Ce qui dit de faire
serializer = AccountSerializer(account, context={'request': request})
serializer.data
Mais je ne suis pas sûr de savoir comment le faire automatiquement à partir de la vue, car je ne peux que changer de classe de sérialiseur, et pas l'instance de sérialiseur elle-même.
GenericViewSet
a la méthode get_serializer_context
que vous pouvez remplacer:
class myModelViewSet(ModelViewSet):
queryset = myModel.objects.all()
permission_classes = [DjangoModelPermissions]
serializer_class = myModelSerializer
def get_serializer_context(self):
return {'request': self.request}
Renvoyer le contexte parent dans la fonction remplacée get_serializer_context
facilitera l'accès à la demande et à ses données.
class myModelViewSet(ModelViewSet):
queryset = myModel.objects.all()
permission_classes = [DjangoModelPermissions]
serializer_class = myModelSerializer
def get_serializer_context(self):
"""
pass request attribute to serializer
"""
context = super(myModelViewSet, self).get_serializer_context()
return context
C'est très stable, car chaque fois que nous demandons un groupe de vues, cela retourne également le contexte.
utilisez simplement get_serializer () dans vos ensembles de vues
def get_serializer(self, *args, **kwargs):
"""
Return the serializer instance that should be used for validating and
deserializing input, and for serializing output.
"""
serializer_class = self.get_serializer_class()
kwargs['context'] = self.get_serializer_context()
return serializer_class(*args, **kwargs)
les valeurs d'un champ de sérialiseur dépendent de l'identité de l'utilisateur actuellement connecté
Voici comment je gère de tels cas dans mon ModelViewSet:
def perform_create(self, serializer):
user = self.request.user
if user.username == 'myuser':
serializer.data['myfield'] = 'something'
serializer.save()