3

I am trying to test django view with REST framework. It starts like this.

class MoveViewSet(viewsets.ModelViewSet):
    serializer_class = FamilySerializer
    queryset = Family.objects.all()
    http_method_names = ['put']

    def update(self, request, pk=None):
        user = request.mobile_user
        ...
        family_id = request.POST.get('family_id', None)
        ...

in test.py I make a request like this.

data = dict(
        join_type='join',
        family_id=target_family.id,
    )
# also tried data = { ... }

header = {
        'Authorization': user.api_key,
        ...
    }
client = Client()
response = client.put(url, data=data, content_type='x-www-form-urlencoded', **header)

### What I've tried ###
# response = client.put(url, data=data, **header)
# response = self.client.put(url, data=data, **header)
# response = client.put(url, data=data, content_type='application/json', **header)

but in view, request.POST.get('paramname', 'default') makes error. request.POST has empty parameter set and of course, request.PUT is None.

I checked middleware but neither could I find params there. Also I've tried this in middleware's process_request.

def process_request(self, request):
    if request.method == "PUT" and request.content_type != "application/json":
        if hasattr(request, '_post'):
            del request._post
            del request._files
        try:
            request.method = "POST"
            request._load_post_and_files()
            request.method = "PUT"
        except AttributeError as e:
            request.META['REQUEST_METHOD'] = 'POST'
            request._load_post_and_files()
            request.META['REQUEST_METHOD'] = 'PUT'

        request.PUT = request.POST

It gives me this error. AttributeError: 'WSGIRequest' object has no attribute 'content_type'

If I send client.post() with data, request.POST has data, but put doesn't. How could I test client.put() with parameters?

Hyunseo Yang
  • 151
  • 1
  • 10
  • Which version of django do you use? – neverwalkaloner May 08 '18 at 06:14
  • 1
    What is your `url`? – rtindru May 08 '18 at 06:44
  • Also you need `request.META['CONTENT_TYPE']` – rtindru May 08 '18 at 06:46
  • 1
    Also, what is in `request.data` -> DRF since 3.x switched over to `request.data` which is a parsed representation of request.POST – rtindru May 08 '18 at 06:48
  • @neverwalkaloner 1.9.7 – Hyunseo Yang May 09 '18 at 05:34
  • @rtindru Thanks a lot with your comments. 1) url = '/api/v2/users/move/{}/'.format(old_family.id) 2) I tried request.META['CONTENT_TYPE'] (which is x-www-form-urlencoded in my code) - in view, after passing middleware code, request.PUT is empty and request.POST raises 415 unsupported media type. 3) request.data has correct value {'family_id': 29211L, 'join_type': 'join'} but it's type is 'str'. in this way, I need to change my view code to parse whenever I test my code. – Hyunseo Yang May 09 '18 at 05:47

1 Answers1

0

request's content_type attribute has been added in Django 1.10. Since you are using Django 1.9 you cannot use this attribute. You can chec request.META.get('HTTP_ACCEPT') solution as mentioned here or update Django.

neverwalkaloner
  • 46,181
  • 7
  • 92
  • 100