简体   繁体   English

的DRF无法发布通过主键的数据

[英]python - DRF Unable to post data passing a Primary Key

I'm starting to work with Django and I followed the tutorial available in the Django Rest Framework website and now I'm trying to adapt the tutorial to do something a little more complex. 我开始使用Django,并且按照Django Rest Framework网站上的可用教程进行操作,现在我试图使该教程适应一些复杂的要求。

I'm trying to create a "Like" system for a Social Network. 我正在尝试为社交网络创建一个“赞”系统。 A User can create Posts (UserPosts) and Like other user's posts. 用户可以创建帖子(UserPosts)和其他用户的帖子。

I'm creating new UserPosts (using the command line) this way: 我正在以这种方式创建新的UserPosts(使用命令行):

http -a admin:Pass1234 POST http://127.0.0.1:8000/posts/ description="I'm just a random comment"

And everything works just fine. 而且一切正常。 The problem is when I try to create a Like instance. 问题是当我尝试创建Like实例时。 In this case I need to pass a UserPost id, so I'm doing the same as I did to create a new comment: 在这种情况下,我需要传递一个UserPost ID,所以我的操作与创建新评论相同:

http -a admin:Pass1234 POST http://127.0.0.1:8000/likes/ post="1"

But when I do this I get the following error: 但是当我这样做时,出现以下错误:

"post": {
        "non_field_errors": [
            "Invalid data. Expected a dictionary, but got unicode."
        ]
    }

The models are the following: 这些模型如下:

class UserPost(models.Model):
    owner = models.ForeignKey('auth.User', related_name='posts', on_delete=models.CASCADE)
    timestamp = models.DateTimeField(auto_now_add=True)
    description = models.CharField(max_length=100, blank=True, default='')

    def save(self, *args, **kwargs):
        options = self.description and {'description': self.description} or {}
        super(UserPost, self).save(*args, **kwargs)

    class Meta:
        ordering = ('timestamp',)


class Like(models.Model):
    owner = models.ForeignKey('auth.User', related_name='likes', on_delete=models.CASCADE)
    post = models.ForeignKey(UserPost, related_name='likes', on_delete=models.CASCADE)
    timestamp = models.DateTimeField(auto_now_add=True)

    def save(self, *args, **kwargs):
        options = self.post and {'post': self.post}
        super(Like, self).save(*args, **kwargs)

    class Meta:
        ordering = ('timestamp',)

The serializers: 序列化器:

class UserPostSerializer(serializers.HyperlinkedModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.id')

    class Meta:
        model = UserPost
        fields = ('url', 'id', 'description', 'owner', 'timestamp')


class LikeSerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.id')
    post = UserPostSerializer(source='post')

    class Meta:
        model = Like
        fields = ('id', 'owner', 'post', 'timestamp')

The Views: 观点:

class PostViewSet(viewsets.ModelViewSet):
    queryset = UserPost.objects.all()
    serializer_class = UserPostSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                          IsOwnerOrReadOnly,)

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


class LikeViewSet(viewsets.ModelViewSet):
    queryset = Like.objects.all()
    serializer_class = LikeSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly,)

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

Routers and urls: 路由器和网址:

router = DefaultRouter()
router.register(r'posts', views.PostViewSet)
router.register(r'users', views.UserViewSet)
router.register(r'likes', views.LikeViewSet)

urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

Any idea of what is happening? 有什么想法吗?

Thanks! 谢谢!

You need to remove post = UserPostSerializer from your LikeSerializer : 您需要从LikeSerializer删除post = UserPostSerializer LikeSerializer

class LikeSerializer(serializers.ModelSerializer):
  owner = serializers.ReadOnlyField(source='owner.id')

  class Meta:
    model = Like
    fields = ('id', 'owner', 'post', 'timestamp')

so that django-rest-framework uses a PrimaryKeyRelatedField for the related UserPost (which is the default for related models with ModelSerializer). 因此django-rest-framework会将PrimaryKeyRelatedField用于相关的UserPost(这是使用ModelSerializer的相关模型的默认设置)。
Then you can create your Like entry with post="1" as parameter. 然后,您可以使用post="1"作为参数创建Like条目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM