Django-grappelli: Filter functionality on admin pages don't work unless actions = None on ModelAdmins

Created on 3 Oct 2012  ·  55Comments  ·  Source: sehmaschine/django-grappelli

Hi all,

Unless actions = None in my ModelAdmin class definitions, grappelli raises and javascript exception and the filter functionality (with fields defined in list_filter) breaks. The dropdown button shows up but nothing drops down when you click on it.

The error is "Uncaught TypeError: Object [object Object] has no method 'actions' " on the line $("tr input.action-select").actions(); (line 66 in the grappelli template).

The relevant code snippet from the grappelli code

Also, I think this might be similar to Issue #206.

I'm using Django 1.4.1 and Grappelli 2.4.2

discussion

All 55 comments

Are you sure you´ve cleared the cache and you´re loading the right files?
because I´m not able to reproduce this (and I´m pretty sure this bug doesn´t exist).

I´ve checked again and I´m not able to reproduce this ... please re–open the ticket if you think it´s a bug.

You're right--it must have been a cache issue, because it's gone now. Strange thing is that I'm using a development server (Werkzeug) and didn't set any cache headers. I've never had a problem with Chrome auto-caching something before. Is something different about Grappelli's dynamically generated content? If so, could we put some kind of notice in for others? It looks like it's happened before (see Issue #206, mentioned above).

