Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

""" 

The Response class in REST framework is similar to HTTPResponse, except that 

it is initialized with unrendered data, instead of a pre-rendered string. 

 

The appropriate renderer is called during Django's template response rendering. 

""" 

from __future__ import unicode_literals 

from django.core.handlers.wsgi import STATUS_CODE_TEXT 

from django.template.response import SimpleTemplateResponse 

from rest_framework.compat import six 

 

 

class Response(SimpleTemplateResponse): 

    """ 

    An HttpResponse that allows its data to be rendered into 

    arbitrary media types. 

    """ 

 

    def __init__(self, data=None, status=200, 

                 template_name=None, headers=None, 

                 exception=False, content_type=None): 

        """ 

        Alters the init arguments slightly. 

        For example, drop 'template_name', and instead use 'data'. 

 

        Setting 'renderer' and 'media_type' will typically be deferred, 

        For example being set automatically by the `APIView`. 

        """ 

        super(Response, self).__init__(None, status=status) 

        self.data = data 

        self.template_name = template_name 

        self.exception = exception 

        self.content_type = content_type 

 

        if headers: 

            for name, value in six.iteritems(headers): 

                self[name] = value 

 

    @property 

    def rendered_content(self): 

        renderer = getattr(self, 'accepted_renderer', None) 

        media_type = getattr(self, 'accepted_media_type', None) 

        context = getattr(self, 'renderer_context', None) 

 

        assert renderer, ".accepted_renderer not set on Response" 

        assert media_type, ".accepted_media_type not set on Response" 

        assert context, ".renderer_context not set on Response" 

        context['response'] = self 

 

        charset = renderer.charset 

        content_type = self.content_type 

 

        if content_type is None and charset is not None: 

            content_type = "{0}; charset={1}".format(media_type, charset) 

        elif content_type is None: 

            content_type = media_type 

        self['Content-Type'] = content_type 

 

        ret = renderer.render(self.data, media_type, context) 

        if isinstance(ret, six.text_type): 

            assert charset, 'renderer returned unicode, and did not specify ' \ 

            'a charset value.' 

            return bytes(ret.encode(charset)) 

        return ret 

 

    @property 

    def status_text(self): 

        """ 

        Returns reason text corresponding to our HTTP response status code. 

        Provided for convenience. 

        """ 

        # TODO: Deprecate and use a template tag instead 

        # TODO: Status code text for RFC 6585 status codes 

        return STATUS_CODE_TEXT.get(self.status_code, '') 

 

    def __getstate__(self): 

        """ 

        Remove attributes from the response that shouldn't be cached 

        """ 

        state = super(Response, self).__getstate__() 

        for key in ('accepted_renderer', 'renderer_context', 'data'): 

            if key in state: 

                del state[key] 

        return state