Manuel Carrero
Manuel Carrero

Reputation: 637

How to correctly pass parameters to a Class Based View instance in Django?

I'm trying to pass parameters in a Class Based View instance, but I can't figure out the proper way to do that.

My api service works good in the REST Framework view and receive two mandatory parameters (user and language):

enter image description here

enter image description here

I found similar answers but send parameters in return, that is not my situation. This is my call,

_customdictionary = CustomDictionaryViewSet()
_customdictionary.custom_dictionary_kpi(request) 

I've tried and fail with:

_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

When I see my error.log, in this part:

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

Sending request, it shows me:

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

Sending the dict, it shows me:

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

Sending just the values:

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)

serializers.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'''

Extra: How could I send an extra optional parameter?

Thanks a lot, any help will be appreciated :)

Upvotes: 0

Views: 1193

Answers (1)

Yugandhar Chaudhari
Yugandhar Chaudhari

Reputation: 3974

Yes that is right data you must be calling the request.data in your custom_dictionary_kpi and you are not giving a parameter as webrequest.

You cam anytime send optional data in the request itself from browser or postman or client like {"language": 1, "user": 1,"foo": "bar"}

and do request.POST.get('foo') on server side.

If you wish to pass data in the class you can do it with keyword argument like this

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

and in your method implementation you can access in args e.g. (request) here as a tuple and as a dictionary if you look into kwargs as a dictionary e.g. {"language": 1, "user": 1} here

Try printing or debugging args and kwargs and see.

Upvotes: 1

Related Questions