I stumbled upon this, too and it doesn't look like a cache issue to me. Even if I delete the cache in Chrome and Firefox and revisit the admin site, the error doesn't disappear. Also, restarting the Django server (I'm using gunicorn) doesn't help. I didn't do any configuration of grappelli yet, just installed it via pip (django-grappelli==2.4.2) and included it in the INSTALLED_APPS in settings.py (before django.contrib.admin).

The problem, I think, is, that the failing call to ".actions()" uses grp.jQuery, but .action() is only defined in django.jQuery. In grappelli.min.js you seem to try to set django.jQuery to grp.jQuery, so that they're the same, but because the grappelli scripts are loaded before the Django admin JavaScripts, that doesn't work.

This is what the HTML code of a Django admin list overview page looks like in my case:

<!-- jQuery, jQuery-UI -->
<script src="/static/grappelli/jquery/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="/static/grappelli/jquery/ui/js/jquery-ui-1.8.18.custom.min.js" type="text/javascript"></script>

<!-- Grappelli Minified -->
<script src="/static/grappelli/js/grappelli.min.js" type="text/javascript"></script>

<script type="text/javascript" src="/static/admin/js/core.js"></script>
<script type="text/javascript" src="/static/admin/js/admin/RelatedObjectLookups.js"></script>
<script type="text/javascript" src="/static/admin/js/jquery.js"></script>
<script type="text/javascript" src="/static/admin/js/jquery.init.js"></script>
<script type="text/javascript" src="/static/admin/js/actions.js"></script>

<script type="text/javascript" src="/admin/jsi18n/"></script>

<script type="text/javascript" charset="utf-8">
    (function($) {
        $(document).ready(function() {
            $("tr input.action-select").actions();
        });
    })(grp.jQuery);
</script>

This may well be a configuration error on my side, but to me it doesn't look like a caching issue...

OK, I think I found the reason and it looks like a Django bug: When you use the static file development view of Django to serve your static files, Django doesn't serve grappelli's overridden jquery.js and jquery.init.js, but instead the original files from the Django admin, which causes this error. :( Now I'm serving my static files with nginx even during development and it works fine.

I´m using staticpatterns, but I´m still not able to reproduce this.

@philwo you´re saying that grappellis jquery.js doesn´t get loaded. if that´s the case, there´s a lot of functionality which doesn´t work, right (e.g. autocompletes)? basically, not much of the admin will work as expected ...

@sehmaschine Yes, that was the case, the features relying on JavaScript didn't work. I'll try to find the cause for this problem on my configuration in the next days and will get back to you.

This is extremely strange.

I'm able to reproduce it when I run the Django devserver using "./manage.py runserver" or gunicorn using "./manage.py run_gunicorn" - then Django seems to override my whole static files config with defaults (even if I configure it totally wrong on purpose and specify non-existing classes in settings.STATICFILES_FINDERS it will still serve static files).

If I run gunicorn using "gunicorn myapp.wsgi:application", Django uses my settings correctly and I have to add the usual "urlpatterns += staticfiles_urlpatterns()" to my urls.py to get static files working. Then the override works and grappelli's JS files get served correctly instead of the original Django admin files.

I'm going to create a minimal example and if I'm successful, I'll report this as an issue on code.djangoproject.com.

since we´re about to do a new release, it´d be nice to solve this issue ...

  1. it seems that STATICFILES_FINDERS is not being used with runserver (I´m able to reproduce that).
  2. still, I´m not able to get django override the grappelli files (unless I´m adding "django.contrib.admin" before "grappelli" with INSTALLED_APPS).

any additional information is helpful ... thx.

I'm having this same problem. I'm running Django 1.4.1 and have grappelli in installed apps before contrib.admin.

<script type="text/javascript" charset="utf-8">
        (function($) {
            $(document).ready(function() {
                $("tr input.action-select").actions();
            });
        })(grp.jQuery);
</script>

When I edit change_list.html to pass in django.jQuery the filter list works as you'd expect. Not a great fix but hope if provides some insight.

<script type="text/javascript" charset="utf-8">
        (function($) {
            $(document).ready(function() {
                $("tr input.action-select").actions();
            });
        })(django.jQuery);
</script>

I am also having this issue running Django 1.4.2 and Grappelli 2.4.3 on a fresh install of Ubuntu 10.04

$("tr input.action-select").actions is not a function

is the error being shown with firebug.

The filter doesn't work and I cant select items for deletion.

I have tried using the domain name directly and also with runserver.

At first I was getting the error with both but changing

STATIC_URL = 'http://somedomain.com/static/'

to simply

STATIC_URL = '/static/'

fixed the issue when using runserver but the problem still exists when using the domain name.

I have compared the html output code of both and they are identical.

It all works flawlessly on my dev server and I would just like to say a big thanks for a fantastic product. Fingers crossed a fix can be found for this.

Any further info I can supply you with please just ask.

Has there been any progress with this issue?

I have two sites to put live for clients and I will need to do some recoding if I have to revert back to the Django templates.

@maffacow since I´ve never been able to reproduce this issue, I need to rely on feedback. so far, I´m not sure what a "fix" could be ...

Since the website is not yet live, I can give you ssh access if you require? Or is there any info I can provide you with?

well ... you can debug, find the issue (if it actually exists) and submit a pull–request. that´s the most straightforward way to solve it.

I am having the same/similar issue, site works fine on devserver but JS loading seems to be not working properly on production server (nginix)

Django's default jquery libs are being loaded rather than the grappelli overrides

The only place grappelli javascripts are working is on the main admin/ page, ie the click() event is handled for the user options dropdown when you click on the username in the top menu.. but only if you are on the main admin dashboard. (because django does not load its jquery libraries on the main admin dashboard)

Django 1.4.2 with Grappelli 2.4.3, no caching enabled, everything appears to be configured properly.. have numerous Django 1.3 sites with grappelli on similar production setup with no issues.

Ok, I finally got this working on my system.

Sehmaschine, is correct in my instance, it wasnt actually a bug but more to do with my settings.

I was loading the static files from the dist-packages using apache in my sites-available file.


Alias /static/grappelli /usr/local/lib/python2.6/dist-packages/grappelli/static/grappelli
Alias /static /usr/local/lib/python2.6/dist-packages/Django-1.4-py2.6.egg/django/contrib/admin/static

This was stupid I know, but the way I was shown when first introduced to Django

All I needed to have was

Alias /static /srv/www/mywebsite.com/public_html/static

and in my settings.py

STATIC_ROOT = '/srv/www/mywebsite.com/public_html/static/'
STATIC_URL = '/static/'

I hope this may be of some help to others and once again, thank you for such a great script

OK I figured out my issue also, it was indeed a caching/configuration error.

Caching was disabled for HTTP but enabled for SSL /static alias.

I had a similar configuration like maffacow.

Using the collectstatic command and removing the alias for the admin files in the server-configuration fixed the issue for me.

I got the same problem: clearing the browser cache solved it

I have the same problem when deploying to Google App Engine. Works just fine on my local machine. From the source of the generated page I see the following entries for various JS libraries when running on GAE:

jquery-1.7.2.min.js from /static/grappelli
jquery-ui-1.8.18.custom.min.js from /static/grappelli

grappelli.min.js from /static/grappelli

core.js from /static/admin
RelatedObjectLookups.js from /static/admin
jquery.js from /static/admin
jquery.init.js from /static/admin
actions.js from /static/admin

I've cleared the browser cache, ran collectstatic and have setup the static urls as per Google's docs. When I check these entries against a locally generated page, the JS entries match...

Unfortunately no solution yet. By the way, thanks for an awesome script...

I had this issue, solved it by ensuring that the AppDirectoriesFinder is first among the STATICFILES_FINDERS, like this:

STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    'django.contrib.staticfiles.finders.FileSystemFinder',
 )

@ulmus that's a good point – we'll update the docs with that info.

I had this issue today as well. I ensured that AppDirectoriesFinder was first in STATICFILES_FINDERS as well as making sure my STATIC_ROOT , STATICFILES_DIRS , and STATIC_URL were all set correctly.

The solution to my issue ended up being moving GRAPPELLI_INDEX_DASHBOARD from my local.py settings file and into my base.py settings file above all of the above declarations.

@idboehman thanks for the hint, but I'm very certain that GRAPPELLI_INDEX_DASHBOARD is not related to the actions whatsoever. My guess is that this issue is caused by caching (could be browser–cache, could be old .pyc–files).

I've had this issue for a long time. The STATICFILES_FINDERS fix worked for me.

The way i did this was to create simlink to grappelli/static/admin (which has the js files in question) in my staticfiles folder. STATICFILES_FINDERS didn't help.

This is what solved it for me as well, zzart.

Just guessing, but the issue appears to be that following the install instructions, django's built-in jquery library is loading after the grappelli jquery-1.7.2. Creating the link as you describe results in effectively loading the jquery library twice, but at least it's the same library.

having the same issue. Tried the GRAPPELLI_INDEX_DASHBOARD suggestion, clearing cache suggestion, the STATICFILES_FINDERS suggestion and made certain all of the paths for static files were to documentation standards. No luck. Perhaps I'll try the modification of the js suggestion but seems rather adhoc. oh well.

@zzart if you need a symlink there´s something wrong with your staticfiles setup ... all staticfiles should be found automatically when doing collectstatic.

@tufelkinder djangos built–in jquery is overriden by grappelli (there is no content with jquery.min.js).

In two months, I have had this issue 3 times, and every time I used a different way to solve it.

But I have found that if you follow the @ulmus comment about AppDirectoriesFinder, and inside your static folder, you replace your admin > js folder by your grapelli > static > admin > js folder, the problem is solved!

Hi guys, I was facing this issue and the core of this tricky issue is that jquery is there twice. U can see that when u look into html source in ur browser.

I didnt wanna use symlink, so I've added this to nginx site conf:

location = /static/admin/js/jquery.js {
    alias /dev/null;
}

@grafa but the file /static/admin/js/jquery.js is empty, see
https://github.com/sehmaschine/django-grappelli/blob/master/grappelli/static/admin/js/jquery.js

another idea – did you try running collectstatic with ignoring the original admin–files?
python manage.py collectstatic --ignore django.contrib.admin

So I had this exact same problem... I took over a project that at some point was started pre 1.3 Django (currently 1.4). Turns out I had been using the old 'staticfiles' app and not 'django.contrib.staticfiles' and wasn't getting everything with collectstatic. After migrating over to django's static, collectstatic worked and no more admin issues!

@sehmaschine my solution wasn't 100%. I've started using collectstatic and it works now.

my problem was solved as follows::

STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'django.contrib.staticfiles.finders.FileSystemFinder',
)

