2

I have the following :

I am working with DRF, based JWT token. I want to associate an experiment with a USER, i.e when a post request is arriving I want to be able to save that post request with the Foreginkey it needed for the author by the user whom sent the request. The POST request is always authenticated and never anonymous, i.e request.user is always exist ( I can see it when debugging)

I tried to add the following

def create(self, request, **kwargs):
   request.data["author"] = request.user
   serializer = ExperimentsSerializers(data=request.data)
   if serializer.is_valid():
       serializer.save()
       return....

But is_valid return always False ( the only time ts was true, was when I took out the author from the ExperimentsSerializers fields....

will be happy for any leads....

my code attached below

Model.py:

class User(AbstractUser):
    pass

    def __str__(self):
        return self.username

class Experiments(models.Model):
    name = models.CharField(max_length=40)
    time = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

View.py:

filter_backends = [DjangoFilterBackend, filters.OrderingFilter]
serializer_class = ExperimentsSerializers
queryset = Experiments.objects.all()
filterset_fields = '__all__'
permission_classes = (permissions.IsAuthenticated,)

serializers.py

class ExperimentsSerializers(serializers.ModelSerializer):
    class Meta:
        model = models.Experiments
        fields = '__all__'
helpper
  • 2,058
  • 4
  • 13
  • 32

2 Answers2

10

You can just pass additional data with save arguments:

def create(self, request, **kwargs):
   serializer = ExperimentsSerializers(data=request.data)
   if serializer.is_valid():
       serializer.save(author=request.user)

Note that you may need to specify author field as read_only so it would not be required in request body:

class ExperimentsSerializers(serializers.ModelSerializer):
    class Meta:
        model = models.Experiments
        fields = '__all__'
        read_only_fields = ['author']
neverwalkaloner
  • 46,181
  • 7
  • 92
  • 100
  • do you have maybe a good link about to how to handle the user association issues? i.e when a user make a get request he can only get his data, delete put and so on.. – helpper Feb 05 '20 at 12:31
  • @helpper you can overrider `get_queryset` method of your view class. Check example here: https://stackoverflow.com/questions/33809345/how-to-access-current-user-in-django-class-based-view – neverwalkaloner Feb 05 '20 at 13:32
3

One more approach can be to use

HiddenField with default value set to CurrentUserDefault

This way that field will not be exposed at the same time current user will be accessible and other operations can be done on that user context.

author = serializers.HiddenField(default=serializers.CurrentUserDefault())

Something like this:

class ExperimentsSerializers(serializers.ModelSerializer):
    author = serializers.HiddenField(default=serializers.CurrentUserDefault())

    class Meta:
        model = models.Experiments
        fields = '__all__'

Reference :

Umair Mohammad
  • 4,489
  • 2
  • 20
  • 34