创建时向django-rest-framework ModelViewSet添加其他字段的最佳方法

Ali*_*Ali 9 python django rest django-rest-framework

我有一个带有外键的Book模型给用户(书的所有者):

class Book(models.Model):
    owner = models.ForiegnKey(User)
    ...
Run Code Online (Sandbox Code Playgroud)

我已经为Book创建了一个ModelViewSet,它显示了登录用户拥有的书籍:

class BookViewSet(viewsets.ModelViewSet):
    model = Book
    serializer_class = BookSerializer
    def get_queryset(self):
        return Book.objects.filter(owner=self.request.user)
Run Code Online (Sandbox Code Playgroud)

现在要创建一本新书,我想用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)
Run Code Online (Sandbox Code Playgroud)

但是我收到了这个错误:这个QueryDict实例是不可变的.(表示request.DATA是一个不可变的QueryDict,无法更改)

在使用django rest框架创建对象时,您是否知道添加其他字段的更好方法?

Car*_*son 11

更新:从v3开始,您需要这样做:

def perform_create(self, serializer):
    serializer.save(owner=self.request.user)
Run Code Online (Sandbox Code Playgroud)

原则保持不变.


您希望将owner图书序列化程序的字段设置为只读,然后设置与用户的关联pre_save().

就像是:

def pre_save(self, obj):
    obj.owner = self.request.user
Run Code Online (Sandbox Code Playgroud)

请参阅"将代码段与用户关联"教程部分.

我希望有所帮助.


Pau*_*l J 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)
Run Code Online (Sandbox Code Playgroud)

希望这能节省一些时间.