Hi i having one issue .. I have created a js file for numeric key pad and wen i call from my application , Its not calling . i get error as "[ object object] has no method. Any help will be appreciated. Thanks in advance

Found it! Make sure to remove the old grappelli and admin files in your static root directory and then do a manage.py collectstatic again after this is changed.

STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'django.contrib.staticfiles.finders.FileSystemFinder',
}
Now it stated to work without that error.

I had the same problem with Filters using gunicorn and ngnix. I had AppDirectoriesFinder before FileSystemFinder in STATICFILES_FINDERS but it still didn't work. What did work is making sure that when the grappelli is using the admin/js/, that is is forcing it to use grappelli's admin javascripts, not the admin apps.

This is what my ngnix config looks like now:

   location /static/admin/js/ {
       root /usr/local/lib/python2.7/dist-packages/grappelli/;
 }
location /static/admin/media/ {
       root /usr/local/lib/python2.7/dist-packages/django/contrib/admin/static/admin/;
 }

 location /static/grappelli/ {
      root /usr/local/lib/python2.7/dist-packages/grappelli/;
    }

 location /static/ {
    # if asset versioning is used
    if ($query_string) {
        expires max;
      }
 }

@squarepegsys thanks, your solution also solved my problem...

With nginx, you should really just have one location /static/ pointing to your static project folder and then let ./manage.py collectstatic DTRT, respecting the collection order specified in settings.py. That way, your nginx and runserver environment will be much more comparable.

