Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Admin Actions not working #39

Open
techdragon opened this issue Apr 12, 2013 · 3 comments
Open

Admin Actions not working #39

techdragon opened this issue Apr 12, 2013 · 3 comments

Comments

@techdragon
Copy link
Contributor

Admin actions fail to execute correctly when run from the state object list view.

Im not able to tell how to fix this or Id be posting a pull request. But either its broken in 1.5 or we need some more documentation on how to use the admin functions so i can see where I went wrong implementing this.

I've followed the instructions as far as settign up the admin.py goes, heres the reveleant portions from my admin.py

class ResourceOfferLegalAgreementAdmin(admin.ModelAdmin):
    import pdb; pdb.set_trace()
    actions = ResourceOfferLegalAgreement.Machine.get_admin_actions()

admin.site.register(
    ResourceOfferLegalAgreement,
    ResourceOfferLegalAgreementAdmin
)

This is the section of machine.py that is breaking and driving me nuts. Ive spent 3 days going over this section of code trying to work out what I have done wrong or what is broken.

    @classmethod
    def get_admin_actions(cls, field_name='state'):
        """
        Creates a list of actions for use in the Django Admin.
        """
        actions = []

        def create_action(transition_name):
            def action(modeladmin, request, queryset):
                # Dry run first
                for o in queryset:
                    get_STATE_info = getattr(o, 'get_%s_info' % field_name)
                    try:
                        get_STATE_info.test_transition(transition_name, request.user)
                    except TransitionException, e:
                        modeladmin.message_user(request, 'ERROR: %s on: %s' % (e.message, unicode(o)))
                        return

                # Make actual transitions
                for o in queryset:
                    get_STATE_info = getattr(o, 'get_%s_info' % field_name)
                    get_STATE_info.make_transition(transition_name, request.user)

                # Feeback
                modeladmin.message_user(request, 'State changed for %s objects.' % len(queryset))

            action.short_description = unicode(cls.transitions[transition_name])
            action.__name__ = 'state_transition_%s' % transition_name
            return action

        for t in cls.transitions.keys():
            actions.append(create_action(t))

        return actions

When I set some pdb breakpoints and walk through the sequence of events when trying to perform an admin action i get the following chain of events. It starts with the line

for o in queryset:

after the comment "# Dry run first"

I step down through the execution and test repeatedly at each stage for the ability to perform *var.test_transition on any variables at that level of the stack. Then after reaching the line that causes the stack dump I step the debugger through a few more lines of generic django 1.5 code before telling the debugger to continue which as it has passed through all my set breakpoints, causes it to execute & print out the Traceback you see at the end of the PDB session.

