[英]how to put absolute url field in serializer model in django rest framework?
I have a model like so: 我有一个这样的模型:
class GiveAbsolute(serializers.Field):
def to_native(self,value):
# this where it give an error (self doesn't have request)
# what i want it to give full url
# like: http://www.blabla.com/othermodel/1
return reverse('link_to_othermodel',
args=[value],
request=self.request)
class SomethingSerializer(serializers.ModelSerializer):
# field with foreign key
othermodel = GiveAbsolute(source="othermodel.id")
class Meta:
model=Something
fields("fields1","othermodel")
is there a way to achieve this ? 有没有办法实现这个目标? thanks
谢谢
The request object is an entry of the context dictionary. 请求对象是上下文字典的条目。 ie.
即。
request = self.context.get('request') request = self.context.get('request')
In your case, just do: 在你的情况下,只需:
self.request = self.context.get('request')
then build the url 然后建立网址
self.request.build_absolute_uri(reverse('some_url_name'))
The only thing in DRF, that has an access to request object is the view, so you need to figure out how to pass your request from view to serializer, for example in generic ListView you can use get_serializer
. DRF中唯一可以访问请求对象的是视图,因此您需要弄清楚如何将请求从视图传递到序列化程序,例如在通用ListView中,您可以使用
get_serializer
。
Then, when you already have it in your serializer, you can use self.parent
(which is a parent serializer) to capture it from the field itself: 然后,当您已经在序列化程序中使用它时,可以使用
self.parent
(它是父序列化程序)从字段本身捕获它:
class GiveAbsolute(serializers.Field):
def to_native(self,value):
return reverse('link_to_othermodel',
args=[value],
request=self.parent.request)
class SomethingSerializer(serializers.ModelSerializer):
# field with foreign key
othermodel = GiveAbsolute(source="othermodel.id")
class Meta:
model=Something
fields=("fields1","othermodel")
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(SomethingSerializer, self).__init__(*args, **kwargs)
class SomethingView(generics.ListAPIView):
model = Something
serializer_class = SomethingSerializer
def get_serializer(self, instance=None, data=None,
files=None, many=False, partial=False):
serializer_class = self.get_serializer_class()
context = self.get_serializer_context()
return serializer_class(instance, data=data, files=files, many=many,
partial=partial, context=context, request=self.request)
Based on the answer of mariodev, here is a reusable solution for Models ; 根据mariodev的答案,这里是模型的可重用解决方案; I use it to provide URLs to service (see them as metheds) on django models.
我用它来提供django模型上的服务URL(见它们为metheds)。
class RequestAwareSerializer(serializers.ModelSerializer):
"""
A serializer which fields can access the request object.
"""
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(RequestAwareSerializer, self).__init__(*args, **kwargs)
class APIMethodField(serializers.Field):
""" To get the absolute URL of a method accessible via the API
"""
def __init__(self, url_action_name, *args, **kwargs):
self._url_name = url_action_name
super(APIMethodField, self).__init__(source='*', *args, **kwargs)
def to_native(self, obj):
"""
@param objid the ID of the object
@param method_url_name, the name of the url, as in urls.py
"""
return reverse_lazy(self._url_name, args=[obj.id],
request=self.parent.request)
class ChattyModelViewSet(ModelViewSet):
""" ModelViewSet which informs the serializer about the request
(abstract)
"""
def get_serializer(self, instance=None, data=None,
files=None, many=False, partial=False):
serializer_class = self.get_serializer_class()
context = self.get_serializer_context()
return serializer_class(instance, data=data, files=files, many=many,
partial=partial, context=context,
request=self.request)
url(r'^v1/maildomain/(?P<maildomain_id>\d+)/check/$',
views.MailDomainDetail.as_view(), name='maildomain_dns_check')
class MailDomainSerializer(RequestAwareSerializer):
checkdns_url = APIMethodField(url_action_name='maildomain_dns_check')
class Meta:
model = MailDomain()
fields = ('name', 'checkdns_url')
class MailDomainView(ChattyModelViewSet):
model = MailDomain
serializer_class = MailDomainSerializer
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.