Same problem that's been reported for 2+ years. Tried all reasonable solutions. No luck.

@sdillinger well, haven't been able to reproduce this for 2+ years. I'm pretty sure this is not related to grappelli but your server/django setup.

It seems to me that the same symptom has multiple root causes depending on the environment.

In my case, 'runserver', the solution was to reverse STATICFILES_FINDERS as suggested above.

ACTUALLY... In my case STATICFILES_FINDERS only partially solved the problem and, in fact, was a red herring.

What solved it for me was making sure grappelli loads before debug_toolbar:

INSTALLED_APPS = (
...
'grappelli',
'debug_toolbar',
...
)

Have just encountered this problem for the second time so exerted some effort looking into it. The following discussion is based upon my setup but it wouldn't surprise me in the slightest if others are in exactly the same boat.

sehmaschine commented on 11 Aug
@sdillinger well, haven't been able to reproduce this for 2+ years. I'm pretty sure this is not related to grappelli but your server/django setup.

@sehmaschine: I'm with you 100% -- in my case at least, it had nothing to do with Grappelli itself. As for reproducing (and fixing) the error -- perhaps I can help you with that...


TL;DR

A simple, working solution to this problem. First up, two important references:

http://django-grappelli.readthedocs.org/en/latest/quickstart.html#setup:

Open settings.py and add grappelli to your INSTALLED_APPS (before django.contrib.admin):

INSTALLED_APPS = (
    'grappelli',
    'django.contrib.admin',
)

https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#django-admin-option---clear:

--clear

Clear the existing files before trying to copy or link the original file.

A caveat:

  • Using --clear is like a sledgehammer; it will clear all static files that aren't needed by the current project
  • So if you are using the same STATIC_ROOT for more than one project, then better to leave this method -- there's a more nuanced, less destructive method outlined further down
  • Essentially, don't use this for anything other than testing, unless you're comfortable to rebuild STATIC_ROOT

Now the steps:

  1. Ensure you have 'grappelli' before 'django.contrib.admin' in INSTALLED_APPS, as shown in the reference above
  2. Run python manage.py collectstatic --noinput --clear
  3. Test from the browser, with full reload of the page with the filter button on it -- error should be resolved

Basic overview
Intro

