I want my visitors to have function for creating and get list of Proposals.
User sends all of the data except the author of Proposal (because the auth is user himself), so I'm trying to extend request.data with request.user like this:
# proposals/views.py
class ProposalsList(ListCreateAPIView):
permission_classes = (IsAuthenticatedOrReadOnly,)
queryset = Proposal.objects.all()
serializer_class = ProposalSerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data={
**request.data,
"author": request.user.id,
})
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)
Although, I want to GET the proposals list with serialized author (user), so my serializer looks like:
# proposals/serializers.py
class ProposalSerializer(serializers.ModelSerializer):
author = UserSerializer()
class Meta:
model = SeekerProposal
fields = ('text', 'author')
The problem is that I GET users list correctly (serialized to dict), but I can't POST (create new) Proposal, because it wants to "author" be a dict (it happens because I'm using nested serializer author = UserSerializer()).
Questions:
- Is there a way to let view be ListCreateAPIView and author = UserSerializer() while GET list with serialized data and create proposal by request.user.id?
- Maybe there is another way to add authorized user to Proposal author field?
Also, this is my model:
# proposals/models.py
class Proposal(models.Model):
text = models.TextField(blank=False, null=False)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.SET(get_sentinel_user),
)
Answer
User @zaidfazil helped me with solution. I needed to add just one more additional field to my serializer for author details to be shown serialized:
# proposals/serializers.py
class ProposalSerializer(serializers.ModelSerializer):
author_details = UserSerializer(source='author', read_only=True)
class Meta:
model = SeekerProposal
# author will be user id, and author_details will be serialized dict
fields = ('text', 'author', 'author_details')
Because author is still just user id and author_details is read_only=True I will get all the data for author in GET request and can create new proposal by author=request.user.id.
One moment:
I didn't use blank=True on author field, because I must be sure that this field is not empty. So my view looks the same as I wrote it above (post on ProposalsList).
Again, thanks a lot to @zaidfazil! If I wrote something wrong please write me, I'm kind of nooby on stackoverflow.