Serving Django application from relative path - django

I am developing a Django application which works fine locally. In production, the application will be served from a relative path, such as www.example.com/app/.
I am using Apache with mod_wsgi, and I have configured Apache to serve the application from the relative URL:
WSGIScriptAlias /app /path/to/my/modwsgi.py
WSGIDaemonProcess app display-name=app_wsgi
Unfortunately, I get an Error 404. The debug information, though, is pretty mysterious. If I try to get www.example.com/app/myurl/, Django says
Using the URLconf defined in apps.urls, Django tried these URL patterns, in this order:
^myurl/$
...
The current URL, myurl/, didn't match any of these.
It seems that Django - correctly - infers that the path requested is myurl/, and not app/myurl/. But, even though myurl/ clearly matches ^myurl/$, it does not find a match.
I have also tried to add the setting
FORCE_SCRIPT_NAME = '/app'
but nothing changes - the error message remains identical.

The debug information lies :-/ Trying with more permissive regexs in the URL conf; iwas able to get a page. From there I could print request.path, and it turned out to be app/myurl/.
To make it work, I had instead to put
FORCE_SCRIPT_NAME = ''
STATIC_URL = '/app/static/'
MEDIA_URL = '/app/media/'

Related

Django + GUnicorn ASGI with SCRIPT_NAME

I have a Django application running with a gunicorn ASGI server and an NGINX reverse proxy for serving static content. All are packaged within a docker container.
Now I want to serve this container behind a reverse proxy with a path prefix, e.g. "mydomain.com/djangoapp/". The problem is, that Django doesn't know it's hosted under a subpath, and for example, the Django admin application then always redirects to the root path "/" instead of "/djangoapp/".
I already read that there are several settings that handle this problem.
I tried setting the "FORCE_SCRIPT_NAME" in the Django settings directly to "/djangoapp". It worked for the admin login page, but after clicking the login button it redirected to the wrong root "/".
I tried setting the "SCRIPT_NAME" environment variable of the gunicorn server to "/djangoapp". It did not apply at all.
I'm running now out of ideas on what else to try. Does anybody else have a solution for this problem?
FORCE_SCRIPT_NAME should work. For the post-login redirect you need to properly set LOGIN_REDIRECT_URL

Deploy Django in subdomains

I want to deploy a django app into an existing webenvironment, with other sites already existing.
Therefore i received a domain from the webadmin like this: www.websites.com/theapp
Now, in my local development environment the path /theapp does not exist, because the project is starting on / and the project folder is called /myapp
Myapp's urls.py is pointing to two included apps like /app1 and /app2
I tried to add /theapp to the urls, what really doesn't work.
As i am fairly new to Django i would appreciate any assistance on how to handle this leading path, so Django could handle the incoming url correctly.
First, you should configure Web Server (like nginx, apache, etc...). Below is the Nginx configuration:
location /theapp {
... something uwsgi configuration or proxy_pass things ...
}
After that, set up Django's urls.py file to accept requests starting with the path /theapp.
from django.urls import path, include
urlpatterns = [
path('theapp/', include('yourapp.urls')),
]

Django can't find staticfiles with Debug=False and Allowed_Hosts

Hi all I'm having trouble solving this issue: If I turn DEBUG to False, I can't run manage.py runserver:
CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False
Then, let's say I add something to ALLOWED_HOSTS:
ALLOWED_HOSTS = ['*']
or
ALLOWED_HOSTS = ['localhost']
or
ALLOWED_HOSTS = ['127.0.0.1', 'localhost']
Now, I can do ´manage.py runserver´ but the staticfiles don't work. Weird.
If I turn DEBUG to True, then it works with ALLOWED_HOSTS set to nothing, to localhost or to *. So, I guess the problem has to do with DEBUG. I don't understand it.
In DEBUG mode, the Django development server handles serving static files for you. However, this is not best for production as it's much more inefficient than a true server. See here.
Serving the files
In addition to these configuration steps, you’ll also need to actually serve the static files.
During development, if you use django.contrib.staticfiles, this will be done automatically by runserver when DEBUG is set to True (see django.contrib.staticfiles.views.serve()).
This method is grossly inefficient and probably insecure, so it is unsuitable for production.
See Deploying static files for proper strategies to serve static files in production environments.
Check out here to learn out how to serve static files in production.
EDIT: Adding the following to answer #alejoss question about viewing error pages with DEBUG=True.
I added something like the following to my root urls.py file:
if settings.DEBUG:
urlpatterns += patterns(
'',
url(r'^400/$', TemplateView.as_view(template_name='400.html')),
url(r'^403/$', TemplateView.as_view(template_name='403.html')),
url(r'^404/$', 'django.views.defaults.page_not_found'),
url(r'^500/$', 'django.views.defaults.server_error'),
)
You might need to alter a bit (i.e., the 400 and 403 pages may need to be edited if your template names are different). Basically, this lets you visit http://localhost/400 to see your 400 error page, http://localhost/403 to see your 403 error page, and so on.
If you still need to server static locally (e.g. for testing without debug) you can run devserver in insecure mode:
manage.py runserver --insecure
Okay Here's the very clean solution. you need to use
DEBUG = False
DEBUG_PROPAGATE_EXCEPTIONS = True
This way in your logs you can see what is then problem. Whitenoise returns 500 usually when It is missing some file.
You can see what is missing in you logs. In my case heroku logs were enough.
for more info: https://docs.djangoproject.com/en/2.0/ref/settings/#debug-propagate-exceptions

