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

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

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants