2013-09-02 33 views
8

Tôi có một mô hình Book với một chìa khóa nước ngoài để sử dụng (chủ sở hữu của cuốn sách):Cách tốt nhất để thêm các trường bổ sung cho django-nghỉ ngơi-framework ModelViewSet khi tạo

class Book(models.Model): 
    owner = models.ForiegnKey(User) 
    ... 

Tôi đã tạo một ModelViewSet cho sách trong đó cho thấy những cuốn sách thuộc sở hữu của người dùng đăng nhập:

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

Bây giờ để tạo ra một cuốn sách mới, tôi muốn lưu lĩnh vực người dùng với request.user, không phải với dữ liệu được gửi từ khách hàng còn lại (đối với bảo mật hơn). ví dụ:

def create(self, request, *args, **kwargs): 
    request.DATA['user'] = request.user 
    ... (some code to create new Book from request.DATA using serialize class) 

nhưng tôi gặp lỗi này: Ví dụ về QueryDict này là không thay đổi. (có nghĩa là request.DATA là một QueryDict không thể thay đổi và không thể thay đổi được)

Bạn có biết cách nào tốt hơn để thêm các trường bổ sung khi tạo đối tượng với khung còn lại django không?

Trả lời

10

Cập nhật: Kể từ v3 bạn cần phải làm điều này:

def perform_create(self, serializer): 
    serializer.save(owner=self.request.user) 

Nguyên tắc vẫn giữ nguyên.


Bạn muốn làm cho owner lĩnh vực serializer sách của bạn chỉ đọc và sau đó thiết lập sự liên kết với người sử dụng trong pre_save().

Cái gì như:

def pre_save(self, obj): 
    obj.owner = self.request.user 

Xem tutorial section on "Associating Snippets with Users".

Tôi hy vọng điều đó sẽ hữu ích.

+0

cách đặt chủ sở hữu chỉ đọc ở lớp ModelSerializer? – Ali

+0

Chỉ cần vượt qua read_only = True. Xem http://django-rest-framework.org/api-guide/fields.html # core-arguments –

+0

Tôi sử dụng một ModelSerializer và các trường được xác định hoàn toàn từ các trường mô hình. – Ali

1

Nếu bạn đang sử dụng ModelSerializer nó dễ dàng như việc thực hiện các phương pháp 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() được sử dụng để deserialize một cuốn từ điển các thuộc tính thành một trường hợp đối tượng. ModelSerializerimplements this method và tạo/cập nhật cá thể cho mô hình bạn đã chỉ định trong lớp Meta. Nếu số instance cho trước là None nghĩa là đối tượng vẫn phải được tạo. Trong trường hợp này, bạn chỉ cần đặt trường user với giá trị mong muốn. thông tin

thêm: http://www.django-rest-framework.org/api-guide/serializers#declaring-serializers

6

Đối với những gì nó có giá trị này đã thay đổi trong Django REST Framework 3. Hiện tại có perform_create() thay thế các móc nối cũ hơn pre_save()post_save() được đề xuất trong câu trả lời trước. Ví dụ:

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) 

Hy vọng điều này sẽ giúp người khác tiết kiệm thời gian.

+1

Tuyệt vời. Chỉ cần một lỗi đánh máy nhỏ, nó phải là 'def perform_create (self, serializer):' –

Các vấn đề liên quan