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 #79 from postatum/103243506_profile_bug
Browse files Browse the repository at this point in the history
Rework singular view model handling
  • Loading branch information
jstoiko committed Sep 18, 2015
2 parents 94e95e3 + 1ae1d5f commit 260b762
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 14 deletions.
5 changes: 3 additions & 2 deletions ramses/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,9 @@ def generate_resource(config, raml_resource, parent_resource):
# but we store it on a different view attribute
if is_singular:
model_name = generate_model_name(route_name)
resource_kwargs['view']._singular_model = get_existing_model(
model_name)
view_cls = resource_kwargs['view']
view_cls._parent_model = view_cls.Model
view_cls.Model = get_existing_model(model_name)

# Create new nefertari resource
log.info('Creating new resource for `{}`'.format(route_name))
Expand Down
19 changes: 19 additions & 0 deletions ramses/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
from contextlib import contextmanager

import six
import inflection
Expand Down Expand Up @@ -318,3 +319,21 @@ def get_events_map():
'before': before_events,
'after': after_events,
}


@contextmanager
def patch_view_model(view_cls, model_cls):
""" Patches view_cls.Model with model_cls.
:param view_cls: View class "Model" param of which should be
patched
:param model_cls: Model class which should be used to patch
view_cls.Model
"""
original_model = view_cls.Model
view_cls.Model = model_cls

try:
yield
finally:
view_cls.Model = original_model
16 changes: 7 additions & 9 deletions ramses/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from nefertari.view import BaseView as NefertariBaseView
from nefertari.json_httpexceptions import JHTTPNotFound

from .utils import patch_view_model


log = logging.getLogger(__name__)

Expand Down Expand Up @@ -405,27 +407,23 @@ class ItemSingularView(ItemSubresourceBaseView):
If you decide to do so, make sure to set `self._singular_model` to a model
class, instances of which will be processed by this view.
"""
_singular_model = None
_parent_model = None

def __init__(self, *args, **kw):
super(ItemSingularView, self).__init__(*args, **kw)
self.attr = self.request.path.split('/')[-1]

def fill_null_values(self, model_cls=None):
return super(ItemSingularView, self).fill_null_values(
model_cls=self._singular_model)

def convert_ids2objects(self, model_cls=None):
return super(ItemSingularView, self).convert_ids2objects(
model_cls=self._singular_model)
def get_item(self, **kwargs):
with patch_view_model(self, self._parent_model):
return super(ItemSingularView, self).get_item(**kwargs)

def show(self, **kwargs):
parent_obj = self.get_item(**kwargs)
return getattr(parent_obj, self.attr)

def create(self, **kwargs):
parent_obj = self.get_item(**kwargs)
obj = self._singular_model(**self._json_params)
obj = self.Model(**self._json_params)
self.set_object_acl(obj)
obj = obj.save(self.request)
parent_obj.update({self.attr: obj}, self.request)
Expand Down
13 changes: 13 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,3 +394,16 @@ def test_get_events_map(self):
events.BeforeReplace,
events.BeforeUpdateMany,
]

def test_patch_view_model(self):
view_cls = Mock()
model1 = Mock()
model2 = Mock()
view_cls.Model = model1

with utils.patch_view_model(view_cls, model2):
view_cls.Model()

assert view_cls.Model is model1
assert not model1.called
model2.assert_called_once_with()
6 changes: 3 additions & 3 deletions tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -566,11 +566,11 @@ def test_create(self):
'foo': Mock(auth=False)
}
view.get_item = Mock()
view._singular_model = Mock()
view.Model = Mock()
resp = view.create(foo=1)
view.get_item.assert_called_once_with(foo=1)
view._singular_model.assert_called_once_with(foo2='bar2')
child = view._singular_model()
view.Model.assert_called_once_with(foo2='bar2')
child = view.Model()
child.save.assert_called_once_with(view.request)
parent = view.get_item()
parent.update.assert_called_once_with(
Expand Down

0 comments on commit 260b762

Please sign in to comment.