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

Does not work with polymorphic package #327

Open
CelestialStreamer opened this issue Aug 29, 2022 · 2 comments
Open

Does not work with polymorphic package #327

CelestialStreamer opened this issue Aug 29, 2022 · 2 comments

Comments

@CelestialStreamer
Copy link

Brand new, minimal django project. On admin pages for parent polymorphic model with sortable admin mixin gives error:

Environment:


Request Method: GET
Request URL: http://localhost:8004/admin/django_gists/parent/

Django Version: 4.0
Python Version: 3.10.1
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.messages',
 'django.contrib.sessions',
 'django.contrib.staticfiles',
 'adminsortable2',
 'polymorphic',
 'django_gists']
Installed Middleware:
['django.contrib.sessions.middleware.SessionMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware']


Template error:
In template /usr/local/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>


Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.10/site-packages/django/core/handlers/base.py", line 204, in _get_response
    response = response.render()
  File "/usr/local/lib/python3.10/site-packages/django/template/response.py", line 105, in render
    self.content = self.rendered_content
  File "/usr/local/lib/python3.10/site-packages/django/template/response.py", line 83, in rendered_content
    return template.render(context, self._request)
  File "/usr/local/lib/python3.10/site-packages/django/template/backends/django.py", line 61, in render
    return self.template.render(context)
  File "/usr/local/lib/python3.10/site-packages/django/template/base.py", line 176, in render
    return self._render(context)
  File "/usr/local/lib/python3.10/site-packages/django/template/base.py", line 168, in _render
    return self.nodelist.render(context)
  File "/usr/local/lib/python3.10/site-packages/django/template/base.py", line 977, in render
    return SafeString(''.join([
  File "/usr/local/lib/python3.10/site-packages/django/template/base.py", line 978, in <listcomp>
    node.render_annotated(context) for node in self
  File "/usr/local/lib/python3.10/site-packages/django/template/base.py", line 938, in render_annotated
    return self.render(context)
  File "/usr/local/lib/python3.10/site-packages/django/template/loader_tags.py", line 130, in render
    compiled_parent = self.get_parent(context)
  File "/usr/local/lib/python3.10/site-packages/django/template/loader_tags.py", line 127, in get_parent
    return self.find_template(parent, context)
  File "/usr/local/lib/python3.10/site-packages/django/template/loader_tags.py", line 106, in find_template
    template, origin = context.template.engine.find_template(
  File "/usr/local/lib/python3.10/site-packages/django/template/engine.py", line 145, in find_template
    template = loader.get_template(name, skip=skip)
  File "/usr/local/lib/python3.10/site-packages/django/template/loaders/base.py", line 18, in get_template
    for origin in self.get_template_sources(template_name):
  File "/usr/local/lib/python3.10/site-packages/django/template/loaders/filesystem.py", line 36, in get_template_sources
    name = safe_join(template_dir, template_name)
  File "/usr/local/lib/python3.10/site-packages/django/utils/_os.py", line 17, in safe_join
    final_path = abspath(join(base, *paths))
  File "/usr/local/lib/python3.10/posixpath.py", line 90, in join
    genericpath._check_arg_types('join', a, *p)
  File "/usr/local/lib/python3.10/genericpath.py", line 152, in _check_arg_types
    raise TypeError(f'{funcname}() argument must be str, bytes, or '

Exception Type: TypeError at /admin/django_gists/parent/
Exception Value: join() argument must be str, bytes, or os.PathLike object, not 'list'

models.py

from django.db import models
from polymorphic.models import PolymorphicModel

class Parent(PolymorphicModel):
    class Meta:
        ordering = ("order_by",)
    order_by = models.PositiveIntegerField(default=0)

class ChildA(Parent):
    pass

class ChildB(Parent):
    pass

admin.py

from adminsortable2.admin import SortableAdminMixin
from django.contrib import admin
from polymorphic.admin import PolymorphicChildModelAdmin, PolymorphicParentModelAdmin
from . import models

class ChildAdmin(PolymorphicChildModelAdmin):
    """Base admin class for all child models"""

@admin.register(models.ChildA)
class ChildAAdmin(ChildAdmin):
    base_model = models.ChildA

@admin.register(models.ChildB)
class ChildBAdmin(ChildAdmin):
    base_model = models.ChildB

@admin.register(models.Parent)
class ParentAdmin(SortableAdminMixin, PolymorphicParentModelAdmin):
    child_models = (models.ChildA, models.ChildB)

Versions

  • django==4.0
  • django-admin-sortable2==2.1.2
  • django-polymorphic==3.1.0
  • Python=3.10.1

Stuck

I don't know if SortableAdminMixin is the culprit or PolymorphicParentModelAdmin. #196 does not work for me. I added SortableAdminMixin to ChildAAdmin and ChildBAdmin or ChildAdmin and I still get the same error.

@jrief
Copy link
Owner

jrief commented Oct 14, 2022

Ok, will have a look for the next release.

@alexkiro
Copy link

TL;DR A quick workaround is using a custom PolymorphicParentModelAdmin class like so:

class CustomPolyParentAdmin(PolymorphicParentModelAdmin):
    @property
    def change_list_template(self):
        return "admin/change_list.html"

@admin.register(models.Parent)
class ParentAdmin(SortableAdminMixin, CustomPolyParentAdmin):
    child_models = (models.ChildA, models.ChildB)

This should work assuming you are not using any custom templates, in which case you would have to specify the path to your custom template instead of `"admin/change_list.html". Unsure what you need to do if you are using multiple mixins, as that gets confusing.


The issue stems from the fact that the property change_list_template from PolymorphicParentModelAdmin returns a list of templates instead of a single template. I believe this is done to allow custom templates based on the child object type. From django-polymorphic docs:

It extends the template lookup paths, to look for both the parent model and child model in the admin/app/model/change_form.html path.

Which is a supported feature of SimpleTemplateResponse. I believe the issue was introduced in #316

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants