我有一个Book模型,其中包含一个外键给用户(该书的所有者):
class Book(models.Model):
owner = models.ForiegnKey(User)
...
我为Book创建了一个ModelViewSet,它显示了登录用户拥有的书籍:
class BookViewSet(viewsets.ModelViewSet):
model = Book
serializer_class = BookSerializer
def get_queryset(self):
return Book.objects.filter(owner=self.request.user)
现在要创建一本新书,我想用request.user保存用户字段,而不是从其他客户端发送数据(为了更高的安全性)。例如:
def create(self, request, *args, **kwargs):
request.DATA['user'] = request.user
... (some code to create new Book from request.DATA using serialize class)
但是我收到了这个错误: 此QueryDict实例是不可变的。 (表示request.DATA是一个不可变的QueryDict,无法更改)
在使用django rest framework创建对象时,您是否知道添加其他字段的更好方法?
答案 0 :(得分:11)
更新:从v3开始,您需要执行此操作:
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
原则保持不变。
您希望将图书序列化程序的owner
字段设为只读,然后在pre_save()
中设置与用户的关联。
类似的东西:
def pre_save(self, obj):
obj.owner = self.request.user
请参阅tutorial section on "Associating Snippets with Users"。
我希望有所帮助。
答案 1 :(得分:7)
在Django REST Framework 3中,它的价值发生了变化。现在有perform_create()
替换了之前答案中建议的旧pre_save()
和post_save()
挂钩。例如:
from rest_framework import viewsets
class MyViewSet(viewsets.ModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
希望这能节省一些时间。
答案 2 :(得分:1)
如果您正在使用ModelSerializer
,那么就像实施restore_object()
方法一样简单:
class MySerializer(serializers.ModelSerializer):
def restore_object(self, attrs, instance=None):
create = not instance
instance = super(MySerializer, self).restore_object(attrs, instance)
if create:
instance.user = self.context['request'].user
return instance
# ...
restore_object()
用于将属性字典反序列化为对象实例。 ModelSerializer
implements this method并为您在Meta
类中指定的模型创建/更新实例。如果给定的instance
是None
,则表示仍然需要创建对象。在这种情况下,您只需将user
字段设置为所需的值。
更多信息: http://www.django-rest-framework.org/api-guide/serializers#declaring-serializers