> /Users/me/Dev/mydjangoproject/backend/prj/django_states/machine.py(250)action()
-> for o in queryset:
(Pdb) queryset[0]
<ResourceOfferLegalAgreement: State: proposed (The legal agreement has been proposed to both parties.)>
(Pdb) temp = queryset[0]
(Pdb) dir(temp)
['DoesNotExist', 'Machine', 'Meta', 'MultipleObjectsReturned', '__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__metaclass__', u'__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__unicode__', '__weakref__', '_base_manager', '_default_manager', '_deferred', '_get_FIELD_display', '_get_next_or_previous_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val', '_get_unique_checks', '_meta', '_perform_date_checks', '_perform_unique_checks', '_set_pk_val', '_state', '_state_log_model', 'can_make_transition', 'clean', 'clean_fields', 'date_error_message', 'delete', 'full_clean', 'get_public_state_transitions', 'get_state_choices', 'get_state_display', 'get_state_info', 'get_state_machine', 'get_state_model_name', 'get_state_transitions', 'id', 'is_initial_state', 'make_transition', 'objects', 'offeringUser', 'offeringUserAgreesToTerms', 'offeringUser_id', 'pk', 'possible_transitions', 'prepare_database_save', 'projectRepresentative', 'projectRepresentativeAgreesToTerms', 'projectRepresentative_id', 'public_transitions', 'resourceoffer_set', 'save', 'save_base', 'serializable_value', 'state', 'state_description', 'state_history', 'state_transitions', 'test_transition', 'unique_error_message', 'validate_unique']
(Pdb) temp.state_description()
*** TypeError: 'unicode' object is not callable
(Pdb) temp.state_description
u'The legal agreement has been proposed to both parties.'
(Pdb) temp.state_transitions
[]
(Pdb) temp.state
u'proposed'
(Pdb) temp.save
<bound method ResourceOfferLegalAgreement.new_save of <ResourceOfferLegalAgreement: State: proposed (The legal agreement has been proposed to both parties.)>>
(Pdb) temp
<ResourceOfferLegalAgreement: State: proposed (The legal agreement has been proposed to both parties.)>
(Pdb) temp.possible_transitions
<generator object possible_transitions at 0x108cfe370>
(Pdb) [x.get_name() for x in temp.possible_transitions]
['proposal_acceptance']
(Pdb) temp.test_transition
<bound method ResourceOfferLegalAgreement.test_transition of <ResourceOfferLegalAgreement: State: proposed (The legal agreement has been proposed to both parties.)>>
(Pdb) s
--Call--
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/db/models/query.py(97)__iter__()
-> def __iter__(self):
(Pdb) r
--Return--
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/db/models/query.py(108)__iter__()-><generat...08cfe820>
-> return self._result_iter()
(Pdb) r
> /Users/me/Dev/mydjangoproject/backend/prj/django_states/machine.py(251)action()
-> get_STATE_info = getattr(o, 'get_%s_info' % field_name)
(Pdb) print o
State: proposed (The legal agreement has been proposed to both parties.)
(Pdb) o.test_transition
<bound method ResourceOfferLegalAgreement.test_transition of <ResourceOfferLegalAgreement: State: proposed (The legal agreement has been proposed to both parties.)>>
(Pdb) o.possible_transitions
<generator object possible_transitions at 0x108cfe2d0>
(Pdb) s
> /Users/me/Dev/mydjangoproject/backend/prj/django_states/machine.py(252)action()
-> pdb.set_trace()
(Pdb) 
--Call--
> /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pdb.py(1250)set_trace()
-> def set_trace():
(Pdb) r
--Return--
> /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pdb.py(1251)set_trace()->None
-> Pdb().set_trace(sys._getframe().f_back)
(Pdb) r
> /Users/me/Dev/mydjangoproject/backend/prj/django_states/machine.py(253)action()
-> try:
(Pdb) s
> /Users/me/Dev/mydjangoproject/backend/prj/django_states/machine.py(254)action()
-> pdb.set_trace()
(Pdb) s
--Call--
> /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pdb.py(1250)set_trace()
-> def set_trace():
(Pdb) r
--Return--
> /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pdb.py(1251)set_trace()->None
-> Pdb().set_trace(sys._getframe().f_back)
(Pdb) r
> /Users/me/Dev/mydjangoproject/backend/prj/django_states/machine.py(255)action()
-> get_STATE_info.test_transition(transition_name, request.user)
(Pdb) print get_STATE_info
<bound method ResourceOfferLegalAgreement._curried of <ResourceOfferLegalAgreement: State: proposed (The legal agreement has been proposed to both parties.)>>
(Pdb) print request.user
root
(Pdb) print transition_name
proposal_acceptance
(Pdb) print get_STATE_info.test_transition(transition_name, request.user)
*** AttributeError: 'function' object has no attribute 'test_transition'
(Pdb) print get_STATE_info.test_transition()
*** AttributeError: 'function' object has no attribute 'test_transition'
(Pdb) print get_STATE_info.test_transition()
*** AttributeError: 'function' object has no attribute 'test_transition'
(Pdb) s
AttributeError: "'function' object has no attribute 'test_transition'"
> /Users/me/Dev/mydjangoproject/backend/prj/django_states/machine.py(255)action()
-> get_STATE_info.test_transition(transition_name, request.user)
(Pdb) s
> /Users/me/Dev/mydjangoproject/backend/prj/django_states/machine.py(256)action()
-> except TransitionException, e:
(Pdb) s
--Call--
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/db/models/query.py(118)_result_iter()
-> yield self._result_cache[pos]
(Pdb) s
GeneratorExit: None
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/db/models/query.py(118)_result_iter()
-> yield self._result_cache[pos]
(Pdb) r
--Return--
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/db/models/query.py(118)_result_iter()->None
-> yield self._result_cache[pos]
(Pdb) r
--Return--
> /Users/me/Dev/mydjangoproject/backend/prj/django_states/machine.py(256)action()->None
-> except TransitionException, e:
(Pdb) s
AttributeError: Attribut...ition'",)
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/contrib/admin/options.py(960)response_action()
-> response = func(self, request, queryset)
(Pdb) s
--Return--
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/contrib/admin/options.py(960)response_action()->None
-> response = func(self, request, queryset)
(Pdb) s
AttributeError: Attribut...ition'",)
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/contrib/admin/options.py(1205)changelist_view()
-> response = self.response_action(request, queryset=cl.get_query_set(request))
(Pdb) r
--Return--
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/contrib/admin/options.py(1205)changelist_view()->None
-> response = self.response_action(request, queryset=cl.get_query_set(request))
(Pdb) r
AttributeError: Attribut...ition'",)
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/utils/decorators.py(21)bound_func()
-> return func(self, *args2, **kwargs2)
(Pdb) r
--Return--
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/utils/decorators.py(21)bound_func()->None
-> return func(self, *args2, **kwargs2)
(Pdb) 
AttributeError: Attribut...ition'",)
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/utils/decorators.py(91)_wrapped_view()
-> response = view_func(request, *args, **kwargs)
(Pdb) 
--Return--
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/utils/decorators.py(97)_wrapped_view()->None
-> raise
(Pdb) 
AttributeError: Attribut...ition'",)
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/utils/decorators.py(25)_wrapper()
-> return bound_func(*args, **kwargs)
(Pdb) 
--Return--
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/utils/decorators.py(25)_wrapper()->None
-> return bound_func(*args, **kwargs)
(Pdb)
AttributeError: Attribut...ition'",)
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/contrib/admin/sites.py(202)inner()
-> return view(request, *args, **kwargs)
(Pdb)
--Return--
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/contrib/admin/sites.py(202)inner()->None
-> return view(request, *args, **kwargs)
(Pdb)
AttributeError: Attribut...ition'",)
> /Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/views/decorators/cache.py(89)_wrapped_view_func()
-> response = view_func(request, *args, **kwargs)
(Pdb) c
ERROR:base:handle_uncaught_exception:212: Internal Server Error: /admin/resources/resourceofferlegalagreement/
Traceback (most recent call last):
File "/Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/core/handlers/base.py", line 115, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "/Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/contrib/admin/options.py", line 372, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/utils/decorators.py", line 91, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/views/decorators/cache.py", line 89, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/contrib/admin/sites.py", line 202, in inner
return view(request, *args, **kwargs)
File "/Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/utils/decorators.py", line 25, in _wrapper
return bound_func(*args, **kwargs)
File "/Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/utils/decorators.py", line 91, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/utils/decorators.py", line 21, in bound_func
return func(self, *args2, **kwargs2)
File "/Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/contrib/admin/options.py", line 1205, in changelist_view
response = self.response_action(request, queryset=cl.get_query_set(request))
File "/Users/me/.virtualenvs/site1env/lib/python2.7/site-packages/django/contrib/admin/options.py", line 960, in response_action
response = func(self, request, queryset)
File "/Users/me/Dev/mydjangoproject/backend/prj/django_states/machine.py", line 255, in action
get_STATE_info.test_transition(transition_name, request.user)
AttributeError: 'function' object has no attribute 'test_transition'
@iV1n5
Copy link

iV1n5 commented May 7, 2013

I have the same problem. I solved it by changing:

get_STATE_info.test_transition(transition_name, request.user)

to

get_STATE_info().test_transition(transition_name, request.user)

Any thoughts?

@iV1n5
Copy link

iV1n5 commented May 7, 2013

get_STATE_info is a function, so it should be called with the brakets like get_STATE_info(). The same thing happen in the Make actual transitions loop

@jpadilla
Copy link
Contributor

jpadilla commented Mar 6, 2015

This is fixed by #65

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants