Projet

Général

Profil

0004-jsonresponse-remove-unused-serializers-from-to_json-.patch

Frédéric Péters, 29 juin 2017 08:00

Télécharger (24,3 ko)

Voir les différences:

Subject: [PATCH 4/5] jsonresponse: remove unused serializers from to_json
 decorator (#17175)

 passerelle/apps/bdp/views.py                    |  8 ++--
 passerelle/apps/choosit/views.py                |  8 ++--
 passerelle/apps/clicrdv/views.py                | 22 +++++-----
 passerelle/apps/csvdatasource/views.py          |  4 +-
 passerelle/contrib/agoraplus/views.py           | 26 +++++------
 passerelle/contrib/fake_family/views.py         |  4 +-
 passerelle/contrib/meyzieu_newsletters/views.py | 12 ++---
 passerelle/contrib/solis_apa/views.py           |  8 ++--
 passerelle/contrib/stub_invoices/views.py       | 16 +++----
 passerelle/contrib/teamnet_axel/views.py        | 10 ++---
 passerelle/utils/jsonresponse.py                | 58 +++----------------------
 passerelle/views.py                             |  3 +-
 tests/test_jsonresponse.py                      | 37 +++++-----------
 13 files changed, 78 insertions(+), 138 deletions(-)
passerelle/apps/bdp/views.py
16 16
    model = Bdp
17 17

  
18 18
    @utils.protected_api('can_access')
19
    @utils.to_json('api')
19
    @utils.to_json()
20 20
    def get(self, request, *args, **kwargs):
21 21
        text_key = request.GET.get('text_key')
22 22
        id_key = request.GET.get('id_key')
......
29 29
                r['text'] = r[text_key]
30 30
            elif 'text' not in r:
31 31
                r['text'] = r['id']
32
        return resources
32
        return {'data': resources}
33 33

  
34 34

  
35 35
class PostAdherentView(View, SingleObjectMixin):
......
39 39
        raise Http404
40 40

  
41 41
    @utils.protected_api('can_access')
42
    @utils.to_json('api')
42
    @utils.to_json()
43 43
    def post(self, request, *args, **kwargs):
44 44
        data = json.loads(request.body) # JSON w.c.s. formdata
45 45
        date_de_naissance = data['fields'].get('date_de_naissance')
......
61 61
            'bibliotheque': {'id': bibliotheque_id},
62 62
            'abonnements': abonnements,
63 63
        }
64
        return self.get_object().post_api('adherents', adherent)
64
        return {'data': self.get_object().post_api('adherents', adherent)}
65 65

  
66 66

  
67 67
class BdpDetailView(DetailView):
passerelle/apps/choosit/views.py
51 51
    def dispatch(self, request, *args, **kwargs):
52 52
        return super(ChoositRegisterView, self).dispatch(request, *args, **kwargs)
53 53

  
54
    @utils.to_json('api')
54
    @utils.to_json()
55 55
    @method_decorator(csrf_exempt)
56 56
    def get(self, request, *args, **kwargs):
57 57
        user = request.GET.get('user')
58 58
        assert user, 'missing user parameter'
59
        return self.get_object().get_list(user)
59
        return {'data': self.get_object().get_list(user)}
60 60

  
61
    @utils.to_json('api')
61
    @utils.to_json()
62 62
    def post(self, request, *args, **kwargs):
63 63
        user = request.GET.get('user')
64 64
        assert user, 'missing user parameter'
65 65
        data = json.loads(request.body)
66 66
        assert isinstance(data, list), 'body must be a JSON list'
67
        return self.get_object().post(user, data)
67
        return {'data': self.get_object().post(user, data)}
passerelle/apps/clicrdv/views.py
19 19
    """
20 20
    model = ClicRdv
21 21

  
22
    @utils.to_json('api')
22
    @utils.to_json()
23 23
    def get(self, request, intervention_id, *args, **kwargs):
24
        return self.get_object().get_datetimes(intervention_id)
24
        return {'data': self.get_object().get_datetimes(intervention_id)}
25 25

  
26 26

  
27 27
class DatesView(View, SingleObjectMixin):
......
34 34
    """
35 35
    model = ClicRdv
36 36

  
37
    @utils.to_json('api')
37
    @utils.to_json()
38 38
    def get(self, request, intervention_id, *args, **kwargs):
39
        return self.get_object().get_dates(intervention_id)
39
        return {'data': self.get_object().get_dates(intervention_id)}
40 40

  
41 41

  
42 42
class TimesView(View, SingleObjectMixin):
......
49 49
    """
50 50
    model = ClicRdv
51 51

  
52
    @utils.to_json('api')
52
    @utils.to_json()
53 53
    def get(self, request, intervention_id, date, *args, **kwargs):
54
        return self.get_object().get_times(intervention_id, date)
54
        return {'data': self.get_object().get_times(intervention_id, date)}
55 55

  
56 56

  
57 57
class CreateAppointmentView(View, SingleObjectMixin):
......
81 81
    model = ClicRdv
82 82

  
83 83
    @utils.protected_api('can_manage_appointment')
84
    @utils.to_json('api')
84
    @utils.to_json()
85 85
    def post(self, request, intervention_id=None, *args, **kwargs):
86 86
        if intervention_id is None:
87 87
            intervention_id = self.request.GET.get('intervention')
88 88
        data = json.loads(request.body)
89
        return self.get_object().create_appointment(
89
        return {'data': self.get_object().create_appointment(
90 90
                intervention_id,
91 91
                self.request.GET.get('websource'),
92
                data)
92
                data)}
93 93

  
94 94

  
95 95
class CancelAppointmentView(View, SingleObjectMixin):
......
102 102
    model = ClicRdv
103 103

  
104 104
    @utils.protected_api('can_manage_appointment')
105
    @utils.to_json('api')
105
    @utils.to_json()
106 106
    def get(self, request, appointment_id, *args, **kwargs):
107
        return self.get_object().cancel(appointment_id)
107
        return {'data': self.get_object().cancel(appointment_id)}
passerelle/apps/csvdatasource/views.py
68 68

  
69 69

  
70 70
    @utils.protected_api('can_access')
71
    @utils.to_json('api')
71
    @utils.to_json()
72 72
    def get(self, request, *args, **kwargs):
73 73
        obj = self.get_object()
74 74
        filters = self._filters_builder(request)
75
        return obj.get_data(filters)
75
        return {'data': obj.get_data(filters)}
76 76

  
77 77

  
78 78
class NewQueryView(CreateView):
passerelle/contrib/agoraplus/views.py
115 115
    def get_data(self, request, *args, **kwargs):
116 116
        raise NotImplementedError
117 117

  
118
    @utils.to_json('api')
118
    @utils.to_json()
119 119
    @utils.protected_api('can_access')
120 120
    def get(self, request, *args, **kwargs):
121 121
        self.object = self.get_object()
122 122
        self.set_user_from_request(request)
123 123
        self.family = None
124
        return self.get_data(request, *args, **kwargs)
124
        return {'data': self.get_data(request, *args, **kwargs)}
125 125

  
126 126

  
127 127
class PingView(DetailView):
......
212 212
class LinkView(GenericDetailView):
213 213
    model = AgoraPlus
214 214

  
215
    @utils.to_json('api')
215
    @utils.to_json()
216 216
    @utils.protected_api('can_access')
217 217
    def get(self, request, *args, **kwargs):
218 218
        agoraplus = self.get_object()
......
237 237
                                               name_id=name_id,
238 238
                                               defaults={'login': login, 'password': password})
239 239
        logger.info('link created: NameID:%r with Agora login:%r', name_id, login)
240
        return True
240
        return {'data': True}
241 241

  
242 242

  
243 243
class UnlinkView(GenericDetailView):
244 244
    model = AgoraPlus
245 245

  
246
    @utils.to_json('api')
246
    @utils.to_json()
247 247
    @utils.protected_api('can_access')
248 248
    def get(self, request, *args, **kwargs):
249 249
        agoraplus = self.get_object()
......
252 252
        name_id = request.GET['NameID']
253 253
        provision_roles(name_id, 'DELETE')
254 254
        AgoraPlusLink.objects.filter(resource=agoraplus, name_id=name_id).delete()
255
        return True
255
        return {'data': True}
256 256

  
257 257

  
258 258
class FamilyView(DetailView):
......
346 346
    def post_data(self, name_id, formdata):
347 347
        raise NotImplementedError
348 348

  
349
    @utils.to_json('api')
349
    @utils.to_json()
350 350
    @utils.protected_api('can_access_sas')
351 351
    def post(self, request, *args, **kwargs):
352 352
        self.object = self.get_object()
......
356 356
        name_id = formdata.get('NameID')
357 357
        if not name_id:
358 358
            raise AgoraAPIError('missing NameID parameter')
359
        return self.post_data(name_id, formdata)
359
        return {'data': self.post_data(name_id, formdata)}
360 360

  
361 361

  
362 362
class SasFamilyView(SasView):
......
459 459
    def post_data(self, formdata):
460 460
        raise NotImplementedError
461 461

  
462
    @utils.to_json('api')
462
    @utils.to_json()
463 463
    @utils.protected_api('can_access_sas')
464 464
    def post(self, request, *args, **kwargs):
465 465
        self.object = self.get_object()
466 466
        self.set_user_from_request(request)
467 467
        data = json.loads(request.body)
468 468
        formdata = Formdata(data)
469
        return self.post_data(formdata)
469
        return {'data': self.post_data(formdata)}
470 470

  
471 471

  
472 472
class IncomesDeclarationView(PostFormdataView):
......
525 525
    def dispatch(self, *args, **kwargs):
526 526
        return super(InvoicePayView, self).dispatch(*args, **kwargs)
527 527

  
528
    @utils.to_json('api')
528
    @utils.to_json()
529 529
    @utils.protected_api('can_access')
530 530
    def post(self, request, *args, **kwargs):
531 531
        self.object = self.get_object()
532 532
        data = json.loads(request.body)
533
        return self.object.pay_invoice(kwargs['invoice_id'], data['transaction_id'],
534
                            data['transaction_date'])
533
        return {'data': self.object.pay_invoice(kwargs['invoice_id'], data['transaction_id'],
534
                            data['transaction_date'])}
535 535

  
536 536

  
537 537
class InvoiceView(DetailView):
passerelle/contrib/fake_family/views.py
45 45
    def get_data(self, request, *args, **kwargs):
46 46
        raise NotImplementedError
47 47

  
48
    @utils.to_json('api')
48
    @utils.to_json()
49 49
    def get(self, request, *args, **kwargs):
50 50
        self.resource = self.get_object()
51
        return self.get_data(request, *args, **kwargs)
51
        return {'data': self.get_data(request, *args, **kwargs)}
52 52

  
53 53

  
54 54
class LinkView(DetailView):
passerelle/contrib/meyzieu_newsletters/views.py
36 36
        raise NotImplementedError
37 37

  
38 38
    @utils.protected_api('can_access')
39
    @utils.to_json('api')
39
    @utils.to_json()
40 40
    def get(self, request, *args, **kwargs):
41
        return self.get_data(request, *args, **kwargs)
41
        return {'data': self.get_data(request, *args, **kwargs)}
42 42

  
43 43

  
44 44
class NewslettersTypesView(DetailView):
......
54 54
        return super(NewslettersSubscriptionsView, self).dispatch(*args, **kwargs)
55 55

  
56 56
    @utils.protected_api('can_access')
57
    @utils.to_json('api')
57
    @utils.to_json()
58 58
    def delete(self, request, *args, **kwargs):
59 59
        email = request.GET.get('email')
60 60
        assert email, 'missing email parameter'
......
62 62
        subscriptions = obj.get_subscriptions(email)
63 63
        for sub in subscriptions:
64 64
            sub['transports'] = []
65
        return obj.set_subscriptions(email, subscriptions)
65
        return {'data': obj.set_subscriptions(email, subscriptions)}
66 66

  
67 67
    @utils.protected_api('can_access')
68
    @utils.to_json('api')
68
    @utils.to_json()
69 69
    def post(self, request, *args, **kwargs):
70 70
        email = request.GET.get('email')
71 71
        assert email, 'missing email parameter'
72 72
        data = json.loads(request.body)
73
        return self.get_object().set_subscriptions(email, data)
73
        return {'data': self.get_object().set_subscriptions(email, data)}
74 74

  
75 75
    def get_data(self, request, *args, **kwargs):
76 76
        return self.get_object().get_subscriptions(request.GET.get('email'))
passerelle/contrib/solis_apa/views.py
41 41
        raise NotImplementedError
42 42

  
43 43
    @utils.protected_api('can_access')
44
    @utils.to_json('api')
44
    @utils.to_json()
45 45
    def get(self, request, *args, **kwargs):
46
        return self.get_data(request, *args, **kwargs)
46
        return {'data': self.get_data(request, *args, **kwargs)}
47 47

  
48 48
    def _get_params(self, request, *params):
49 49
        return [ request.GET.get(item, None) for item in params]
......
106 106
        return super(IntegrationView, self).dispatch(request, *args, **kwargs)
107 107

  
108 108
    @utils.protected_api('can_access')
109
    @utils.to_json('api')
109
    @utils.to_json()
110 110
    def post(self, request, *args, **kwargs):
111 111
        data = request.body
112
        return self.get_object().import_flow(data)
112
        return {'data': self.get_object().import_flow(data)}
passerelle/contrib/stub_invoices/views.py
31 31
class InvoicesView(DetailView):
32 32
    model = StubInvoicesConnector
33 33

  
34
    @utils.to_json('api')
34
    @utils.to_json()
35 35
    def get(self, request, *args, **kwargs):
36
        return [x for x in self.get_object().get_invoices() if not x.get('payment_date')]
36
        return {'data': [x for x in self.get_object().get_invoices() if not x.get('payment_date')]}
37 37

  
38 38

  
39 39
class HistoryInvoicesView(DetailView):
40 40
    model = StubInvoicesConnector
41 41

  
42
    @utils.to_json('api')
42
    @utils.to_json()
43 43
    def get(self, request, *args, **kwargs):
44
        return [x for x in self.get_object().get_invoices() if x.get('payment_date')]
44
        return {'data': [x for x in self.get_object().get_invoices() if x.get('payment_date')]}
45 45

  
46 46

  
47 47
class InvoiceView(DetailView):
48 48
    model = StubInvoicesConnector
49 49

  
50
    @utils.to_json('api')
50
    @utils.to_json()
51 51
    def get(self, request, *args, **kwargs):
52
        return self.get_object().get_invoice(kwargs.get('invoice_id'))
52
        return {'data': self.get_object().get_invoice(kwargs.get('invoice_id'))}
53 53

  
54 54

  
55 55
class InvoicePDFView(DetailView):
......
70 70
    def dispatch(self, *args, **kwargs):
71 71
        return super(InvoicePayView, self).dispatch(*args, **kwargs)
72 72

  
73
    @utils.to_json('api')
73
    @utils.to_json()
74 74
    @utils.protected_api('can_access')
75 75
    def post(self, request, *args, **kwargs):
76
        return utils.response_for_json(request, {'data': None})
76
        return {'data': None}
passerelle/contrib/teamnet_axel/views.py
38 38
        raise NotImplementedError
39 39

  
40 40
    @utils.protected_api('can_access')
41
    @utils.to_json('api')
41
    @utils.to_json()
42 42
    def get(self, request, *args, **kwargs):
43 43
        self.object = self.get_object()
44
        return self.get_data(request, *args, **kwargs)
44
        return {'data': self.get_data(request, *args, **kwargs)}
45 45

  
46 46

  
47 47
class PingView(DetailView):
......
159 159
    def dispatch(self, *args, **kwargs):
160 160
        return super(InvoicePayView, self).dispatch(*args, **kwargs)
161 161

  
162
    @utils.to_json('api')
162
    @utils.to_json()
163 163
    @utils.protected_api('can_access')
164 164
    def post(self, request, *args, **kwargs):
165 165
        self.object = self.get_object()
166 166
        data = json.loads(request.body)
167
        return self.object.pay_invoice(kwargs['regie_id'],
167
        return {'data': self.object.pay_invoice(kwargs['regie_id'],
168 168
                    kwargs['invoice_id'], data['transaction_id'],
169
                    data['transaction_date'])
169
                    data['transaction_date'])}
passerelle/utils/jsonresponse.py
6 6
import functools
7 7
import logging
8 8
import re
9
from collections import Iterable
10 9

  
11 10
from django.http import HttpResponse, Http404, HttpResponseBadRequest
12 11
from django.conf import settings
......
30 29

  
31 30

  
32 31
class to_json(object):
33
    def __init__(self, serializer_type, error_code=500, wrap_response=True, **kwargs):
34
        """
