django-admin-easy
=================
Collection of admin fields, decorators and mixin to help to create computed or custom fields more friendly and easy way
.. image:: https://img.shields.io/badge/django-2.x%203.x%204.x%205.0%205.1-brightgreen.svg
:target: http://pypi.python.org/pypi/django-admin-easy
.. image:: https://img.shields.io/pypi/v/django-admin-easy.svg?style=flat
:target: http://pypi.python.org/pypi/django-admin-easy
.. image:: https://img.shields.io/pypi/pyversions/django-admin-easy.svg?maxAge=2592000
:target: http://pypi.python.org/pypi/django-admin-easy
.. image:: https://img.shields.io/pypi/format/django-admin-easy.svg?maxAge=2592000
:target: http://pypi.python.org/pypi/django-admin-easy
.. image:: https://img.shields.io/pypi/status/django-admin-easy.svg?maxAge=2592000
:target: http://pypi.python.org/pypi/django-admin-easy
.. image:: https://github.com/ebertti/django-admin-easy/actions/workflows/test.yml/badge.svg?maxAge=2592000
:target: https://github.com/ebertti/django-admin-easy/actions/workflows/test.yml
.. image:: https://img.shields.io/coveralls/ebertti/django-admin-easy/master.svg?maxAge=2592000
:target: https://coveralls.io/r/ebertti/django-admin-easy?branch=master
Installation
------------
1. Requirements: **Django > 3** and **Python > 3**
``pip install django-admin-easy==0.8.0``
* For **Django < 1.8** or **Python 2.x**
``pip install django-admin-easy==0.4.1``
* For **Django < 2**
``pip install django-admin-easy==0.7.0``
How it Works
------------
When you want to display a field on Django Admin, and this field doesn't exist in your Model
or you need to compute some information, like a Image or Link, you will need to create a method on your ModelAdminClass like this:
.. code-block:: python
from django.contrib import admin
class YourAdmin(admin.ModelAdmin):
fields = ('sum_method', 'some_img', 'is_true')
def sum_method(self, obj):
sum_result = obj.field1 + obj.field2 + obj.field3
return '<b>%s</b>' % sum_result
sum_method.short_description = 'Sum'
sum_method.admin_order_field = 'field1'
sum_method.allow_tags = True
def some_img(self, obj):
return '<img scr="%s">' % obj.image
some_img.short_description = 'image'
some_img.admin_order_field = 'id'
some_img.allow_tags = True
def is_true(self, obj):
return obj.value > 0
is_true.short_description = 'Positive'
is_true.admin_order_field = 'value'
is_true.boolean = True
It takes too much lines! =D
With **django-admin-easy** you can easily create this field with less lines:
.. code-block:: python
from django.contrib import admin
import easy
class YourAdmin(admin.ModelAdmin):
fields = ('sum_method', 'some_img', 'is_true')
sum_method = easy.SimpleAdminField(lambda obj: '<b>%s</b>' % (obj.field1 + obj.field2 + obj.field3), 'Sum', 'field1', True)
some_img = easy.ImageAdminField('image', 'id')
is_true = easy.BooleanAdminField('Positive', 'value')
If you still prefer using a custom method, you can use our decorators, like this:
.. code-block:: python
from django.contrib import admin
import easy
class YourAdmin(admin.ModelAdmin):
fields = ('sum_method', 'some_img', 'is_true')
@easy.smart(short_description='Sum', admin_order_field='field1', allow_tags=True )
def sum_method(self, obj):
sum_result = obj.field1 + obj.field2 + obj.field3
return '<b>%s</b>' % sum_result
@easy.short(desc='image', order='id', tags=True)
def some_img(self, obj):
return '<img scr="%s">' % obj.image
@easy.short(desc='Positive', order='value', bool=True)
def is_true(self, obj):
return obj.value > 0
Another Decorators
------------------
In all of this extra decorators, you can use `short` or `smart` arguments to complement field information.
* **Allow HTML tags**
.. code-block:: python
@easy.with_tags()
def some_field_with_html(self, obj):
return '<b>{}</b>'.format(obj.value)
# output some as: mark_safe("<b>something</b>")
if value is `5`, will display:
**5** and not `<b>5</b>` on admin page.
* **Cached field**
If you, for some reason, need to cache a custom field on admin
.. code-block:: python
@easy.cache(10)# in secondd, default is 60
def some_field_with_html(self, obj):
return obj.related.some_hard_word()
If you change something on your model, or some related object, you can clean this cache using this easy way:
.. code-block:: python
import easy
# wherever you want
easy.cache_clear(my_model_instance)
# or
class MyModel(models.Model):
# ... fields
def save(*args, **kwargs):
easy.cache_clear(self)
super(MyModel, self).save(*args, **kwargs)
* **Django template filter**
Can be used with all template filters on your project.
.. code-block:: python
# builtin template filter like {{ value|title }}
@easy.filter('title')
def some_field_with_html(self, obj):
return 'ezequiel bertti'
# output: "Ezequiel Bertti"
# like {% load i10n %} and {{ value|localize }}
@easy.filter('localize', 'l10n')
def some_field_with_html(self, obj):
return 10000
# output: "10.000"
# like {{ value|date:'y-m-d' }}
@easy.filter('date', 'default', 'y-m-d')
def some_field_with_html(self, obj):
return datetime(2016, 06, 28)
# output: "16-06-28"
* **Django utils functions**
Tested with:
.. code-block:: python
@easy.utils('html.escape')
@easy.utils('html.conditional_escape')
@easy.utils('html.strip_tags')
@easy.utils('safestring.mark_safe')
@easy.utils('safestring.mark_for_escaping')
@easy.utils('text.slugify')
@easy.utils('translation.gettext')
@easy.utils('translation.ugettext')
@easy.utils('translation.gettext_lazy')
@easy.utils('translation.ugettext_lazy')
@easy.utils('translation.gettext_noop')
@easy.utils('translation.ugettext_noop')
def your_method(self, obj):
return obj.value
More Examples
-------------
.. code-block:: python
from django.contrib import admin
import easy
class YourAdmin(admin.ModelAdmin):
list_fields = ('id', 'custom1', 'custom2', 'custom3' ... 'customN')
actions = ('simples_action',)
@easy.action('My Little Simple Magic Action')
def simple_action(self, request, queryset):
return queryset.update(magic=True)
# actoin only for user that has change permission on this model
@easy.action('Another Simple Magic Action', 'change')
def simple_action(self, request, queryset):
return queryset.update(magic=True)
# render a value of field, method, property or your model or related model
simple1 = easy.SimpleAdminField('model_field')
simple2 = easy.SimpleAdminField('method_of_model')
simple3 = easy.SimpleAdminField('related.attribute_or_method')
simple4 = easy.SimpleAdminField('related_set.count', 'count')
simple5 = easy.SimpleAdminField(lambda x: x.method(), 'show', 'order_by')
# render boolean fields
bool1 = easy.BooleanAdminField(lambda x: x.value > 10, 'high')
# render with string format fields
format1 = easy.FormatAdminField('{o.model_field} - {o.date_field:Y%-%m}', 'column name')
# render foreignkey with link to change_form in admin
fk1 = easy.ForeignKeyAdminField('related')
# render foreignkey with link to change_form in admin and related_id content as text
fk2 = easy.ForeignKeyAdminField('related', 'related_id')
# render foreignkey_id, like raw_id_fields, with link to change_form in admin and related_id content as text
# without extra queries or select_related to prevent extra n-1 queries
raw1 = easy.RawIdAdminField('related')
# render template
template1 = easy.TemplateAdminField('test.html', 'shorty description', 'order_field')
# render to change_list of another model with a filter on query
link1 = easy.LinkChangeListAdminField('app_label', 'model_name', 'attribute_to_text',
{'field_name':'dynamic_value_model'})
link2 = easy.LinkChangeListAdminField('app_label', 'model_name', 'attribute_to_text',
{'field_name':'dynamic_value_model'},
{'another_field': 'static_value'})
# render link to generic content type fields
# don't forget to use select_related with content-type to avoid N+1 queries like example below
generic = easy.GenericForeignKeyAdminField('generic')
def get_queryset(self, request):
qs = super().get_queryset(request)
return qs.select_related('content_type')
# or enable cache
generic = easy.GenericForeignKeyAdminField('generic', cache_content_type=True)
# display image of some model
image1 = easy.ImageAdminField('image', {'image_attrs':'attr_value'})
# use django template filter on a field
filter1 = easy.FilterAdminField('model_field', 'upper')
filter2 = easy.FilterAdminField('date_field', 'date', 'django', 'y-m-d')
filter3 = easy.FilterAdminField('float_field', 'localize', 'l18n')
@easy.smart(short_description='Field Description 12', admin_order_field='model_field')
def custom12(self, obj):
return obj.something_cool()
@easy.short(desc='Field Description 1', order='model_field', tags=True)
def decorator1(self, obj):
return '<b>' + obj.model_field + '</b>'
@easy.short(desc='Field Description 2', order='model_field', bool=True)
def decorator2(self, obj):
return obj.model_field > 10
If you want to use on admin form to show some information,
don't forget to add your custom field on ``readonly_fields`` attribute of your admin class
.. code-block:: python
from django.contrib import admin
import easy
class YourAdmin(admin.ModelAdmin):
fields = ('custom1', 'custom2', 'custom3' ... 'customN')
readonly_fields = ('custom1', 'custom2', 'custom3' ... 'customN')
custom1 = easy.ForeignKeyAdminField('related')
# ...
Another way to use is directly on ``list_fields`` declaration:
.. code-block:: python
from django.contrib import admin
import easy
class YourAdmin(admin.ModelAdmin):
list_fields = (
easy.TemplateAdminField('test.html', 'shorty description', 'order_field'),
easy.ImageAdminField('image', {'image_attrs':'attr_value'}),
# ...
)
# ...
Mixin
-----
To help you to create a custom view on django admin, we create the MixinEasyViews for your Admin Classes
.. code-block:: python
from django.contrib import admin
import easy
class MyModelAdmin(easy.MixinEasyViews, admin.ModelAdmin):
# ...
def easy_view_jump(self, request, pk=None):
# do something here
return HttpResponse('something')
To call this view, you can use this reverse:
.. code-block:: python
from django.core.urlresolvers import reverse
# to do something with one object of a model
reverse('admin:myapp_mymodel_easy', args=(obj.pk, 'jump'))
# or to do something with a model
reverse('admin:myapp_mymodel_easy', args=('jump',))
Or one HTML template
.. code-block:: html
#<!-- to do something with one object of a model -->
{% url 'admin:myapp_mymodel_easy' obj.pk 'jump' %}
#<!-- or to do something with a model -->
{% url 'admin:myapp_mymodel_easy' 'jump' %}
Utilities
---------
* Response for admin actions
Return for the change list and show some message for the user keeping or not the filters.
.. code-block:: python
from django.contrib import admin
from django.contrib import messages
import easy
class YourAdmin(admin.ModelAdmin):
# ...
actions = ('simples_action',)
def simples_action(self, request, queryset):
success = queryset.do_something()
if success:
return easy.action_response(request, 'Some success message for user', keep_querystring=False)
else:
return easy.action_response(request, 'Some error for user', messages.ERROR)
# or just redirect to changelist with filters
return easy.action_response()
So easy, no?
Screenshot
----------
Using example of poll of django tutorial
.. image:: https://raw.githubusercontent.com/ebertti/django-admin-easy/master/screenshot/more.png
.. image:: https://raw.githubusercontent.com/ebertti/django-admin-easy/master/screenshot/related.png
Please help us
--------------
This project is still under development. Feedback and suggestions are very welcome and I encourage you to use the `Issues list <http://github.com/ebertti/django-admin-easy/issues>`_ on Github to provide that feedback.
.. image:: https://img.shields.io/github/issues/ebertti/django-admin-easy.svg
:target: https://github.com/ebertti/django-admin-easy/issues
.. image:: https://img.shields.io/waffle/label/ebertti/django-admin-easy/in%20progress.svg?maxAge=2592000
:target: https://waffle.io/ebertti/django-admin-easy
.. image:: https://img.shields.io/github/forks/ebertti/django-admin-easy.svg
:target: https://github.com/ebertti/django-admin-easy/network
.. image:: https://img.shields.io/github/stars/ebertti/django-admin-easy.svg
:target: https://github.com/ebertti/django-admin-easy/stargazers
Authors
-------
The django-admin-easy was originally created by Ezequiel Bertti `@ebertti <https://github.com/ebertti>`_ October 2014.
Changelog
---------
* 0.8.0
Add new field GenericForeignKeyAdminField
Add Support for Django 5.0 and 5.1
Add Support for Python 3.12
Drop support for Django < 2.0
Add typing and docstring (thanks `codeium <https://codeium.com/>`_)
* 0.7.0
Add support for Django 4.0, 4.1 and 4.2
Add support for Python 3.10 and 3.11
Add Github Actions for testing
Add job to realease on pypi
Thanks @Lex98
* 0.6.1
Add support for Django 3.2 and Python 3.9
* 0.6
Add RawIdAdminField
* 0.5.1
Add permission on action decorator
* 0.4.1
Django 2.0
* 0.4
Django 1.11
Create module utils with action_response
* 0.3.2
Add params_static to LinkChangeListAdminField
* 0.3.1
Add FormatAdminField
* 0.3
Add import from `__future__` on all files
Django 1.10
More decorators
More admin fields
* 0.2.2
Add MixinEasyViews
* 0.2.1
Fix for Django 1.7 from `@kevgathuku <https://github.com/kevgathuku>`_
Star History
------------
.. image:: https://api.star-history.com/svg?repos=ebertti/django-admin-easy&type=Date
:target: https://star-history.com/#ebertti/django-admin-easy&Date
Raw data
{
"_id": null,
"home_page": "http://github.com/ebertti/django-admin-easy/",
"name": "django-admin-easy",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "admin field django easy simple",
"author": "Ezequiel Bertti",
"author_email": "ebertti@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/60/f6/afd4dd29819661b0a2612697a4a7d6fbe7c0f825bfd82846b2bedde4efc4/django_admin_easy-0.8.0.tar.gz",
"platform": "OS Independent",
"description": "django-admin-easy\n=================\n\nCollection of admin fields, decorators and mixin to help to create computed or custom fields more friendly and easy way\n\n\n\n.. image:: https://img.shields.io/badge/django-2.x%203.x%204.x%205.0%205.1-brightgreen.svg\n :target: http://pypi.python.org/pypi/django-admin-easy\n\n.. image:: https://img.shields.io/pypi/v/django-admin-easy.svg?style=flat\n :target: http://pypi.python.org/pypi/django-admin-easy\n\n.. image:: https://img.shields.io/pypi/pyversions/django-admin-easy.svg?maxAge=2592000\n :target: http://pypi.python.org/pypi/django-admin-easy\n\n.. image:: https://img.shields.io/pypi/format/django-admin-easy.svg?maxAge=2592000\n :target: http://pypi.python.org/pypi/django-admin-easy\n\n.. image:: https://img.shields.io/pypi/status/django-admin-easy.svg?maxAge=2592000\n :target: http://pypi.python.org/pypi/django-admin-easy\n\n.. image:: https://github.com/ebertti/django-admin-easy/actions/workflows/test.yml/badge.svg?maxAge=2592000\n :target: https://github.com/ebertti/django-admin-easy/actions/workflows/test.yml\n\n.. image:: https://img.shields.io/coveralls/ebertti/django-admin-easy/master.svg?maxAge=2592000\n :target: https://coveralls.io/r/ebertti/django-admin-easy?branch=master\n\n\nInstallation\n------------\n\n1. Requirements: **Django > 3** and **Python > 3**\n\n ``pip install django-admin-easy==0.8.0``\n\n\n* For **Django < 1.8** or **Python 2.x**\n\n ``pip install django-admin-easy==0.4.1``\n\n* For **Django < 2**\n\n ``pip install django-admin-easy==0.7.0``\n\n\nHow it Works\n------------\n\nWhen you want to display a field on Django Admin, and this field doesn't exist in your Model\nor you need to compute some information, like a Image or Link, you will need to create a method on your ModelAdminClass like this:\n\n.. code-block:: python\n\n from django.contrib import admin\n\n class YourAdmin(admin.ModelAdmin):\n fields = ('sum_method', 'some_img', 'is_true')\n\n def sum_method(self, obj):\n sum_result = obj.field1 + obj.field2 + obj.field3\n return '<b>%s</b>' % sum_result\n sum_method.short_description = 'Sum'\n sum_method.admin_order_field = 'field1'\n sum_method.allow_tags = True\n\n def some_img(self, obj):\n return '<img scr=\"%s\">' % obj.image\n some_img.short_description = 'image'\n some_img.admin_order_field = 'id'\n some_img.allow_tags = True\n\n def is_true(self, obj):\n return obj.value > 0\n is_true.short_description = 'Positive'\n is_true.admin_order_field = 'value'\n is_true.boolean = True\n\nIt takes too much lines! =D\n\nWith **django-admin-easy** you can easily create this field with less lines:\n\n.. code-block:: python\n\n from django.contrib import admin\n import easy\n\n class YourAdmin(admin.ModelAdmin):\n fields = ('sum_method', 'some_img', 'is_true')\n\n sum_method = easy.SimpleAdminField(lambda obj: '<b>%s</b>' % (obj.field1 + obj.field2 + obj.field3), 'Sum', 'field1', True)\n some_img = easy.ImageAdminField('image', 'id')\n is_true = easy.BooleanAdminField('Positive', 'value')\n\nIf you still prefer using a custom method, you can use our decorators, like this:\n\n.. code-block:: python\n\n from django.contrib import admin\n import easy\n\n class YourAdmin(admin.ModelAdmin):\n fields = ('sum_method', 'some_img', 'is_true')\n\n @easy.smart(short_description='Sum', admin_order_field='field1', allow_tags=True )\n def sum_method(self, obj):\n sum_result = obj.field1 + obj.field2 + obj.field3\n return '<b>%s</b>' % sum_result\n\n @easy.short(desc='image', order='id', tags=True)\n def some_img(self, obj):\n return '<img scr=\"%s\">' % obj.image\n\n @easy.short(desc='Positive', order='value', bool=True)\n def is_true(self, obj):\n return obj.value > 0\n\nAnother Decorators\n------------------\n\nIn all of this extra decorators, you can use `short` or `smart` arguments to complement field information.\n\n* **Allow HTML tags**\n\n.. code-block:: python\n\n @easy.with_tags()\n def some_field_with_html(self, obj):\n return '<b>{}</b>'.format(obj.value)\n # output some as: mark_safe(\"<b>something</b>\")\n\n\nif value is `5`, will display:\n\n**5** and not `<b>5</b>` on admin page.\n\n* **Cached field**\n\nIf you, for some reason, need to cache a custom field on admin\n\n.. code-block:: python\n\n @easy.cache(10)# in secondd, default is 60\n def some_field_with_html(self, obj):\n return obj.related.some_hard_word()\n\nIf you change something on your model, or some related object, you can clean this cache using this easy way:\n\n.. code-block:: python\n\n import easy\n # wherever you want\n easy.cache_clear(my_model_instance)\n\n # or\n class MyModel(models.Model):\n # ... fields\n\n def save(*args, **kwargs):\n easy.cache_clear(self)\n super(MyModel, self).save(*args, **kwargs)\n\n\n* **Django template filter**\n\nCan be used with all template filters on your project.\n\n.. code-block:: python\n\n # builtin template filter like {{ value|title }}\n @easy.filter('title')\n def some_field_with_html(self, obj):\n return 'ezequiel bertti'\n # output: \"Ezequiel Bertti\"\n\n # like {% load i10n %} and {{ value|localize }}\n @easy.filter('localize', 'l10n')\n def some_field_with_html(self, obj):\n return 10000\n # output: \"10.000\"\n\n # like {{ value|date:'y-m-d' }}\n @easy.filter('date', 'default', 'y-m-d')\n def some_field_with_html(self, obj):\n return datetime(2016, 06, 28)\n # output: \"16-06-28\"\n\n* **Django utils functions**\n\nTested with:\n\n.. code-block:: python\n\n @easy.utils('html.escape')\n @easy.utils('html.conditional_escape')\n @easy.utils('html.strip_tags')\n @easy.utils('safestring.mark_safe')\n @easy.utils('safestring.mark_for_escaping')\n @easy.utils('text.slugify')\n @easy.utils('translation.gettext')\n @easy.utils('translation.ugettext')\n @easy.utils('translation.gettext_lazy')\n @easy.utils('translation.ugettext_lazy')\n @easy.utils('translation.gettext_noop')\n @easy.utils('translation.ugettext_noop')\n def your_method(self, obj):\n return obj.value\n\nMore Examples\n-------------\n\n.. code-block:: python\n\n from django.contrib import admin\n import easy\n\n class YourAdmin(admin.ModelAdmin):\n list_fields = ('id', 'custom1', 'custom2', 'custom3' ... 'customN')\n\n actions = ('simples_action',)\n\n @easy.action('My Little Simple Magic Action')\n def simple_action(self, request, queryset):\n return queryset.update(magic=True)\n\n # actoin only for user that has change permission on this model\n @easy.action('Another Simple Magic Action', 'change')\n def simple_action(self, request, queryset):\n return queryset.update(magic=True)\n\n\n # render a value of field, method, property or your model or related model\n simple1 = easy.SimpleAdminField('model_field')\n simple2 = easy.SimpleAdminField('method_of_model')\n simple3 = easy.SimpleAdminField('related.attribute_or_method')\n simple4 = easy.SimpleAdminField('related_set.count', 'count')\n simple5 = easy.SimpleAdminField(lambda x: x.method(), 'show', 'order_by')\n\n # render boolean fields\n bool1 = easy.BooleanAdminField(lambda x: x.value > 10, 'high')\n\n # render with string format fields\n format1 = easy.FormatAdminField('{o.model_field} - {o.date_field:Y%-%m}', 'column name')\n\n # render foreignkey with link to change_form in admin\n fk1 = easy.ForeignKeyAdminField('related')\n\n # render foreignkey with link to change_form in admin and related_id content as text\n fk2 = easy.ForeignKeyAdminField('related', 'related_id')\n\n # render foreignkey_id, like raw_id_fields, with link to change_form in admin and related_id content as text\n # without extra queries or select_related to prevent extra n-1 queries\n raw1 = easy.RawIdAdminField('related')\n\n # render template\n template1 = easy.TemplateAdminField('test.html', 'shorty description', 'order_field')\n\n # render to change_list of another model with a filter on query\n link1 = easy.LinkChangeListAdminField('app_label', 'model_name', 'attribute_to_text',\n {'field_name':'dynamic_value_model'})\n\n link2 = easy.LinkChangeListAdminField('app_label', 'model_name', 'attribute_to_text',\n {'field_name':'dynamic_value_model'},\n {'another_field': 'static_value'})\n\n # render link to generic content type fields\n # don't forget to use select_related with content-type to avoid N+1 queries like example below\n generic = easy.GenericForeignKeyAdminField('generic')\n\n def get_queryset(self, request):\n qs = super().get_queryset(request)\n\n return qs.select_related('content_type')\n\n # or enable cache\n generic = easy.GenericForeignKeyAdminField('generic', cache_content_type=True)\n\n # display image of some model\n image1 = easy.ImageAdminField('image', {'image_attrs':'attr_value'})\n\n # use django template filter on a field\n filter1 = easy.FilterAdminField('model_field', 'upper')\n filter2 = easy.FilterAdminField('date_field', 'date', 'django', 'y-m-d')\n filter3 = easy.FilterAdminField('float_field', 'localize', 'l18n')\n\n @easy.smart(short_description='Field Description 12', admin_order_field='model_field')\n def custom12(self, obj):\n return obj.something_cool()\n\n @easy.short(desc='Field Description 1', order='model_field', tags=True)\n def decorator1(self, obj):\n return '<b>' + obj.model_field + '</b>'\n\n @easy.short(desc='Field Description 2', order='model_field', bool=True)\n def decorator2(self, obj):\n return obj.model_field > 10\n\n\nIf you want to use on admin form to show some information,\ndon't forget to add your custom field on ``readonly_fields`` attribute of your admin class\n\n.. code-block:: python\n\n from django.contrib import admin\n import easy\n\n class YourAdmin(admin.ModelAdmin):\n fields = ('custom1', 'custom2', 'custom3' ... 'customN')\n readonly_fields = ('custom1', 'custom2', 'custom3' ... 'customN')\n\n custom1 = easy.ForeignKeyAdminField('related')\n # ...\n\nAnother way to use is directly on ``list_fields`` declaration:\n\n.. code-block:: python\n\n from django.contrib import admin\n import easy\n\n class YourAdmin(admin.ModelAdmin):\n list_fields = (\n easy.TemplateAdminField('test.html', 'shorty description', 'order_field'),\n easy.ImageAdminField('image', {'image_attrs':'attr_value'}),\n # ...\n )\n\n # ...\n\nMixin\n-----\n\nTo help you to create a custom view on django admin, we create the MixinEasyViews for your Admin Classes\n\n.. code-block:: python\n\n from django.contrib import admin\n import easy\n\n class MyModelAdmin(easy.MixinEasyViews, admin.ModelAdmin):\n # ...\n\n def easy_view_jump(self, request, pk=None):\n # do something here\n return HttpResponse('something')\n\nTo call this view, you can use this reverse:\n\n.. code-block:: python\n\n from django.core.urlresolvers import reverse\n\n # to do something with one object of a model\n reverse('admin:myapp_mymodel_easy', args=(obj.pk, 'jump'))\n\n # or to do something with a model\n reverse('admin:myapp_mymodel_easy', args=('jump',))\n\nOr one HTML template\n\n.. code-block:: html\n\n #<!-- to do something with one object of a model -->\n {% url 'admin:myapp_mymodel_easy' obj.pk 'jump' %}\n\n #<!-- or to do something with a model -->\n {% url 'admin:myapp_mymodel_easy' 'jump' %}\n\nUtilities\n---------\n\n* Response for admin actions\n\n Return for the change list and show some message for the user keeping or not the filters.\n\n.. code-block:: python\n\n from django.contrib import admin\n from django.contrib import messages\n import easy\n\n class YourAdmin(admin.ModelAdmin):\n # ...\n actions = ('simples_action',)\n\n def simples_action(self, request, queryset):\n\n success = queryset.do_something()\n if success:\n return easy.action_response(request, 'Some success message for user', keep_querystring=False)\n else:\n return easy.action_response(request, 'Some error for user', messages.ERROR)\n\n # or just redirect to changelist with filters\n return easy.action_response()\n\nSo easy, no?\n\nScreenshot\n----------\n\nUsing example of poll of django tutorial\n\n.. image:: https://raw.githubusercontent.com/ebertti/django-admin-easy/master/screenshot/more.png\n\n.. image:: https://raw.githubusercontent.com/ebertti/django-admin-easy/master/screenshot/related.png\n\nPlease help us\n--------------\nThis project is still under development. Feedback and suggestions are very welcome and I encourage you to use the `Issues list <http://github.com/ebertti/django-admin-easy/issues>`_ on Github to provide that feedback.\n\n.. image:: https://img.shields.io/github/issues/ebertti/django-admin-easy.svg\n :target: https://github.com/ebertti/django-admin-easy/issues\n\n.. image:: https://img.shields.io/waffle/label/ebertti/django-admin-easy/in%20progress.svg?maxAge=2592000\n :target: https://waffle.io/ebertti/django-admin-easy\n\n.. image:: https://img.shields.io/github/forks/ebertti/django-admin-easy.svg\n :target: https://github.com/ebertti/django-admin-easy/network\n\n.. image:: https://img.shields.io/github/stars/ebertti/django-admin-easy.svg\n :target: https://github.com/ebertti/django-admin-easy/stargazers\n\nAuthors\n-------\nThe django-admin-easy was originally created by Ezequiel Bertti `@ebertti <https://github.com/ebertti>`_ October 2014.\n\nChangelog\n---------\n* 0.8.0\n\n Add new field GenericForeignKeyAdminField\n Add Support for Django 5.0 and 5.1\n Add Support for Python 3.12\n Drop support for Django < 2.0\n Add typing and docstring (thanks `codeium <https://codeium.com/>`_)\n\n* 0.7.0\n\n Add support for Django 4.0, 4.1 and 4.2\n Add support for Python 3.10 and 3.11\n Add Github Actions for testing\n Add job to realease on pypi\n Thanks @Lex98\n\n* 0.6.1\n\n Add support for Django 3.2 and Python 3.9\n\n* 0.6\n\n Add RawIdAdminField\n\n* 0.5.1\n\n Add permission on action decorator\n\n* 0.4.1\n\n Django 2.0\n\n* 0.4\n\n Django 1.11\n Create module utils with action_response\n\n* 0.3.2\n\n Add params_static to LinkChangeListAdminField\n\n* 0.3.1\n\n Add FormatAdminField\n\n* 0.3\n\n Add import from `__future__` on all files\n Django 1.10\n More decorators\n More admin fields\n\n* 0.2.2\n\n Add MixinEasyViews\n\n* 0.2.1\n\n Fix for Django 1.7 from `@kevgathuku <https://github.com/kevgathuku>`_\n\n\nStar History\n------------\n\n.. image:: https://api.star-history.com/svg?repos=ebertti/django-admin-easy&type=Date\n :target: https://star-history.com/#ebertti/django-admin-easy&Date\n",
"bugtrack_url": null,
"license": "MIT License",
"summary": "Collection of admin fields and decorators to help to create computed or custom fields more friendly and easy way",
"version": "0.8.0",
"project_urls": {
"Homepage": "http://github.com/ebertti/django-admin-easy/"
},
"split_keywords": [
"admin",
"field",
"django",
"easy",
"simple"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "695b377b27878671c013b025dd14e733709ac8529ba1f903395d093036f29147",
"md5": "96450e774b1d4abb0093068630a85f91",
"sha256": "fb213f0c2eae5c3cb710e607e37e92352a41dc0d6b0cf5b4c244a3bd13d280d3"
},
"downloads": -1,
"filename": "django_admin_easy-0.8.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "96450e774b1d4abb0093068630a85f91",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 19022,
"upload_time": "2024-08-28T02:28:52",
"upload_time_iso_8601": "2024-08-28T02:28:52.982210Z",
"url": "https://files.pythonhosted.org/packages/69/5b/377b27878671c013b025dd14e733709ac8529ba1f903395d093036f29147/django_admin_easy-0.8.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "60f6afd4dd29819661b0a2612697a4a7d6fbe7c0f825bfd82846b2bedde4efc4",
"md5": "197501f4f66636d50a4e42f23bf94468",
"sha256": "f12128df4d9f3d84a1fb0f2f8fd68641add776161761db695329362de1878bad"
},
"downloads": -1,
"filename": "django_admin_easy-0.8.0.tar.gz",
"has_sig": false,
"md5_digest": "197501f4f66636d50a4e42f23bf94468",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 16896,
"upload_time": "2024-08-28T02:28:54",
"upload_time_iso_8601": "2024-08-28T02:28:54.596643Z",
"url": "https://files.pythonhosted.org/packages/60/f6/afd4dd29819661b0a2612697a4a7d6fbe7c0f825bfd82846b2bedde4efc4/django_admin_easy-0.8.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-08-28 02:28:54",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "ebertti",
"github_project": "django-admin-easy",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "model-bakery",
"specs": []
},
{
"name": "Sphinx",
"specs": []
},
{
"name": "Pillow",
"specs": []
},
{
"name": "tox",
"specs": []
},
{
"name": "coverage",
"specs": []
},
{
"name": "django-debug-toolbar",
"specs": []
}
],
"tox": true,
"lcname": "django-admin-easy"
}