创建新对象时django rest框架的问题

时间:2018-03-23 18:58:02

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

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

代码:

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."]}

我不清楚我应该怎么做。我将不胜感激任何反馈。

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

以前的答案都指出了我正确的方向。最后,解决方案不是覆盖perform_create,而是创建函数:

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