简体   繁体   English

如何在django rest框架中将绝对url字段放在序列化器模型中?

[英]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 谢谢

From the source 来自消息来源

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)。

Reusable components 可重复使用的组件

serializers.py serializers.py

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)

views.py views.py

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)

Example use 使用示例

urls.py urls.py

url(r'^v1/maildomain/(?P<maildomain_id>\d+)/check/$',
    views.MailDomainDetail.as_view(), name='maildomain_dns_check')

serializers.py serializers.py

class MailDomainSerializer(RequestAwareSerializer):
    checkdns_url = APIMethodField(url_action_name='maildomain_dns_check')

    class Meta:
        model = MailDomain()
        fields = ('name', 'checkdns_url')

views.py views.py

class MailDomainView(ChattyModelViewSet):
    model = MailDomain
    serializer_class = MailDomainSerializer

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

相关问题 Django Rest Framework模型序列化程序自定义字段 - Django Rest Framework Model Serializer Custom Field Django Rest Framework Url 字段序列化程序 - Django Rest Framework Url Field Serializer 如何使用 Django Rest Framework 将 url 字段添加到序列化程序 - How to add an url field to a serializer with Django Rest Framework 如何在包含另一个序列化程序(模型)、django rest 框架的序列化程序中创建自定义列表字段? - How to create custom list field in serializer, which contains another serializer(model), django rest framework? Django rest框架如何访问序列化程序中的字段 - Django rest framework how to access field in serializer Django Rest Framework - 如何自定义序列化器字段 - Django Rest Framework - how to customize serializer field django rest 框架序列化器方法字段如何 - django rest framework serializer method field how to 如何在 Django Rest 框架中从父 model 序列化器获取子 model 字段值? - How to get child model field value from parent model serializer in Django Rest Framework? Django Rest Framework序列化器-多次序列化单个模型字段 - Django rest framework serializer - Serialize single model field multiple times Django Rest Framework - 在序列化器中获取相关的模型字段 - Django Rest Framework - Get related model field in serializer
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM