在Django Rest Framework中访问Viewset和Serializer中的请求对象?

时间:2022-04-27 11:44:12

I want to access the request object in my Views.py and Serializers.py in DRF. My Views.py:

我想在DRF中的Views.py和Serializers.py中访问请求对象。我的Views.py:

class ProductViewSet(viewsets.ReadOnlyModelViewSet):

    """
    This viewset automatically provides `list` and `detail` actions.
    """
    queryset = Product.objects.all()
    serializer_class = ProductSerializer(context={'request': request})

My Serializers.py:

我的Serializers.py:

class ProductSerializer(serializers.HyperlinkedModelSerializer):

    get_sr_price = serializers.SerializerMethodField('get_sr_price_func')

    def get_sr_price_func(self, obj):
        return self.request.user ??

    class Meta:
        model = Product
        fields = (
            'title', 'slug', 'product_stores', 'get_sr_price')

In Serializers.py I get ProductSerializer' object has no attribute 'request'. Also In views.py I get NameError: name 'request' is not defined

在Serializers.py中,我得到的ProductSerializer'对象没有属性'request'。另外在views.py中我得到NameError:未定义名称'request'

How do I access request object? Do I have to pass it from views to serializers? Also what's the difference between views.py and serializers.py? Generally I write all the business logic in Views.py ; here also should I do all the queries/filters in the views or should I do them in serializers or it doesn't make a difference. New to DRF please help.

我如何访问请求对象?我是否必须将它从视图传递给序列化程序?那还有views.py和serializers.py之间的区别是什么?通常我会在Views.py中编写所有业务逻辑;这里也应该在视图中执行所有查询/过滤器,或者我应该在序列化程序中执行它们,或者它没有什么区别。 DRF新手请帮忙。

2 个解决方案

#1


19  

You don't need to include request object in the context as the generic views passes request object to the serializer context.

由于通用视图将请求对象传递给序列化程序上下文,因此您无需在上下文中包含请求对象。

DRF Source code snippet:

DRF源代码段:

# rest_framework/generics.py
def get_serializer_context(self):
    """
    Extra context provided to the serializer class.
    """
    return {
        'request': self.request, # request object is passed here
        'format': self.format_kwarg,
        'view': self
    }

In your serializer, you can access the request object using .context attribute.

在序列化程序中,您可以使用.context属性访问请求对象。

The context dictionary can be used within any serializer field logic, such as a custom .to_representation() method, by accessing the self.context attribute.

通过访问self.context属性,可以在任何序列化器字段逻辑中使用上下文字典,例如自定义.to_representation()方法。

class ProductSerializer(serializers.HyperlinkedModelSerializer):

    get_sr_price = serializers.SerializerMethodField('get_sr_price_func')

    def get_sr_price_func(self, obj):
        return self.context['request'].user # access the request object

#2


1  

Serializers are the way external data is mapped from / to models (Django or simple Python classes).

序列化器是外部数据从/向模型映射的方式(Django或简单的Python类)。

Views are dealing with how the data will be shown. Throttling, pagination, authentication are managed by the view. They also handle the data set.

视图正在处理数据的显示方式。限制,分页,身份验证由视图管理。他们还处理数据集。

DRF provides a context to pass request specific data to the serializer without having to redefine the init. This is likely what you're looking for.

DRF提供上下文以将请求特定数据传递给序列化程序,而无需重新定义init。这可能是你正在寻找的。

#1


19  

You don't need to include request object in the context as the generic views passes request object to the serializer context.

由于通用视图将请求对象传递给序列化程序上下文,因此您无需在上下文中包含请求对象。

DRF Source code snippet:

DRF源代码段:

# rest_framework/generics.py
def get_serializer_context(self):
    """
    Extra context provided to the serializer class.
    """
    return {
        'request': self.request, # request object is passed here
        'format': self.format_kwarg,
        'view': self
    }

In your serializer, you can access the request object using .context attribute.

在序列化程序中,您可以使用.context属性访问请求对象。

The context dictionary can be used within any serializer field logic, such as a custom .to_representation() method, by accessing the self.context attribute.

通过访问self.context属性,可以在任何序列化器字段逻辑中使用上下文字典,例如自定义.to_representation()方法。

class ProductSerializer(serializers.HyperlinkedModelSerializer):

    get_sr_price = serializers.SerializerMethodField('get_sr_price_func')

    def get_sr_price_func(self, obj):
        return self.context['request'].user # access the request object

#2


1  

Serializers are the way external data is mapped from / to models (Django or simple Python classes).

序列化器是外部数据从/向模型映射的方式(Django或简单的Python类)。

Views are dealing with how the data will be shown. Throttling, pagination, authentication are managed by the view. They also handle the data set.

视图正在处理数据的显示方式。限制,分页,身份验证由视图管理。他们还处理数据集。

DRF provides a context to pass request specific data to the serializer without having to redefine the init. This is likely what you're looking for.

DRF提供上下文以将请求特定数据传递给序列化程序,而无需重新定义init。这可能是你正在寻找的。