【问题标题】:Model Serializer : choose which fields to display and add custom fields模型序列化器:选择要显示的字段并添加自定义字段
【发布时间】:2013-07-26 10:54:48
【问题描述】:

假设我有这个简单的模型:

class BlogPost(models.Model):
    author = models.ForeignKey(MyUser)
    body = models.TextField()
    title = models.CharField(max_length=64)
    urlid = models.CharField(max_length=32)
    private_data = models.CharField(max_length=64)

private_data 包含我不想向 API 公开的数据 (!)。我正在使用 ModelSerializer :

class BlogPostSerializer(serializers.ModelSerializer):
    class Meta:
        model = BlogPost

    def __init__(self, *args, **kwargs):
        # Don't pass the 'request' arg up to the superclass
        request = kwargs.pop('request', None)
        # Instatiate the superclass normally
        super(ModelSerializer, self).__init__(*args, **kwargs)
        self.request = request

    def absolute_url(self, blogpost):
        return blogpost.get_absolute_url(self.request)

absolute_url 方法需要 request 来确定域名(例如 dev 或 prod)以及它是在 http 还是 https 中创建的。

我想指定模型中的哪些字段将由序列化程序返回(例如,不公开 private_data)。很简单:

class BlogPostSerializer(serializers.ModelSerializer):
    class Meta:
        model = BlogPost
        fields = ('author', 'body', 'title', 'urlid',)

    # The same jazz after that

好的,它有效。现在我也想返回absoluteUrl:

class BlogPostSerializer(serializers.ModelSerializer):
    absoluteUrl = serializers.SerializerMethodField('absolute_url')

    class Meta:
        model = BlogPost
        fields = ('author', 'body', 'title', 'urlid',)

    # The same jazz after that

好吧,毫无疑问,这只会返回我指定的字段,没有 absoluteUrl。如何仅返回模型的某些字段和从序列化程序计算的 absoluteUrl?

如果我不指定fields,我会得到absoluteUrl,但会包含所有模型的字段(包括private_data)。如果我将'absoluteUrl' 添加到fields 我会收到一个错误,因为blogpost.absoluteUrl 不存在(这并不奇怪)。我认为我不能使用 http://django-rest-framework.org/api-guide/serializers.html#specifying-fields-explicitly 这个方法,因为我需要 request 来获取 absoluteUrl(或者我可以为模型的方法指定参数吗?)

【问题讨论】:

  • 显然我可以将逻辑从blogpost.get_absolute_url 移动到序列化程序,但我宁愿将逻辑留在模型中。另外,我不是复制粘贴功能的忠实粉丝。

标签: django-rest-framework serialization


【解决方案1】:

如果我不指定字段,我会得到 absoluteUrl,但会包含模型的所有字段(包括 private_data)。如果我将 'absoluteUrl' 添加到字段中,我会收到错误消息,因为 blogpost.absoluteUrl 不存在(这并不奇怪)。

您应该只是将 'absoluteUrl' 添加到 fields 元组,它应该可以正常工作 - 那么您看到了什么错误?

absolute_url 方法需要请求来确定域名(例如 dev 或 prod)以及它是在 http 还是 https 中生成的。

请注意,您也可以在不修改__init__ 的情况下将上下文传递给序列化器,只需在实例化序列化器时传递context={'request': request}。默认的通用视图集为您执行此操作,因此您可以在任何序列化程序方法中访问self.context['request']。 (请注意,这就是超链接关系能够返回完全限定 URL 的方式)

【讨论】:

  • 我看到的错误是这样的:File "/usr/local/lib/python2.7/dist-packages/rest_framework/serializers.py", line 206, in get_fields new[key] = ret[key] KeyError: 'url'我使用url作为名称而不是absolute_url,它似乎把事情搞砸了......当我实际使用@ 987654329@ 它工作正常。好的,感谢您花时间回答!并感谢上下文的东西,我一定会使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
相关资源
最近更新 更多