【问题标题】:Issue with django rest framework when creating new objects创建新对象时出现 django rest 框架问题
【发布时间】:2018-09-02 13:04:36
【问题描述】:

我正在尝试使用 django rest 框架为不同类型的内容(例如 Book)创建 Bookmark 模型的实例。

代码:

models.py

class Bookmark(models.Model):
    user = models.ForeignKey(User)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

api.py

from django.contrib.contenttypes.models import ContentType
from rest_framework import viewsets, mixins, serializers, permissions
from .models import Bookmark


class BookmarkSerializer(serializers.ModelSerializer):
    class Meta:
        model = Bookmark
        fields = ('id', 'user', 'content_type', 'object_id')


class BookmarkViewSet(mixins.CreateModelMixin,
                           mixins.ListModelMixin,
                           mixins.RetrieveModelMixin,
                           mixins.UpdateModelMixin,
                           mixins.DestroyModelMixin,
                           viewsets.GenericViewSet):
    queryset = Bookmark.objects.all()
    serializer_class = BookmarkSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]


    def perform_create(self, serializer):
        content_type = self.request.query_params.get('content_type')
        app, model = content_type.split(".")
        ct = ContentType.objects.get_by_natural_key(app, model)

        object_id = self.request.query_params.get('object_id')

        serializer.save(user=self.request.user, content_type=ct, object_id=object_id)


    def get_queryset(self):
        items = Bookmark.objects.filter(user=self.request.user)

        content_type = self.request.query_params.get('content_type', None)
        if content_type: 
            app, model = content_type.split(".")
            ct = ContentType.objects.get_by_natural_key(app, model)
            items = items.filter(content_type=ct)

        object_id = self.request.query_params.get('object_id', None)
        if object_id:
            items = items.filter(object_id=object_id)

        return items

get_queryset 部分很好。但是当我尝试创建新书签时 perform_create 失败:

var item = new Bookmark({'content_type': 'books.book', 'object_id': self.book_id});
item.save();

回复:

{"user":["This field is required."],"content_type":["Incorrect type. Expected pk value, received unicode."]}

我不清楚我应该如何做到这一点。如有任何反馈,我将不胜感激。

【问题讨论】:

    标签: javascript python django rest django-rest-framework


    【解决方案1】:

    您也应该发布您的模型定义,但您得到的错误是您还需要将 user 参数传递给 Bookmark 并且您应该传递一个 pk 值(也就是一个整数,即content_type 的对象的 id)。

    【讨论】:

      【解决方案2】:

      关于用户的错误消息我不能说什么,但这是我对第二个错误消息的 2 美分。

      您不能简单地将模型的路径作为content_type 键的字符串提供。

      Apparently ,您必须使用get_for_model 方法作为参数传递给模型(模型'Book',而不是它的实例),并返回ContentType 类型的对象。这个对象的id 是你应该作为值传递的。

      【讨论】:

        【解决方案3】:

        之前的两个答案都为我指明了正确的方向。最后解决的办法不是重写perform_create,而是create function:

        def create(self, request, *args, **kwargs):
        
            content_type = request.data['content_type']
            if content_type:
                app, model = content_type.split(".")
                ct = ContentType.objects.get_by_natural_key(app, model)
        
            request.data['user'] = request.user.id
            request.data['content_type'] = ct.id
            #object_id already passed as id in request.data
        

        可以在此处阅读进一步的说明: https://github.com/encode/django-rest-framework/issues/3470

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-04-23
          • 1970-01-01
          • 2019-06-14
          • 1970-01-01
          • 2014-07-07
          • 2019-02-10
          • 2020-02-19
          相关资源
          最近更新 更多