Skip to content

Add label/description decorator for "cleaner" code #115

New issue

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

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

Already on GitHub? # to your account

Closed
wolph opened this issue Jan 8, 2021 · 14 comments
Closed

Add label/description decorator for "cleaner" code #115

wolph opened this issue Jan 8, 2021 · 14 comments
Milestone

Comments

@wolph
Copy link
Contributor

wolph commented Jan 8, 2021

Perhaps it's something that only irks me, but I find that this syntax quickly becomes readable after the function goes beyond a few lines:

   def publish_this(self, request, obj):
       publish_obj(obj)
   publish_this.label = "Publish"  # optional
   publish_this.short_description = "Submit this article"  # optional

I'm currently using this little decorator to take care of the labels and description which works great:

def create_action(label=None, short_description=None):

    def _create_action(function):
        if label:
            function.label = label

        if short_description:
            function.short_description = short_description

        return function

    return _create_action

Usage is like this:

    @create_action('Publish', 'Submit this article')
    def publish_this(self, request, obj):
        publish_obj(obj)
@crccheck
Copy link
Owner

crccheck commented Jan 8, 2021

neat. It bugs me too but I was copying how a lot Django admin stuff does. I haven't checked out those docs in awhile though. I worry about "There should be one-- and preferably only one --obvious way to do it." from PEP 20

These assignments create a lot of annoying mypy errors too.

@crccheck
Copy link
Owner

crccheck commented Jan 8, 2021

if the Django admin has this pattern now then ya we should definitely do it!

@wolph
Copy link
Contributor Author

wolph commented Jan 8, 2021

With regards to the Zen of Python, I think Django has been lost from the beginning. It's filled with (meta) magic all over so there's no real clean way anymore.

A cleaner way to do it would have been similar to argparse: https://docs.python.org/3/library/argparse.html#example
So instead of having a list/tuple of actions, you would have something like:

actions = Actions()

@actions.add_action(label=label, ...)
def my_action(self, request, obj):
    ...

That would still work regular functions too if you wanted:

actions.add_action(label=label, ...)(some_function)

Or perhaps better:

actions.add_action(some_function, label=label, ...)

Note that I used keyword arguments for the label here so a simple version like this (without passing arguments to the decorator) would still work:

@actions.add_action
def my_action(self, request, obj):
    ...

Just a fyi, I'm Dutch so I should be good with PEP20 ;)

@wolph
Copy link
Contributor Author

wolph commented Jan 8, 2021

It doesn't look like Django is doing something like this yet: https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display

I still see decade_born_in.short_description = ... in the documentation. But a universal decorator could be made easily:

def set_attributes(**kwargs):
    def _set_attributes(function):
        for key, value in kwargs.items():
            setattr(function, key, value)
        return function
    return _set_attributes

@crccheck
Copy link
Owner

Great thoughts @wolph. It sounds like a universal-ish decorator would be a better way to solve this than to scope it to just this package.

@wolph
Copy link
Contributor Author

wolph commented Jan 11, 2021

That's fair I guess, I'll add it to my Django Utils library in that case: https://pypi.org/project/django-utils2/

@wolph
Copy link
Contributor Author

wolph commented Jan 15, 2021

Well... great minds think alike. It seems that the Django development release has this feature: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.display

@wolph
Copy link
Contributor Author

wolph commented Jan 15, 2021

While we're still stuck with older Django versions, the python-utils package now has this included. This is a pure-python package I maintain which is available through the repo in most BSD/Linux distributions.

https://python-utils.readthedocs.io/en/latest/python_utils.html#python_utils.decorators.set_attributes

@alfonsrv
Copy link

Well... great minds think alike. It seems that the Django development release has this feature: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.display

Unfortunately this decorator cannot be used with django-object-actions. @admin.display(description='Test') doesn't work and @admin.display(label='Test') raises an exception.

@crccheck
Copy link
Owner

crccheck commented Mar 29, 2022

Interesting! I'll look into seeing what it'll take to get it to work... one day. I made this issue bigger so it stands out more

@crccheck crccheck added this to the 4.0 milestone Mar 29, 2022
@crccheck crccheck pinned this issue Mar 29, 2022
@odigity
Copy link

odigity commented May 25, 2022

Just wanted to add my support - now that Django has an @admin.display() decorator for "admin actions", it sure would be nice if django-object-actions offered a similar decorator for object actions. Would look better / more consistent.

@alfonsrv
Copy link

New release on pypi?

@crccheck
Copy link
Owner

There was some sort of cleanup thing I was going to do before a release but now I can't remember. So I'll just hit the button to release!

@crccheck
Copy link
Owner

Well the CI job is broken, but I was able to publish it manually https://pypi.org/project/django-object-actions/4.1.0/

@crccheck crccheck unpinned this issue Nov 18, 2022
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants