-1

I'm testing one and the same application both on the default Django server and on Apache and I see a lot of big differences. I managed to resolve some of them, but at this moment I'm unable to resolve a major difference. So, in project settings.py file I have this code:

MODULES_DIR = BASE_DIR + '/system/modules/'

for item in os.listdir(MODULES_DIR):
    stat = os.path.join(MODULES_DIR, item + '/static')
    if os.path.isdir(os.path.join(MODULES_DIR, item)):
        INSTALLED_APPS += ('system.modules.%s' % item, )
        STATICFILES_DIR += (stat, )

APPS_DIR = true

This code is supposed to populate INSTALLED_APPS dynamically, based on the contents of BASE_DIR + '/system/modules/' folder. In other words, if there is a folder inside /modules, this folder becomes an application. Likewise, I build dynamically STATICFILES_DIR - in this case it is supposed, that every single folder/application (which is inside /modules folder) has a /static folder with static contents - js, css etc. For example, it may be such a construct:

\modules
    \DefaultModule
        __init__.py
        urls.py
        views.py
        \static
            test.js
        \templates
            DefaultModule.html

And DefaultModule.html in this example loads static files like this:

<html>
<head>
{% load static from staticfiles %}
<script type="text/javascript" src="{% static "test.js" %}"></script>

It is rather interesting, but on default Django server this logic works perfectly, so that when I go in my browser to localhost/DefaultModule/, I see a template DefaultModule.html loaded and I see test.js file loaded from http://localhost/DefaultModule/static/. However, on Apache the template is rendered too, but the test.js file is loaded from http://localhost/static/ what eventually results in a 404 NOT FOUND error. So, for some reason Apache server does not take into account STATICFILES_DIR. And yes I checked its (I mean STATICFILES_DIR) contents and it is the same. In both cases STATICFILES_DIR contains modules/DefaultModule/static/, but on Apache it is ignored for some reason. Hope someone can help. Thanks!

Jacobian
  • 10,122
  • 29
  • 128
  • 221

1 Answers1

1

I think you should read the Django docs on static files. Looks like you're falling into the simple and old Django Static File Hosting an Apache

Check it out and let us know.

Community
  • 1
  • 1
Patrick Bassut
  • 3,310
  • 5
  • 31
  • 54
  • The problem is I have a rather dynamic static files =) In a sense, that I build STATICFILES_DIR dynamically. So the forum thread you are pointing to, does not answer to my question. But if you know how I can set `Alias ` in Apache configuration file, so that it would accept all static folders inside all dynamic modules - like `modules\module_1\static`, `modules\module_2\static`, `modules\someOtherModule\static` etc, then it would be really helpful. – Jacobian Sep 22 '15 at 20:01
  • You can still have dynamic static files. But in apache you must point to only one place unless you want to apply the same script using apache(which is not very clean). What I suggest is: since you have everything on your INSTALLED_APPS you can do a collectstatic and put everything in one place and make apache point to that directory to serve static files. – Patrick Bassut Sep 22 '15 at 20:03
  • I think `AliasMatch` - http://httpd.apache.org/docs/2.2/mod/mod_alias.html#aliasmatch - looks more promissing. I will try to use it first to make a rule, that all static files should obey. – Jacobian Sep 22 '15 at 20:06
  • Well, i tried dozens of diferent regular expressions to set `AliasMatch`, but competely to no avail. So, the problem remains unsolved. Your advise to move static files from different apllications to a single static folder, will not work, because it will destroy the modular organisation of the project. – Jacobian Sep 22 '15 at 20:30
  • 1
    I never said that. Django has a command called "collectstatic" that gets every static folder of every app on your installed_apps and puts it in another folder. That way, you can make apache point to that – Patrick Bassut Sep 22 '15 at 20:42
  • And how should this command `collectstatic` be invoked? Should I do this on the application level, or should I run it manually? If I should do it manually, then it is not the solution either, because that will destroy again the idea of dynamic `modules/applications`. That will be terrible, if the admin will have to run this command every time, when new module/application is uploaded to `modules` folder. I wish I could do it once and forever - the way it works on the default Django server. – Jacobian Sep 22 '15 at 20:49
  • 'python manage.py collectstatic' - manually. This is part of the deploy. Everything a new module comes in, you must collect it's static content and put in one place. I do it when I'm deploying using fabric. Also, if you're thinking of when a user uploads a folder and then the module gets automatically reloaded, you're gonna have to reread settings.py – Patrick Bassut Sep 22 '15 at 20:54
  • That's a painful routine. I wish that could be solved on Apache side - just the way it is handled in the default Django server. – Jacobian Sep 22 '15 at 21:00
  • I've tried different regular expressions, but could not find one that would work for me. – Jacobian Sep 23 '15 at 06:03
  • Sorry, don't you know how to force Django to ignore missing folders with static contents inside some applications? I'm asking this, because when I do `python manage.py collectstatic`, I get an error message `No such file or directory PROJECT_PATH/js`. Whereas, I suppose this command to search and upload files from `static/js`, `static/css` and `static/img` folders of some applications. So when there is no `static` folder inside an application, it should not throw an error. – Jacobian Sep 23 '15 at 16:22
  • If you could, please, share how you set Alias or AliasMatch in your config file, I will definitely accept it as an answer. I did like you advised me - used `python manage.py collectstatic`, resolved some issues. Now I see, that at least this part of problem is solved - I see how static files and folders with static contents are uploaded to the root static folder. But the first problem is that it again works only on default server, so that when I restart it, I see that it loads content from the root static folder And even though Apache server loads it from the very same folder, ... – Jacobian Sep 23 '15 at 17:21
  • I see in the console error message `NOT FOUND`. The way I set Alias and AliasMatch is: `AliasMatch ^/js(.*) /home/jacobian/apps/apps/static$1`, `Alias /static/ /home/jacobian/apps/apps/static`. Hope you can help – Jacobian Sep 23 '15 at 17:24
  • And the second problem that in both cases - on the default server and on Apache server - the static folder is discarded. But that I mean that if I open the console and reload the page, I can see there such an URL localhost/home/jacobian/apps/apps/static/js/. What I do not like is that it shows home/jacobian as a part of the URL. – Jacobian Sep 23 '15 at 17:27
  • I think a regex of something like this would work: ```AliasMatch ^/(.+)/static/ /modules/$1/static/```. This way, urls of the form ```/mynewmodule/static/``` would redirect to ```/modules/mynewmodule/static/```. Also, when you upload a new module, it would automatically get the new static folder – Patrick Bassut Sep 23 '15 at 21:04
  • Thank you, Patrick. Your advice to use `collectstatic` helped me to do the trick! Although, I do not really like the idea to manually run this command and to reload the server every time, when a new module/application is uploaded to the project. – Jacobian Sep 24 '15 at 03:45
  • You can always make a bash script to watch the directory and if a new folder comes in, you fire the command. But I don't think this is pretty. :) Check this out: http://stackoverflow.com/questions/6475252/bash-script-watch-folder-execute-command – Patrick Bassut Sep 24 '15 at 03:51