Skip to content
This repository has been archived by the owner on Sep 28, 2022. It is now read-only.

Commit

Permalink
Merge pull request #107 from postatum/101517326_simplify_logic
Browse files Browse the repository at this point in the history
Refactor BaseView. Clear query params on tunneled collection update
  • Loading branch information
jstoiko committed Sep 10, 2015
2 parents 58fc701 + b0e3f5f commit 5525143
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 25 deletions.
1 change: 1 addition & 0 deletions nefertari/tweens.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def get_tunneling(request):
valid_params = drop_reserved_params(get_params)
request.body = six.b(json.dumps(valid_params))
request.content_type = 'application/json'
request._tunneled_get = True

return handler(request)

Expand Down
65 changes: 40 additions & 25 deletions nefertari/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ def view_mapper_wrapper(context, request):
action = getattr(view_obj, action_name)
request.action = action_name

# Tunneled collection PATCH/PUT doesn't support query params
tunneled = getattr(request, '_tunneled_get', False)
if tunneled and action_name in ('update_many',):
view_obj._query_params = dictset()

# we should not run "after_calls" here, so lets save them in
# request as filters they will be ran in the renderer factory
request.filters = view_obj._after_calls
Expand Down Expand Up @@ -103,39 +108,16 @@ def __init__(self, context, request, _query_params={}, _json_params={}):
"""
self.context = context
self.request = request
self._query_params = dictset(_query_params or request.params.mixed())
self._json_params = dictset(_json_params)

ctype = request.content_type
if request.method in ['POST', 'PUT', 'PATCH']:
if ctype == 'application/json':
try:
self._json_params.update(request.json)
except simplejson.JSONDecodeError:
log.error(
"Expecting JSON. Received: '{}'. "
"Request: {} {}".format(
request.body, request.method, request.url))

self._json_params = BaseView.convert_dotted(self._json_params)
self._query_params = BaseView.convert_dotted(self._query_params)

self._params = self._query_params.copy()
self._params.update(self._json_params)
self.prepare_request_params(_query_params, _json_params)

# dict of the callables {'action':[callable1, callable2..]}
# as name implies, before calls are executed before the action is
# called after_calls are called after the action returns.
self._before_calls = defaultdict(list)
self._after_calls = defaultdict(list)

# no accept headers, use default
if '' in request.accept:
request.override_renderer = self._default_renderer
elif 'application/json' in request.accept:
request.override_renderer = 'nefertari_json'
elif 'text/plain' in request.accept:
request.override_renderer = 'string'
self.set_override_rendered()

root_resource = getattr(self, 'root_resource', None)
self._auth_enabled = root_resource is not None and root_resource.auth
Expand All @@ -151,6 +133,39 @@ def _run_init_actions(self):
if self.request.method == 'PUT':
self.fill_null_values()

def prepare_request_params(self, _query_params, _json_params):
""" Prepare query and update params. """
self._query_params = dictset(
_query_params or self.request.params.mixed())
self._json_params = dictset(_json_params)

ctype = self.request.content_type
if self.request.method in ['POST', 'PUT', 'PATCH']:
if ctype == 'application/json':
try:
self._json_params.update(self.request.json)
except simplejson.JSONDecodeError:
log.error(
"Expecting JSON. Received: '{}'. "
"Request: {} {}".format(
self.request.body, self.request.method,
self.request.url))

self._json_params = BaseView.convert_dotted(self._json_params)
self._query_params = BaseView.convert_dotted(self._query_params)

self._params = self._query_params.copy()
self._params.update(self._json_params)

def set_override_rendered(self):
""" Set self.request.override_renderer if needed. """
if '' in self.request.accept:
self.request.override_renderer = self._default_renderer
elif 'application/json' in self.request.accept:
self.request.override_renderer = 'nefertari_json'
elif 'text/plain' in self.request.accept:
self.request.override_renderer = 'string'

def _setup_aggregation(self):
""" Wrap `self.index` method with ESAggregator.
Expand Down
1 change: 1 addition & 0 deletions tests/test_tweens.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ def mixed(self):
assert request.method == 'POST'
assert request.content_type == 'application/json'
assert request.body == six.b('{"foo": "bar"}')
assert request._tunneled_get

def test_get_tunneling_not_allowed_method(self):
class GET(dict):
Expand Down

0 comments on commit 5525143

Please sign in to comment.