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 #120 from postatum/fix_eventinstance
Browse files Browse the repository at this point in the history
Check for DataProxy when setting event.instance
  • Loading branch information
jstoiko committed Oct 14, 2015
2 parents fd45a7d + ca50985 commit 0a66d41
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 10 deletions.
2 changes: 1 addition & 1 deletion docs/source/field_processors.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Keyword Arguments
New value of of field

**instance**
Instance affected by request. Is None when set of items is updated in bulk and when item is created.
Instance affected by request. Is None when set of items is updated in bulk and when item is created. ``event.response`` may be used to access newly created object, if object is returned by view method.

**field**
Instance of nefertari.utils.data.FieldData instance containing data of changed field.
Expand Down
23 changes: 17 additions & 6 deletions nefertari/events.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from contextlib import contextmanager

from nefertari.utils import FieldData
from nefertari.utils import FieldData, DataProxy


class RequestEvent(object):
Expand All @@ -19,16 +19,25 @@ class RequestEvent(object):
determine what event was triggered when same event handler was
registered with and without field predicate.
:param instance: Object instance affected by request. Used in item
requests only. Should be used to read data only. Changes to the
instance may result in database data inconsistency.
requests only(item GET, PATCH, PUT, DELETE). Should be used
to read data only. Changes to the instance may result in database
data inconsistency.
:param response: Return value of view method. E.g. if view method
returns "1", value of event.response will be "1". Is None in all
"before" events. Note that is not necessarily a valid Pyramid
Response instance but the exact value returned by view method.
May be useful to access newly created object on "create" action
if it is returned by view method.
"""
def __init__(self, model, view,
fields=None, field=None, instance=None):
fields=None, field=None, instance=None,
response=None):
self.model = model
self.view = view
self.fields = fields
self.field = field
self.instance = instance
self.response = response

def set_field_value(self, field_name, value):
""" Set value of field named `field_name`.
Expand Down Expand Up @@ -287,15 +296,17 @@ def trigger_events(view_obj):
view_obj._json_params,
view_obj.Model)
}
if hasattr(view_obj.context, 'pk_field'):
event_kwargs['instance'] = view_obj.context
ctx = view_obj.context
if hasattr(ctx, 'pk_field') or isinstance(ctx, DataProxy):
event_kwargs['instance'] = ctx

before_event = BEFORE_EVENTS[event_action]
request.registry.notify(before_event(**event_kwargs))

yield

if do_trigger:
event_kwargs['response'] = view_obj._response
after_event = AFTER_EVENTS[event_action]
request.registry.notify(after_event(**event_kwargs))

Expand Down
3 changes: 2 additions & 1 deletion nefertari/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ def view_mapper_wrapper(context, request):
raise JHTTPNotFound()

with trigger_events(view_obj):
return action(**matchdict)
view_obj._response = action(**matchdict)
return view_obj._response

return view_mapper_wrapper

Expand Down
5 changes: 3 additions & 2 deletions tests/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def test_trigger_events(self, mock_from):

mock_after.assert_called_once_with(
fields={'foo': 1}, model=view.Model, instance=ctx,
view=view)
view=view, response=view._response)
mock_before.assert_called_once_with(
fields={'foo': 1}, model=view.Model, instance=ctx,
view=view)
Expand Down Expand Up @@ -146,7 +146,8 @@ class A(object):
pass

mock_after.assert_called_once_with(
fields={'foo': 1}, model=view.Model, view=view)
fields={'foo': 1}, model=view.Model, view=view,
response=view._response)
mock_before.assert_called_once_with(
fields={'foo': 1}, model=view.Model, view=view)
view.request.registry.notify.assert_has_calls([
Expand Down
1 change: 1 addition & 0 deletions tests/test_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def test_viewmapper(self):

class MyView(object):
Model = Mock
_response = None

def __init__(self, ctx, req):
self._before_calls = {'index': [bc1], 'show': [bc3]}
Expand Down

0 comments on commit 0a66d41

Please sign in to comment.