假设我有这个简单的模型:
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(或者我可以指定模型方法的参数吗?)
答案 0 :(得分:4)
如果我没有指定字段,我会获得absoluteUrl,但是包含所有模型的字段(包括private_data)。如果我在字段中添加'absoluteUrl',我会收到错误,因为blogpost.absoluteUrl不存在(没有惊喜)。
您应该将'absoluteUrl'
添加到fields
元组中,它应该可以正常工作 - 那么您看到的是什么错误?
absolute_url方法需要请求来确定域名(例如dev或prod),以及它是用http还是https制作的。
请注意,您也可以在不修改__init__
的情况下将上下文传递给序列化程序,只需在实例化序列化程序时传递context={'request': request}
即可。默认的通用视图集为您执行此操作,因此您可以在任何序列化程序方法中访问self.context['request']
。 (请注意,这是超链接关系如何返回完全限定的URL)