With the steps shown below, I've been able to reproduce and fix the error 100% consistently, using the following setup:

  1. Django 1.8
  2. DEBUG = False
  3. Nginx + Gunicorn via. Unix socket

In any case, as long as the static files are being accessed at STATIC_ROOT, the following steps should work.

Reproducing the error

In order to reproduce the error, note that I am about to _contradict the official instructions as shown above_, because that is one of the ways that this problem could have occurred.

  • Switch the ordering in INSTALLED_APPS, i.e.:
INSTALLED_APPS = (
    'django.contrib.admin',
    'grappelli',
)
  • Delete (or at least rename) the static/admin/js directory
  • Run python manage.py collectstatic --noinput, output should show django/contrib/admin in the path, such as:
$ python manage.py collectstatic --noinput
Copying '.../django/contrib/admin/static/admin/js/inlines.js'
Copying '.../django/contrib/admin/static/admin/js/collapse.js'
Copying '.../django/contrib/admin/static/admin/js/related-widget-wrapper.js'
Copying '.../django/contrib/admin/static/admin/js/calendar.js'
Copying '.../django/contrib/admin/static/admin/js/collapse.min.js'
Copying '.../django/contrib/admin/static/admin/js/urlify.js'
Copying '.../django/contrib/admin/static/admin/js/core.js'
Copying '.../django/contrib/admin/static/admin/js/jquery.js'
Copying '.../django/contrib/admin/static/admin/js/actions.min.js'
Copying '.../django/contrib/admin/static/admin/js/jquery.init.js'
Copying '.../django/contrib/admin/static/admin/js/inlines.min.js'
Copying '.../django/contrib/admin/static/admin/js/actions.js'
Copying '.../django/contrib/admin/static/admin/js/jquery.min.js'
Copying '.../django/contrib/admin/static/admin/js/timeparse.js'
Copying '.../django/contrib/admin/static/admin/js/SelectBox.js'
Copying '.../django/contrib/admin/static/admin/js/prepopulate.min.js'
Copying '.../django/contrib/admin/static/admin/js/SelectFilter2.js'
Copying '.../django/contrib/admin/static/admin/js/LICENSE-JQUERY.txt'
Copying '.../django/contrib/admin/static/admin/js/prepopulate.js'
Copying '.../django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js'
Copying '.../django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js'

21 static files copied to '.../static', 593 unmodified.
  • Test from the browser, with full reload of the page with the filter button on it -- error should be manifest

Fixing the error

The resolution steps are almost the same:

  • Correct the ordering in INSTALLED_APPS, i.e.:
INSTALLED_APPS = (
    'grappelli',
    'django.contrib.admin',
)
  • Delete (or at least rename) the static/admin/js directory
  • Run python manage.py collectstatic --noinput, output should show grappelli in the path, such as:
$ python manage.py collectstatic --noinput
Copying '.../grappelli/static/admin/js/SelectFilter2.js'
Copying '.../grappelli/static/admin/js/collapse.min.js'
Copying '.../grappelli/static/admin/js/actions.min.js'
Copying '.../grappelli/static/admin/js/inlines.js'
Copying '.../grappelli/static/admin/js/urlify.js'
Copying '.../grappelli/static/admin/js/related-widget-wrapper.js'
Copying '.../grappelli/static/admin/js/collapse.js'
Copying '.../grappelli/static/admin/js/jquery.js'
Copying '.../grappelli/static/admin/js/jquery.min.js'
Copying '.../grappelli/static/admin/js/calendar.js'
Copying '.../grappelli/static/admin/js/prepopulate.js'
Copying '.../grappelli/static/admin/js/prepopulate.min.js'
Copying '.../grappelli/static/admin/js/actions.js'
Copying '.../grappelli/static/admin/js/core.js'
Copying '.../grappelli/static/admin/js/LICENSE-JQUERY.txt'
Copying '.../grappelli/static/admin/js/timeparse.js'
Copying '.../grappelli/static/admin/js/SelectBox.js'
Copying '.../grappelli/static/admin/js/inlines.min.js'
Copying '.../grappelli/static/admin/js/jquery.init.js'
Copying '.../grappelli/static/admin/js/admin/RelatedObjectLookups.js'
Copying '.../grappelli/static/admin/js/admin/DateTimeShortcuts.js'

