【问题标题】:How to pass extra context to Django Rest Framework serializers如何将额外的上下文传递给 Django Rest Framework 序列化程序
【发布时间】:2020-09-14 06:27:43
【问题描述】:

这是我第一个使用 Django REST 框架的项目,我正在努力做到这一点。我知道在主流 Django 框架中,如果我需要为基于类的视图添加额外的上下文,我会这样做:

class PostDetail(DetailView):
    model = Post

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # Add in a QuerySet of all the books by a certain author John
        context['john_books'] = Book.objects.filter(author=john)
        return context

然后,我将能够在我的模板中访问上下文“john_books”。现在我需要通过将额外的上下文传递给我的 PostViewSets 来做同样的事情。在详细视图中,我想在我的 api 端点中访问由该帖子作者创作的帖子列表(类似于“来自同一作者的帖子”)。我已经阅读了有关get_serializer_context 的信息,但仍然无法弄清楚如何实现它。这是我到目前为止所拥有的:

class PostViewSets(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

     def get_serializer_context(self):
        context = super(PostViewSets, self).get_serializer_context()
        author = self.get_object.author
        author_posts = self.get_queryset().filter(author=author)
        context.update({'author_posts': author_posts})
        return context

我得到这个错误:

/posts/ 'function' 对象的 AttributeError 没有属性 'author'

我的帖子模型:

class Post(models.Model):
    title = models.CharField(max_length=100, unique=True)
    body = models.TextField()
    is_featured = models.BooleanField(default=True)
    viewcount = models.IntegerField(default=0)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    created = models.DateTimeField(auto_now_add=True)

还有我的 PostSerializer 类:

class PostSerializer(serializers.ModelSerializer):
    author = UserSerializer()

    class Meta:
        model = Post
        fields = ['id', 'title', 'body', 'author', 'viewcount', 'is_featured', 'created']

【问题讨论】:

  • @ncopiy 的回答似乎是正确的。它不起作用,因为有几个问题,您可能需要逐步进行并为新问题打开新问题。

标签: django django-rest-framework


【解决方案1】:

您必须将get_object 用作函数,而不是属性:

class PostViewSets(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

     def get_serializer_context(self):
        context = super(PostViewSets, self).get_serializer_context()
        author = self.get_object().author
        author_posts = self.get_queryset().filter(author=author)
        context.update({'author_posts': author_posts})
        return context

【讨论】:

  • 它不起作用。我之前尝试过,它给出了断言错误
  • 请在错误下方找到:AssertionError at /posts/ Expected view PostViewSets to be called with a URL keyword argument named "pk". Fix your URL conf, or set the .lookup_field attribute on the view correctly。但是,视图集上的lookup_field 属性设置如下lookup_field = 'pk'
  • @banky 你怎么称呼它?
  • @banky 请在PostViewSets中添加lookup_field = 'pk'参数
  • @banky 请检查您的网址是否类似于 /posts/
【解决方案2】:

1。错误信息

/posts/ 'function' 对象的 AttributeError 没有属性 'author'

明确说明问题出在什么地方:

作者 = self.get_object.author

我猜你试图做这样的事情

author = self.get_object().author

2。一个 DRF 视图集

响应由相应的序列化器序列化的数据。因此,您无需更改 ViewSet,而是使用以下内容更新 Serializer:

class PostListSerializer(serializers.ModelSerializer):
    ... some fields ...

    class Meta:
        model = Post
        fields = [ ... some fields ... ]


class PostDetailsSerializer(serializers.ModelSerializer):
    ... some fields ...

    author_posts = PostListSerializer(source="author.post_set", many=True, read_only=True)

    class Meta:
        model = Post
        fields = [ ... some fields ... , 'author_posts']

或使用 SerializerMethodField

    class PostDetailsSerializer(serializers.ModelSerializer):
    ... some fields ...

    author_posts = serializers.SerializerMethodField()

    def get_author_posts(self, obj):
        return PostListSerializer(instance=obj.post_set.all(), many=True).data

    class Meta:
        model = Post
        fields = [ ... some fields ... , 'author_posts']

我没有尝试这个确切的代码,但这是主要思想。

【讨论】:

    猜你喜欢
    • 2016-09-25
    • 2014-05-24
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 2022-08-08
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多