jrief / django-admin-sortable2

Generic drag-and-drop ordering for objects in the Django admin interface
https://django-admin-sortable2.readthedocs.io/en/latest/
Other
753 stars 179 forks source link

How to use SortableAdminMixin together with ImportExportModelAdmin from django-import-export? #345

Open micudaj opened 1 year ago

micudaj commented 1 year ago

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>
jrief commented 1 year ago

Please read the contribution guidelines.

micudaj commented 1 year ago

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?

jrief commented 1 year ago

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.

micudaj commented 1 year ago

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.

jrief commented 1 year ago

Okay, thanks!

Quantra commented 1 year ago

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.

PetrDlouhy commented 1 year ago

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().

matthewhegarty commented 1 year ago

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.

micudaj commented 1 year ago

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().

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?

PetrDlouhy commented 1 year ago

There are 3 remaining issues in this library which causes this issue:

JunusErgin commented 7 months ago

Hi, did someone figure out a workaround so far or is there any update on this issue? :)

nguyenduclongwin commented 5 months ago

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 %}`