如何正确地将参数传递给 Django 中的基于类的视图实例?

Posted

技术标签:

【中文标题】如何正确地将参数传递给 Django 中的基于类的视图实例?【英文标题】:How to correctly pass parameters to a Class Based View instance in Django? 【发布时间】:2020-01-21 03:27:51 【问题描述】:

我正在尝试在基于类的视图实例中传递参数,但我想不出正确的方法。

我的 api 服务在 REST Framework 视图中运行良好,并接收两个强制参数(用户和语言):

我发现了类似的answers,但发送参数作为回报,这不是我的情况。这是我的电话,

_customdictionary = CustomDictionaryViewSet()
_customdictionary.custom_dictionary_kpi(request) 

我尝试过但失败了:

_customdictionary.custom_dictionary_kpi(request)
_customdictionary.custom_dictionary_kpi('language': 1, 'user': 1)
_customdictionary.custom_dictionary_kpi(1,1)
# In all cases i receive status = 500

当我看到我的 error.log 时,在这部分:

class CustomDictionaryViewSet(viewsets.ModelViewSet):
...
    def custom_dictionary_kpi(self, request, *args, **kwargs):
        try:
            import pdb;pdb.set_trace()

发送请求,它告诉我:

AttributeError: 'WSGIRequest' object has no attribute 'data'

发送 dict,它告诉我:

AttributeError: 'dict' object has no attribute 'data'

只发送值:

AttributeError: 'int' object has no attribute 'data'

api/urls.py

urlpatterns = [
url(r'^api/customdictionary/custom_dictionary_kpi/user/<int:user_id>/language/<int:language_id>', CustomDictionaryViewSet.as_view('post': 'custom_dictionary_kpi'), name='custom_dictionary_kpi')
]

api/api.py

class CustomDictionaryViewSet(viewsets.ModelViewSet):
    queryset = CustomDictionary.objects.filter(
        is_active=True,
        is_deleted=False
    ).order_by('id')
    permission_classes = [
        permissions.AllowAny
    ]
    pagination_class = StandardResultsSetPagination

    def __init__(self,*args, **kwargs):
        self.response_data = 'error': [], 'data': 
        self.code = 0

    def get_serializer_class(self):
        if self.action == 'custom_dictionary_kpi':
            return CustomDictionaryKpiSerializer
        return CustomDictionarySerializer

    @action(methods=['post'], detail=False)
    def custom_dictionary_kpi(self, request, *args, **kwargs):
        try:
            '''some logic'''
        except Exception as e:
            '''some exception'''
        return Response(self.response_data,status=self.code)

序列化器.py

class CustomDictionarySerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomDictionary
        fields = ('__all__')

class CustomDictionaryKpiSerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomDictionary
        fields = ('user','language')

web/views.py

class CustomDictionaryView(View):
    """docstring for CustomDictionaryView"""
    def __init__(self,*args, **kwargs):
        self.response_data = 'error': [], 'data': 
        self.code = 0

    def get(self, request, *args, **kwargs):
        try:
            _customdictionary = CustomDictionaryViewSet()
            import pdb;pdb.set_trace()
            _customdictionary.custom_dictionary_kpi()   # Here is the call, 
            self.response_data['data'] = _customdictionary.response_data['data']
            self.code = _customdictionary.code

        except Exception as e:
            '''some exception'''

额外: 如何发送额外的可选参数?

非常感谢,任何帮助将不胜感激:)

【问题讨论】:

【参考方案1】:

是的,这是正确的数据,您必须在您的 custom_dictionary_kpi 并且您没有将参数作为 webrequest 提供。

您可以随时从浏览器或邮递员或客户端(如"language": 1, "user": 1,"foo": "bar")在请求本身中发送可选数据

在服务器端执行request.POST.get('foo')

如果你想在类中传递数据,你可以使用这样的关键字参数来实现

_customdictionary = CustomDictionaryViewSet()
_customdictionary.custom_dictionary_kpi(request,language=1,user=1) 

在您的方法实现中,您可以在args 中访问,例如(请求)在这里作为元组和字典,如果您将kwargs 作为字典查看,例如"language": 1, "user": 1这里

尝试打印或调试 args 和 kwargs 看看。

【讨论】:

Yugandhar Chaudhari 当我测试我的 html 时,将 custom_dictionary_kpi request.data['user'] 更改为 request['user'] 效果很好,但是如果我在DRF 视图,我收到:*** TypeError:“请求”对象不可下标。有没有办法在两种情况下继续工作(DRF 视图和通过在 html 模板中请求) ` *** TypeError: 'Request' object is not subscriptable` 这意味着当它不是字典时,您正在尝试通过这样做来处理字典 request['user'] 它是 WSGIRequest 实例不是字典。最简洁的发送方式是请求数据并访问它

以上是关于如何正确地将参数传递给 Django 中的基于类的视图实例?的主要内容,如果未能解决你的问题,请参考以下文章

如何正确地将参数传递给rails表单

如何正确地将参数传递给 joomla 组件?

Django:将字符串参数传递给基于类的视图不起作用

如何有条件地将参数传递给 Flutter/Dart 中的 Widget?

如何最好地将 CString 转换为 BSTR 以将其作为“in”参数传递给 COM 方法?

Django - 将参数传递给 CBV 装饰器的正确方法?