Django Rest框架嵌套对象使用request.user创建
我希望我的访问者有创建和获取建议列表的功能 用户发送除提案作者以外的所有数据(因为作者是用户本人),因此我尝试使用request.User扩展request.data,如下所示:Django Rest框架嵌套对象使用request.user创建,django,model,django-rest-framework,authorization,Django,Model,Django Rest Framework,Authorization,我希望我的访问者有创建和获取建议列表的功能 用户发送除提案作者以外的所有数据(因为作者是用户本人),因此我尝试使用request.User扩展request.data,如下所示: # proposals/views.py class ProposalsList(ListCreateAPIView): permission_classes = (IsAuthenticatedOrReadOnly,) queryset = Proposal.objects.all() ser
# 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)
虽然我希望获得带有序列化作者(用户)的建议列表,但我的序列化程序如下所示:
# proposals/serializers.py
class ProposalSerializer(serializers.ModelSerializer):
author = UserSerializer()
class Meta:
model = SeekerProposal
fields = ('text', 'author')
问题是,我正确地获取了用户列表(序列化为dict),但我无法发布(创建新的)提案,因为它希望“author”是dict(发生这种情况是因为我使用嵌套序列化程序author=UserSerializer())
问题:
# 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),
)
回答
用户帮助我解决了这个问题。
我只需在序列化程序中添加一个附加字段,即可序列化显示作者详细信息:
# 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')
因为author
仍然只是用户id,而author\u details
是read\u only=True
我将在get
request中获取作者的所有数据,并可以通过author=request.user.id
创建新提案
等一下:
我没有在author
字段中使用blank=True
,因为我必须确保该字段不是空的。因此,我的观点看起来与我在上面写的观点相同(post
onProposalsList
)
再次感谢您!如果我写错了什么,请写信给我,我有点像stackoverflow上的nooby。通常的方法是在模型中将您的
作者
字段定义为blank=True
,并在保存序列化程序时传递给用户
author = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.SET(get_sentinel_user), blank=True)
serializers.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email', 'first_name', .....)
class ProposalSerializer(serializers.ModelSerializer):
author_details = UserSerializer(source='author', read_only=True)
class Meta:
model = SeekerProposal
fields = ('text', 'author', 'author_details')
那么在你看来,
class ProposalsList(ListCreateAPIView):
permission_classes = (IsAuthenticatedOrReadOnly,)
queryset = SeekerProposal.objects.all()
serializer_class = SeekerProposalSerializer
def perform_create(self, serializer):
serializer.save(author=self.request.user)
谢谢但仍然存在问题:首先,在GET上,我需要一个带有序列化作者的提案列表,在创建提案后,我需要一个带有author=request.user.id的提案列表(但我不能,因为如果我在ProposalSerializer中使用author=UserSerializer(),它会在创建时请求对象);其次,我不想让author为空=True,因为这有点危险(很多情况下我都需要授权)将author
blank=True
设置为空不会产生任何影响,因为分配用户只能在后台处理。否则,它将失去自身的安全性,而且user
字段仍然是必需的。对于有关author详细信息的问题,您可以在GET请求中添加一个read_
字段,以查看详细信息现有作者信息的。我将很快更新我的答案。你给了我解决这个问题的方法!我将在我的问题中描述它。但有两件事:我需要确保作者不是空白的,所以我真的不想使用blank=True
而且我没有,你能在你的答案中向元组添加“author\u details”吗(为什么他们会出错)某种类型的答案是创建名为ProposalNestedSerializer的新序列化程序,该序列化程序继承我的ProposalSerializer并扩展author=UserSerializer(),同时将其从ProposalSerializer中删除。所以现在,我使用ProposalNestedSerializer for GET(并获得序列化作者的响应)和ProposalSerializer with POST(并且可以使用request.user.id创建提案)