21 static files copied to '.../static', 593 unmodified.
  • Test from the browser, with full reload of the page with the filter button on it -- error should be resolved
Why is the problem occurring?
  • collectstatic is getting the static/admin/js files from 'django.contrib.admin' instead of 'grappelli'
How could this have happened?
  1. As in the steps shown above, could have the INSTALLED_APPS ordered wrongly
  2. Another cause could be that collectstatic was run for 'django.contrib.admin' before 'grappelli' was ever installed
  3. ...

Further details

The following points are from my basic investigations and not any meaningful experience. I'd be perfectly happy for a Django expert to come along and tell me I'm all wrong and there are better explanations and solutions. I just want to develop more robust, stable apps. Please take with a pinch of salt.

Everything hinges on how collectstatic works

https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#collectstatic:

On subsequent collectstatic runs (if STATIC_ROOT isn’t empty), files are copied only if they have a modified timestamp greater than the timestamp of the file in STATIC_ROOT. Therefore if you remove an application from INSTALLED_APPS, it’s a good idea to use the --clear option in order to remove stale static files.

  • Emphasis above is mine
  • Possible scenario:

    • Wrong static/admin/js in place

    • User has corrected ordering in INSTALLED_APPS

    • However, modification dates on system are unfavourable, i.e.:

    • grappelli/static/admin/js < static/admin/js

  • The result will be something like:
$ python manage.py collectstatic --noinput

0 static files copied to '.../static', 614 unmodified.
  • Change the modification date for one of the source files, to show that it is then collected:
$ touch .../grappelli/static/admin/js/jquery.init.js 
$ python manage.py collectstatic --noinput
Copying '.../grappelli/static/admin/js/jquery.init.js'

1 static file copied to '.../static', 613 unmodified.
  • Probably far more appropriate to change modification dates in the static directory rather than the source files, e.g.:
$ touch -d 2000-01-01 .../static/admin/js/jquery.init.js 
$ python manage.py collectstatic --noinput
Copying '.../grappelli/static/admin/js/jquery.init.js'

1 static file copied to '.../static', 613 unmodified.
  • So for the whole static/admin/js directory:
$ find .../static/admin/js -type f -exec touch -d 2000-01-01 {} \;
$ python manage.py collectstatic --noinput
Copying '.../grappelli/static/admin/js/SelectFilter2.js'
Copying '.../grappelli/static/admin/js/collapse.min.js'
Copying '.../grappelli/static/admin/js/actions.min.js'
Copying '.../grappelli/static/admin/js/inlines.js'
Copying '.../grappelli/static/admin/js/urlify.js'
Copying '.../grappelli/static/admin/js/related-widget-wrapper.js'
Copying '.../grappelli/static/admin/js/collapse.js'
Copying '.../grappelli/static/admin/js/jquery.js'
Copying '.../grappelli/static/admin/js/jquery.min.js'
Copying '.../grappelli/static/admin/js/calendar.js'
Copying '.../grappelli/static/admin/js/prepopulate.js'
Copying '.../grappelli/static/admin/js/prepopulate.min.js'
Copying '.../grappelli/static/admin/js/actions.js'
Copying '.../grappelli/static/admin/js/core.js'
Copying '.../grappelli/static/admin/js/LICENSE-JQUERY.txt'
Copying '.../grappelli/static/admin/js/timeparse.js'
Copying '.../grappelli/static/admin/js/SelectBox.js'
Copying '.../grappelli/static/admin/js/inlines.min.js'
Copying '.../grappelli/static/admin/js/jquery.init.js'
Copying '.../grappelli/static/admin/js/admin/RelatedObjectLookups.js'
Copying '.../grappelli/static/admin/js/admin/DateTimeShortcuts.js'

21 static files copied to '.../static', 593 unmodified.
  • In regards to the --clear option, as mentioned at the beginning; some observations:

    • It definitely works...

    • ... but it is a very aggressive solution, which can end up removing static files belonging to other projects that share the same STATIC_ROOT

    • Thus, not really appropriate as a general recommendation

Repercussions

This issue remaining active for over 3 years is a testament to this collectstatic functionality. What makes it even more delicious is that the "bug" can resolve itself given the right conditions. An example:

  • Amongst trying different solutions, user upgrades Grappelli, introducing new static/admin/js source files, with more recent modification dates than those currently in STATIC_ROOT

    • Yet, filter button stubbornly refuses to work

  • At some future point in time, user runs collectstatic

    • Suddenly, the filter button is working again

In an ideal world:

  • An in-between setting for collectstatic, something like a --replace or --overwrite or --ignore-timestamps
  • Basically:

    • Find all the static files as it currently does

    • Copy them over regardless of existing static files

    • Don't touch any other static files in STATIC_ROOT

Now if this ideal world already exists, please let me know. Perhaps even this issue could finally be closed!

"The File of Doom"

Finally, this whole discussion wouldn't be complete without identifying the offender, fingering the exact line of code that has caused so much pain!

I've already sneakily mentioned it above... and it is...:

  • static/admin/js/jquery.init.js!!! But y'all had already figured that out, right?!

If Grappelli wins the collectstatic battle, then you'll find it contains:

// dropped
// not used in grappelli
// kept this file to prevent 404

Yet if Django-Admin comes out trumps, you'll find:

/* Puts the included jQuery into our own namespace using noConflict and passing
 * it 'true'. This ensures that the included jQuery doesn't pollute the global
 * namespace (i.e. this preserves pre-existing values for both window.$ and
 * window.jQuery).
 */
var django = django || {};
django.jQuery = jQuery.noConflict(true);
  • So, just a 2-line js file after all of that
  • And it's actually the last line that is the troublemaker -- comment it out and the filter button works again

NB: I am in no way advocating this method of getting the filter button working again -- just sharing this finding for the curious out there.

@myii Thanks a lot for the research and the very detailed explanation. What you're saying makes sense indeed (still funny that I've never run across this issue with any projects we did).

