darklow / django-suit

Modern theme for Django admin interface
http://djangosuit.com/
Other
2.33k stars 705 forks source link

'NoneType' object is not iterable \site-packages\django_suit-2.0a1-py2.7.egg\suit\menu.py in map_native_apps, line 116 #658

Open yinix opened 6 years ago

yinix commented 6 years ago

If this is a bug please specify versions you're using first.

Django version: 1.11.8 Django Suit version: 2.0a1 Python version: 2.7.12

Issue: I build the suit menu by add config class in apps.py:

class SuitConfig(DjangoSuitConfig): layout = 'vertical'

menu = (
    ParentItem('myapps', children=[
        ChildItem(model='bstsms.appinfo'),
        ChildItem('Custom view', url='/admin/custom/'),
    ], icon='fa fa-leaf'),
    ParentItem('smsconfig', children=[
        ChildItem('sms-template',model='bstsms.smstemplate'),
        ChildItem('sms-signature',model='bstsms.signtemplate'),
    ], icon='fa fa-leaf'),
    ParentItem('authen', children=[
        ChildItem('user',model='auth.user'),
        ChildItem('group', model='auth.group'),
    ], icon='fa fa-users'),
    ParentItem('system', children=[
        ChildItem('open sms send report', url='/admin/sms_send_report_monitor'),
        ChildItem('open sms up', url='http://google.com', target_blank=True),

    ], align_right=True, icon='fa fa-cog'),
)

it works when i login the admin panel and i could see the menu i wanted. but, when i logout and try to access the the url "http://localhost:8080/admin/sms_send_report_monitor/". I got the type error: 'NoneType' object is not iterable when building the suit menu: TypeError at _admin_sms_send_reportmonitor.zip

what does this mean?

TypeError at _admin_sms_send_reportmonitor.zip

cometsong commented 6 years ago

The basic issue is that Suit does not yet support the massive changes into Django v2+. @darklow (plus pull requests) will get to it.... :)

yinix commented 6 years ago

@cometsong Have a good day! The Django I used is v1.11, is it belongs to v2+? And, I'd like to when could get the issue fixed? Thanks

Yinix

gamesbook commented 6 years ago

Is there any activity at all from @darklow recently on this project? See also #657 (support for Django 2)

cometsong commented 6 years ago

@yinix my mistake on misreading !! I saw django version 2 instead of suit version 2.

Arlington1985 commented 6 years ago

I have same problem in django suti v2 when I want to to override index view from my custom defined admin_site in my dashboard/admin.py

from django.contrib.admin import AdminSite
from django.shortcuts import render

class MyAdminSite(AdminSite):
    site_header = 'My Custom dashboard'

    def index(self, request):
        return render(request, 'admin/index.html', {"foo": "bar"})

admin_site = MyAdminSite(name='myadmin')

in urls.py

from dashboard.admin import admin_site

urlpatterns = [
    url(r'^admin/', include(admin_site.urls)),
]

It worked fine in old version(v1) of django suit

gamesbook commented 6 years ago

See #672

You need to add context to the render: https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#adminsite-methods

For example:

def index(self, request):
    return render(
        request=request,
        template_name='admin/index.html',
        context=dict(
            admin.site.each_context(request),
            foo=bar)
        )
    )

(and obviously, import the admin module first.)

jfajardo commented 5 years ago

It's work for me

class MyModelView(DetailView):
    model = MyModel

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context.update(custom_admin.each_context(self.request))
        context['title'] = 'Title'
        return context
jayvdb commented 4 years ago

I am seeing this, or something very similar, when using https://github.com/barseghyanartur/django-admin-timeline . It provides /admin/timeline/ , but I guess it doesnt add it to the admin structure, so django-suit cant find its parent.

In template /usr/local/src/django-suit/suit/templates/suit/menu.html, error at line 8: {% for parent_item in menu %}
shivamjagdishsingh commented 4 years ago

try this, was facing same issue. Added this in settings. it worked for me perfectly.

LOGOUT_REDIRECT_URL = '/'

zstyblik commented 4 years ago

EDIT2: If only my brain was present, debugging wouldn't take that long. What seems to be the fix in my case is:

--- suit/menu.py        2020-09-01 13:27:05.676527816 +0000
+++ suit/menu.py.patch  2020-09-01 13:26:42.844283983 +0000
@@ -113,6 +113,9 @@
         """
         Make dictionary of native apps and models for easier matching
         """
+        if not self.available_apps:
+            return
+
         for native_app in self.available_apps:
             app_key = native_app['app_url'].split('/')[-2]
             self._available_apps['apps'][app_key] = native_app
@@ -141,6 +144,9 @@

     def build_menu_by_available_apps(self):
         menu_items = []
+        if not self.available_apps:
+            return menu_items
+
         for native_app in self.available_apps:
             parent_item = self.make_parent_from_native_app(native_app)
             menu_items.append(parent_item)

You see, I thought that menu or some (iter) "item" in menu or something is None in template's context. But that doesn't seem to be issue in my case and stack trace was telling me so (probably) the whole day.

With the patch above, I get menu for logged in user and no stack trace for anonymous user in django admin (custom) login form which extends admin/base_site.html and so on.

My guess is that available_apps can be None in django 3.x.


Such pain which could be solved by simple fix like {% if menu and menu|length > 0 %} in django-suit/suit/templates/suit/menu.html:

{% load i18n suit_menu suit_tags %}

{% get_menu request as menu %}
{% with suit_layout='layout'|suit_conf:request %}
    <div id="suit-nav">
        <ul>
            {% if menu and menu|length > 0 %}
                {% for parent_item in menu %}
                    {% if not parent_item.align_right or suit_layout == 'vertical' %}
                        {% include 'suit/menu_item.html' %}
                    {% endif %}
                {% endfor %}
            {% endif %}
        </ul>
        {% if menu.aligned_right_menu_items %}
            <ul class="suit-nav-right">
                {% for parent_item in menu.aligned_right_menu_items %}
                    {% include 'suit/menu_item.html' %}
                {% endfor %}
            </ul>
        {% endif %}
    </div>
    {% if suit_layout == 'horizontal' and menu and menu.active_parent_item %}
        <div id="suit-sub-nav">
            <ul>
                {% for child_item in menu.active_parent_item.children %}
                    <li{{ child_item.is_active|yesno:' class=active,' }}>
                        <a href="{{ child_item.url }}"
                                {{ child_item.target_blank|yesno:' target=_blank,' }}>{{ child_item.label }}</a>
                    </li>
                {% endfor %}
            </ul>
        </div>
    {% endif %}
{% endwith %}

I'm using https://github.com/darklow/django-suit/commit/0d854c9b5e81adf9b9ea2ca9ee0a2856dcef5e15

EDIT: despite it solves one problem, it introduces another by not showing up menu when it should. Oh well.

try this, was facing same issue. Added this in settings. it worked for me perfectly.

LOGOUT_REDIRECT_URL = '/'

Did nothing for me.

It's work for me

class MyModelView(DetailView):
    model = MyModel

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context.update(custom_admin.each_context(self.request))
        context['title'] = 'Title'
        return context

Neither did this, but it was worth the shot.