How to use SortableAdminMixin together with ImportExportModelAdmin from django-import-export?
micudaj opened this issue · 12 comments
I tried to use ImportExportModelAdmin together with SortableAdminMixin from admin-sortable2, but I get the following error. Any idea how and if these can work together?
join() argument must be str, bytes, or os.PathLike object, not 'list'
Request Method: GET
Request URL: http://xxxxx.de/admin/tenant_only/frage/
Django Version: 4.1.5
Exception Type: TypeError
Exception Value:
join() argument must be str, bytes, or os.PathLike object, not 'list'
Exception Location: /usr/local/Cellar/python@3.10/3.10.9/Frameworks/Python.framework/Versions/3.10/lib/python3.10/genericpath.py, line 152, in _check_arg_types
Raised during: adminsortable2.admin.changelist_view
Error during template rendering
In template /Users/mim/Downloads/sourcecode/django/django-klimawahlen/venv/lib/python3.10/site-packages/adminsortable2/templates/adminsortable2/change_list.html, error at line 1
join() argument must be str, bytes, or os.PathLike object, not 'list'
1 {% extends base_change_list_template %}
2
3 {% block extrahead %}
4 {{ block.super }}
5 <script type="application/json" id="admin_sortable2_config">
6 {
7 "update_url": "{{ sortable_update_url }}",
8 "current_page": {{ cl.page_num }},
9 "total_pages": {{ cl.paginator.num_pages }}
10 }
11 </script>
Please read the contribution guidelines.
I'm sorry. I am not sure where to look. Do you have own contribution guidelines for questions? Can you please point me to them?
Please read here:
https://django-admin-sortable2.readthedocs.io/en/latest/contributing.html#reporting-bugs
Fork the repository, and adopt that demo to use ImportExportModelAdmin
.
This has the benefit that if fixed, we have UI tests and E2E tests.
I am too lazy/busy to learn about another 3rd party library.
I recreated the bug in a fork: https://github.com/micudaj/django-admin-sortable2/tree/import-export-bug
It occurs when you open "Books (ordered by model, no inlines)" in admin.
Okay, thanks!
To get adminsortable2 and import-export working together I have the following:
admin.py
from adminsortable2.admin import SortableAdminMixin
from django.contrib import admin
from import_export.admin import ExportActionMixin, ImportExportMixin
class ExampleAdmin(
ImportExportMixin, ExportActionMixin, SortableAdminMixin, admin.ModelAdmin
):
# ...
Then to have both the adminsortable2 drag handles and the import-export buttons on the admin change list create the following template in your project template directory such that it will override the template included in the adminsortable2 package.
my_project/templates/adminsortable2/change_list.html
{% extends 'adminsortable2/change_list.html' %}
{% block object-tools-items %}
{% include "admin/import_export/change_list_import_item.html" %}
{% include "admin/import_export/change_list_export_item.html" %}
{{ block.super }}
{% endblock %}
Thing is it looks like adminsortable2 will extend it's change list template from whatever you set the changelist_template attribute on your model admin to be. So you might think you can set it to one of the change list templates in import-export and adminsortable2 will extend that and the buttons will appear - but... import-export also implements this feature in a very similar way and uses exactly the same variable name when extending the changelist_template base_change_list_template
. This results in a TemplateNotFound which is slightly confusing, but a result of the Django template finder system and our now recursive extends.
So I felt it was acceptable to solve this via the template override above. I could have just as easily extended the import-export template and copied the content from adminsortable2 but since import-export provides templates to include for their buttons I feel this way is better.
I'm not sure this needs fixing. Perhaps it could be fixed by renaming the base_change_list_template
variable. But then I wonder if I've misunderstood the purpose of this base_change_list_template
variable and perhaps it is no coincidence that it is identical in both packages. Perhaps it is meant to facilitate a situation such as this where the change list template should extend a chain of templates from multiple apps and I just don't know how to use it.
I was able to make work sorting with import/export butons just by explicitly setting change_list_template
:
class MyAdmin(ImportExportMixin, SortableAdminMixin, admin.ModelAdmin):
change_list_template = "admin/import_export/change_list.html"
This seems to be issue of django-import-export
which doesn't define change_list_template
explicitly.
If the order of mixins is reversed (SortableAdminMixin, ImportExportMixin, admin.ModelAdmin
) I think the issue lies in django-adminsortable2
which returns list for the change_list_template
property while as defined in Django documentation it should return just the template path:
Path to a custom template, used by changelist_view().
perhaps it is no coincidence that it is identical in both packages
Yes, this is because the change was applied in django-admin-sortable2 and then ported to django-import-export. The purpose was to try to make it easier for the two packages to work together.
I was able to make work sorting with import/export butons just by explicitly setting
change_list_template
:class MyAdmin(ImportExportMixin, SortableAdminMixin, admin.ModelAdmin): change_list_template = "admin/import_export/change_list.html"This seems to be issue of
django-import-export
which doesn't definechange_list_template
explicitly.If the order of mixins is reversed (
SortableAdminMixin, ImportExportMixin, admin.ModelAdmin
) I think the issue lies indjango-adminsortable2
which returns list for thechange_list_template
property while as defined in Django documentation it should return just the template path:Path to a custom template, used by changelist_view().
Hi Petr,
when I use you suggestion I can see drag handles and import / export on the page, but the drag handles are not working. I see that they do not get any event handler assigned for drag events. Do you have any idea what I could do?
There are 3 remaining issues in this library which causes this issue:
- The
base_change_list_template
variable should has specific name for each project. I have made PR fordjango-import-export
, but to avoid clashes with other libraries I would recommend renaming the variable to somethingsortable_base_change_list_template
. - The
change_list_template
doesn't have setter on which the solution with template mixin overrides depends. - The
change_list_template
does return list of paths witch is something that Django documentation doesn't count for and cannot be used in{% extends base_change_list_template %}
of other associated libraries.
Hi, did someone figure out a workaround so far or is there any update on this issue? :)
Solution
step 1: use ImportExportMixin in admin
step 2: create file templates\adminsortable2\change_list.html with body:
`{% extends 'adminsortable2/change_list.html' %}
{% block object-tools-items %}
{% include "admin/import_export/change_list_import_item.html" %}
{% include "admin/import_export/change_list_export_item.html" %}
{{ block.super }}
{% endblock %}`