django-suit icon indicating copy to clipboard operation
django-suit copied to clipboard

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

Open yinix opened this issue 6 years ago • 10 comments

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_report_monitor.zip

what does this mean?

TypeError at admin_sms_send_report_monitor.zip

yinix avatar Dec 28 '17 05:12 yinix

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

cometsong avatar Jan 02 '18 14:01 cometsong

@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

yinix avatar Jan 03 '18 02:01 yinix

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

gamesbook avatar Jan 03 '18 06:01 gamesbook

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

cometsong avatar Jan 03 '18 11:01 cometsong

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

Arlington1985 avatar Jan 14 '18 22:01 Arlington1985

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

gamesbook avatar Apr 07 '18 06:04 gamesbook

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

jfajardo avatar Aug 21 '19 16:08 jfajardo

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

jayvdb avatar Apr 23 '20 03:04 jayvdb

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

LOGOUT_REDIRECT_URL = '/'

shivamjagdishsingh avatar May 10 '20 14:05 shivamjagdishsingh

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.

zstyblik avatar Sep 01 '20 09:09 zstyblik