@myii Thanks. I added the steps` to my deployment in Ansible like so, and then run collectstatic again (unfortunately):

- name: 'manage.py collectstatic'
  django_manage: app_path={{common_htdocs_dir}}/fos
                 command=collectstatic
                 settings=fos.settings
                 virtualenv={{common_htdocs_dir}}/fos-venv
  when: code.changed or code_deps.changed or settings.changed
  tags:
    - fos
    - collectstatic

# Next two steps, credits to @myii
# https://github.com/sehmaschine/django-grappelli/issues/214#issuecomment-158576652
- name: "Move Django's admin assets to avoid conflict with Grapelli's"
  command: mv {{common_htdocs_dir}}/fos/static/admin/js {{common_htdocs_dir}}/fos/static/admin/js-already-moved creates={{common_htdocs_dir}}/fos/static/admin/js-already-moved
  tags:
    - fos
    - collectstatic
    - grapelli

# Using command directly so ----no-post-process can be passed, for extra speed
- name: "Re-run collectstatic to replace admin assets with Grapelli's"
  command: '{{common_htdocs_dir}}/fos-venv/bin/python ./manage.py collectstatic --no-color --noinput --no-post-process chdir={{common_htdocs_dir}}/fos'
  tags:
    - fos
    - collectstatic

Luckily Grapelli does not need post-processing, and only JS is affected.

I got the same error, added this and it worked
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'django.contrib.staticfiles.finders.FileSystemFinder',
}

;)

Hi all, Django 1.9.8 / Grappelli 2.8., this problem still occurs, even in production with static files setup.

Is there any 'simple' solution for this ? Noting that in my project, admin js is never loaded any time.

marcoooo,

Is grappelli first in INSTALLED_APPS?

INSTALLED_APPS = (
    'grappelli',
    'django.contrib.admin',
)

Did you run collectstatic? What is the output? Which filesystem path does it collect to? How are your static files served? Which filesystem path are they served from? Have you emptied your browser cache and any server caches for your static files?

@marcoooo Based upon my long answer above and the follow-up by @Tatsh, I've got a 2-step summary for you:

  1. Clear/move the static/admin/js directory
  2. Run collectstatic again

As long as you've got the correct ordering as pointed out by @ecederstrand, you'll be good to go.

Hi All, thank for your quiclk response !

  • Ordering in apps is ok (since in the reverse order, I d'ont get the grappelli style at all)
  • I run collectstatic, admin files comme again (so I deleted the folder)
  • path is (relative to project ~/staticfiles/) I think my conf is correct because all other statics are served well (no urlpatterns update in my urls.py configuration, as recommanded in Django doc)

Still got this issue.

Django packages installed:

django-admin-sortable (2.0.18)
django-authtools (1.5.0)
django-bootstrap-themes (3.3.6)
django-braces (1.9.0)
django-ckeditor (5.1.0)
django-cors-headers (1.1.0)
django-countries (3.4.1)
django-crispy-forms (1.6.0)
django-crontab (0.7.1)
django-debug-toolbar (1.5)
django-eav (0.9.2, /home/marc/.virtualenvs/waves1/src/django-eav)
django-environ (0.4.0)
django-grappelli (2.8.1)
django-ipware (1.1.5)
django-jquery (1.12.2)
django-jquery-ui (1.11.4.1)
django-log-file-viewer (0.9)
django-mail-templated (2.6.2)
django-mptt (0.8.4)
django-multiupload (0.5.1)
django-nested-admin (3.0.8)
django-polymorphic (1.0.1)
django-registration (2.1.2)
django-smart-selects (1.2.2)
django-tabbed-admin (1.0.0)
djangorestframework (3.4.0)
djangorestframework-jwt (1.8.0)
djangorestframework-xml (1.3.0)
drfdocs (0.0.11)

Running on apache with static serving setup:

<Directory [ABSOLUTE_PATH_TO_WAVES_INSTALL_DIR]/src/waves_services>
Options FollowSymLinks Indexes
<Files wsgi.py>
Require all granted
</Files>
</Directory>
<Location /static>
SetHandler None
</Location>
<Location /media>
SetHandler None
</Location>
Alias /media [ABSOLUTE_PATH_TO_WAVES_INSTALL_DIR]/media
Alias /static [ABSOLUTE_PATH_TO_WAVES_INSTALL_DIR]/staticfiles

To help: actions() function seems to be declared in actions.js, but this file is not loaded in my admin pages (I inherit base_site.html in my project). Should I force this inclsion in my template ? I didn't see any trace of this import in any template in Grappelli sources.

GOT IT ! This is what happens, I don't know how, but includes on actions.js seems to be lost somewhere, I forced inclusion in my admin base_site.html template, and now it works.

For future reference it could be helpfull. (But anyway, does this file should not be included in base_site.html grappelli file ?)

I run collectstatic, admin files comme again (so I deleted the folder)

@marcoooo Only delete the folder before collectstatic. When you run collectstatic again, it produces the correct files _that you need to keep_.

Hello everyone!
We have here the same issue but with a different scenario:

  • 2 virtualenvs packaged with RPM
  • one of them have Grappelli
    our static files are shared across the virtualenv and collectstatic is run first for the one that do not have Grappelli.
    The timestamp of files are the date of the RPM's creation, so Grappellis and Djando static admin files are almost ate the same datetime.

If someone else got this scenario beware. Our solution (for now) is to mannualy copy Grappelli's static files after collectstatic.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

johncpang picture johncpang  ·  4Comments

asfaltboy picture asfaltboy  ·  11Comments

adamchainz picture adamchainz  ·  24Comments

bob-r picture bob-r  ·  9Comments

FrozenAlex picture FrozenAlex  ·  15Comments