Static (admin) files do not seem to be served correctly

I have problems with Django serving static files on the admin panel.
Calling http://vbox.me/admin/ (where vbox.me is aliased to the VM's IP) results in a blank page without stylesheets.
Calling http://vbox.me/static/admin/css/base.css though, which is part of the stylesheets that should be loaded when opening http://vbox.me/admin/, brings up the correct file.
Here is some essential information:
I recently started experimenting with Django.
My current version of Django is 1.8.
I'm running nginx (on Arch Linux within a VirtualBox on Windows 7) that passes every non-static file to uwsgi
uwsgi and nginx run as service using systemd
Running the Django development server standalone does not result in the given weird behavior.
Nginx configuration file:
# ...
http {
sendfile on;
upstream django {
server unix:/tmp/uwsgi.sock;
}
server {
# ...
location /static {
# static directory of the django project
alias /home/martin/projects/django_test/static;
}
location / {
uwsgi_pass django;
include /etc/nginx/uwsgi_params;
}
}
}
INI file for uwsgi:
[uwsgi]
chdir=/home/martin/projects/django_test
wsgi-file=django_test/wsgi.py
chmod-socket=666
socket=/tmp/uwsgi.sock
master=true
vacuum=true
Important parts from settings.py within the Django project:
STATIC_ROOT = '/home/martin/projects/django_test/static/'
# using vbox.me to make sure the browser does not make up some strange url.
STATIC_URL = 'http://vbox.me/static/'
I'm pretty much "left in the dark", I can only guess that I made some mistake in configuring uwsgi or Django, since nginx seems to server the static files perfectly (at least when explicitly requesting them...)
Thanks in advance!
Edit: I will do a fresh setup of all the tools I use to deploy my app to make sure I made no mistakes. Additionally, I will be using virtualenv this time (which I haven't used previously). I'll let you know if that works!
After doing a fresh install of everything following this tutorial, everything works just fine now. Looks like I made some mistakes in configuration.
I also used Django 1.7 here, so Django 1.8 might have been the cause to my problems as well (though thats really unlikely)

How do you configure a Django ImageField with upload_to and MEDIA_ROOT on Webfaction?

I have the following model field in a django project:
headshot = models.ImageField(upload_to='/tmp', blank=True, null=True)
settings.py
# format <project>/<app>
MEDIA_ROOT = '/home/username/webapps/django/myproject/books/media/'
I have created a directory: /home/username/webapps/django/myproject/books/media/tmp and gave it chmod 777 permissions.
I get the following error when I try to add a new image:
SuspiciousOperation at /admin/books/author/add/
Attempted access to '/tmp/Comment.png' denied.
Request Method: POST
Request URL: http://username.webfactional.com/app/admin/books/author/add/
Django Version: 1.3.1
Exception Type: SuspiciousOperation
Exception Value:
Attempted access to '/tmp/Comment.png' denied.
Exception Location: /home/username/webapps/django/lib/python2.7/django/core/files/storage.py in path, line 234
Python Executable: /usr/local/bin/python
Python Version: 2.7.1
Does anyone know what I'm doing wrong? Do I need .htaccess or some other settings to be able to write to this directory or is there something wrong with my Django config?
I would still like to know what chmod values to use and how to set MEDIA_URL. I'm thinking I might need to do something in urls.py for MEDIA_URL.
My project is set up on the webhost Webfaction if that makes a difference.
Fixed it. Seems like the answer was to use upload_to='tmp' instead of upload_to='/tmp'.
I see you've marked this as answered, but still have some questions in your answer. Here is how I have this set up, in case you are still working on it.
Set up a new app for media (via the webfaction control panel). I used the "static_only" application because it should prevent users from uploading scripts and running them. You could also use one of the "static/cgi/php". Creating a new app for this (instead of using Django and making a new view) is good practice because it will have a lower resource overheard. Django is overkill for serving static files (images, css files, javascript files, etc.).
Bind your new media (static_only, or whatever you used) app to some URL, again using the webfaction control panel. I bound mine to media..com. MEDIA_URL should be set to the URL you can access your media through, and MEDIA_ROOT should be the root directory for the media app. Thus, in my settings.py file I have:
MEDIA_ROOT = '/home/<username>/webapps/media/'
MEDIA_URL = 'http://media.<mydomain>.com/'
It's best to do the same thing for STATIC_ROOT and STATIC_URL.
As far as permissions go, the defaults should be OK - if you have troubles with that just ask.