35
        serializer_types:
36
            * api - serialize buildin objects (dict, list, etc) in strict api
37
            * objects - serialize list of region in strict api
38
            * plain - just serialize result of function, do not wrap response and do not handle exceptions
39
        """
40
        self.serializer_type = serializer_type
32
    def __init__(self, error_code=500, **kwargs):
41 33
        self.method = None
42 34
        self.error_code = error_code
43 35
        self.kwargs = kwargs
44
        self.wrap_response = wrap_response
45 36
        if 'cls' not in self.kwargs:
46 37
            self.kwargs['cls'] = DjangoJSONEncoder
47 38

  
......
52 43
                return self.method(f, *args, **kwargs)
53 44

  
54 45
            if not args:
55
                if self.serializer_type == 'plain':
56
                    self.method = self.plain_func
57
                else:
58
                    self.method = self.api_func
46
                self.method = self.api_func
59 47

  
60 48
            if getattr(getattr(args[0], f.__name__, None), "im_self", False):
61
                if self.serializer_type == 'plain':
62
                    self.method = self.plain_method
63
                else:
64
                    self.method = self.api_method
49
                self.method = self.api_method
65 50
            else:
66
                if self.serializer_type == 'plain':
67
                    self.method = self.plain_func
68
                else:
69
                    self.method = self.api_func
51
                self.method = self.api_func
70 52

  
71 53
            return self.method(f, *args, **kwargs)
72 54

  
73 55
        return wrapper
74 56

  
75 57
    def obj_to_response(self, req, obj):
76
        if self.serializer_type == 'objects':
77
            if isinstance(obj, Iterable):
78
                obj = [o.serialize(req) if obj else None for o in obj]
79
            elif obj:
80
                obj = obj.serialize(req)
81
            else:
82
                obj = None
83
        if self.wrap_response:
84
            d = {"err": 0}
85
            d.update({"data": obj})
86
            return d
87
        else:
88
            if isinstance(obj, dict) and not 'err' in obj:
89
                obj['err'] = 0
90
            return obj
58
        if isinstance(obj, dict) and not 'err' in obj:
59
            obj['err'] = 0
60
        return obj
91 61

  
92 62
    def err_to_response(self, err):
93 63
        if hasattr(err, "__module__"):
......
182 152
                status = self.error_code
183 153

  
184 154
        return self.render_data(req, data, status)
185

  
186
    def plain_method(self, f, *args, **kwargs):
187
        data = f(*args, **kwargs)
188
        if isinstance(data, HttpResponse):
189
            return data
190

  
191
        return self.render_data(args[1], data)
192

  
193
    def plain_func(self, f, *args, **kwargs):
194
        data = f(*args, **kwargs)
195
        if isinstance(data, HttpResponse):
196
            return data
197

  
198
        return self.render_data(args[0], data)
passerelle/views.py
265 265
        return self.endpoint(request, **self.get_params(request, *args, **kwargs))
266 266

  
267 267
    def get(self, request, *args, **kwargs):
268
        json_decorator = to_json('api', wrap_response=False)
269 268
        if self.endpoint.endpoint_info.pattern:
270 269
            pattern = url(self.endpoint.endpoint_info.pattern, self.endpoint)
271 270
            match = pattern.resolve(kwargs.get('rest') or '')
......
274 273
            kwargs['other_params'] = match.kwargs
275 274
        elif kwargs.get('rest'):
276 275
            raise Http404()
277
        return json_decorator(self.perform)(request, *args, **kwargs)
276
        return to_json()(self.perform)(request, *args, **kwargs)
278 277

  
279 278
    def post(self, request, *args, **kwargs):
280 279
        return self.get(request, *args, **kwargs)
tests/test_jsonresponse.py
22 22
        return 'log as warning exception'
23 23

  
24 24

  
25
@to_json('api')
25
@to_json()
26 26
def wrapped_exception(req, *args, **kwargs):
27 27
    raise WrappedException
28 28

  
29 29

  
30
@to_json('api')
30
@to_json()
31 31
def log_as_warning_exception(req, *args, **kwargs):
32 32
    raise LogAsWarningException
33 33

  
34 34

  
35
@to_json('api')
35
@to_json()
36 36
def http404_exception(req, *args, **kwargs):
37 37
    raise Http404
38 38

  
39
@to_json('api')
39
@to_json()
40 40
def doesnotexist_exception(req, *args, **kwargs):
41 41
    raise ObjectDoesNotExist
42 42

  
43 43

  
44
@to_json('api')
44
@to_json()
45 45
def permissiondenied_exception(req, *args, **kwargs):
46 46
    raise PermissionDenied
47 47

  
......
104 104
def test_jsonresponse_error_header():
105 105
    request = RequestFactory()
106 106
    req = request.get('/')
107
    @to_json('api')
107
    @to_json()
108 108
    def test_func(req):
109 109
        return {"test": "un test"}
110 110

  
111 111
    result = test_func(req)
112 112
    assert result.status_code == 200
113 113
    data = json.loads(result.content)
114
    assert 'err' in data
115
    assert data['err'] == 0
116
    assert 'data' in data
117
    assert 'test' in data['data']
118
    assert data['data']['test'] == 'un test'
119
    @to_json('api')
114
    assert data == {'test': 'un test', 'err': 0}
115
    @to_json()
120 116
    def test_func(req):
121 117
        class CustomException(Exception):
122 118
            http_status = 200
......
135 131
    response = http404_exception(request.get('/'))
136 132
    assert response.status_code == 404
137 133

  
138
def test_jsonresponse_without_wrapping():
139
    request = RequestFactory()
140
    req = request.get('/')
141
    @to_json('api', wrap_response=False)
142
    def test_func(req):
143
        return {"foo": "bar"}
144
    result = test_func(req)
145
    data = json.loads(result.content)
146
    assert data == {"foo": "bar", "err": 0}
147

  
148 134
def test_jsonresponse_with_callback():
149 135
    request = RequestFactory()
150 136
    req = request.get('/?callback=myfunc')
151
    @to_json('api')
137
    @to_json()
152 138
    def test_func(req):
153 139
        return {"foo": "bar"}
154 140
    result = test_func(req)
......
156 142
    assert 'application/javascript' in content_type
157 143
    assert result.content.startswith('myfunc(')
158 144
    args = json.loads(result.content[7:-2])
159
    assert args['err'] == 0
160
    assert args['data'] == {"foo": "bar"}
145
    assert args == {'foo': 'bar', 'err': 0}
161 146

  
162 147
def test_jsonresponse_with_wrong_callback():
163 148
    request = RequestFactory()
164 149
    req = request.get('/?callback=myfunc()')
165
    @to_json('api')
150
    @to_json()
166 151
    def test_func(req):
167 152
        return {"foo": "bar"}
168 153
    result = test_func(req)
169
-