Django not serving admin static files using fastcgi - python

I am trying to deploy my django app on a subdomain, say example.djangoapp.com, everything works fine, except for my django admin site, when i click on the link that goes to the admin site, it routes to a different url. This happens when i use the admin url template tag, i.e. it routes to djangoapp.com/index instead of example.djangoapp.index.fcgi/login (which is the admin site).
After removing the admin url template tag, i put an absolute url to the to redirect to the admin site, this work fine and the admin site shows up, but its static files are not served. So i am stack in between.
I am deploying on server that runs fastcgi on shared hosting
My questions:
1)Option 1 (Using the admin url template tag):
How do i get django to redirect me to the correct admin site (www.example.djangoapp.index.fcgi/login) instead of redirecting me to (www.djangoapp.com/index).
2) When using absolute url:
Now i hardcoded the admin link within my home template index page, this works fine but the django admin static files are not served. How can they get served?
Pardom my ignorance but i have been struggling with this for weeks. I decided to hardcode the url but still the admin sites static files are not being served.
Below is my settings.py , urls.py and index.html(where i hardcoded the admin site url). This code is inline with option 2 above that has the hardcoded admin site url.
settings.py
WSGI_APPLICATION = 'cconnect_web.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '',
'USER': '',
'PASSWORD': '',
'HOST': '',
'PORT': '',
'CONN_MAX_AGE': 3600,
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Africa/Cairo'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/
STATIC_URL = '/cconnect/static/'
STATIC_ROOT = '/home4/techaven/public_html/cconnect/static'
FORCE_SCRIPT_NAME="/index.fcgi/"
Urls.py
from django.conf.urls import *
from django.conf.urls import include, url
from django.contrib import admin
from cconnect_frontEnd import views
from . import settings
#app_name = 'cconnect_frontEnd
urlpatterns = [
url(r'^$', views.index, name ='index'),
url(r'^backend/', include('Back_End.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root':settings.STATIC_ROOT}),
]
urlpatterns += patterns('Back_End.views',
(r'^login/$', 'login_view'),
)
admin.site.site_header = 'Cconnect Administration.'
index.html
<body>
<div class="header-wrapper">
<nav>
<div class=nav-wrapper">
{% load staticfiles %}
<img src="{% static "cconnect_frontEnd/images/slide/logo.png" %}" alt="Conference Connect"/>
<ul class="right hide-on-med-and-down">
{% load admin_urls %}
<li>Sign In</li>
<li>Features</li>
<li>Videos</li>
</ul>
index.fcgi
import os
import sys
from flup.server.fcgi import WSGIServer
from django.core.wsgi import get_wsgi_application
sys.path.insert(0, "/home4/techaven/public_html/cconnect/cconnect_web/")
os.chdir("/home4/techaven/public_html/cconnect/cconnect_web")
os.environ['DJANGO_SETTINGS_MODULE'] = "cconnect_web.settings"
WSGIServer(get_wsgi_application()).run()
.htaccess
AddHandler fcgid-script .fcgi
DirectoryIndex index.fcgi
RewriteEngine On
RewriteCond %{HTTP_HOST} ^cconnect\.techavenue137\.rw$ [OR]
RewriteCond %{HTTP_HOST} ^www\.cconnect\.techavenue137\.rw$
RewriteRule ^/?$ "http\:\/\/www\.techavenue137\.rw\/cconnect\/index\.fcgi" [R=301,L]
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /cconnect/
RewriteRule ^index\.fcgi$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#RewriteCond %{REQUEST_URI} !^/static/
RewriteRule ^(.*)$ /cconnect/index.fcgi/$1 [L]
</IfModule>
Thank you for your help and once again pardon my stupid questions.

You'll need to add a rewrite rule to redirect the browser request to the actual static files for the admin page.
Below your last rewrite rule, add these lines:
RewriteCond "%{REQUEST_URI}" ".*/static/admin/.*"
RewriteRule "(.*)/cconect/(.*)" "$1/index.fcgi/$2" [R, L]
Here, the rewrite condition is saying that if the requested URI contains /static/admin then replace cconnect with index.fcgi and keep everything else the same. Mark it as a redirect [R] and stop rule processing if found [L]. I hope this solves your issue.
Disclaimer: I'm not very proficient in regex patterns and I have a basic understanding of Apache, so this solution might need to be tweaked. Have a look here if you need to adjust it.

I entirely fixed this issue by moving a different host, it was had to deploy and using fast cgi. I deployed to Digital Oceans and used Nginx to serve the static and media files.

Related

How do I serve media files in a local Django environment?

I can upload an image through the admin page, but the image can not be found when I navigate to the url that is generated by django. (404 error)
The files are being uploaded to the folder:
project_root/media/eventbanner/1/
I have tried multiple solutions but none seem to work for my situation.
Django 1.10 is being run local on Ubuntu 16.04.
The url I get is:
http://localhost:8000/media/eventbanner/1/banner_image.jpg
Media root folder is located at:
/home/username/xxx/xxx/project_name/media
Code in HTML file:
<div class="banner-image">
<img src="{{ event.eventbanner.banner_image.url }}"/>
</div>
url.py code:
from django.conf.urls import url, include
from django.contrib import admin
from . import views
from django.conf import settings
from django.conf.urls.static import static
app_name = 'events'
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^details/(?P<event_id>[0-9]+)/$', views.details, name='details'),
url(r'^details/(?P<event_id>[0-9]+)/addcomment/$', views.add_comment, name='add_comment'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS =[os.path.join(BASE_DIR, 'static'),]
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL = '/media/'
models.py
def validate_only_one_instance(obj):
model = obj.__class__
if (model.objects.count() > 0 and obj.id != model.objects.get().id):
raise ValidationError("Can only create 1 %s instance" % model.__name__)
class EventBanner(models.Model):
event = models.OneToOneField(Event, unique=True)
banner_image = models.ImageField(upload_to=get_image_path, blank=True, null=True)
def clean(self):
validate_only_one_instance(self)
The real problem here is that there is no relationship between this url http://localhost:8000/media/eventbanner/1/banner_image.jpg and this location on disk /home/username/xxx/xxx/project_name/media.
In a production application you'd have a web server where you'd store your Media content, the serving URL would be MEDIA_ROOT and you'd append ImageField.url to this value to get a valid image path.
What you need here is to set up a web server for your media images. At first that sounds like a lot of work, but Django provides a shortcut...
Serving Files in Development
You have some work you need to do to have the media files served locally. It requires some changes to your urls.py ...
from django.conf import settings
from django.views.static import serve
# ... the rest of your URLconf goes here ...
if settings.DEBUG:
urlpatterns += [
url(r'^media/(?P<path>.*)$', serve, {
'document_root': settings.MEDIA_ROOT,
}),
]
This uses the views.serve bit and should only be used in DEBUG mode. It overrides the path to media files(django's term for user uploaded content like ImageField). This will redirect those requests through the serve view. Best I can tell this is a mini web server that will map those request routes to locations on disk and allow those locations to be reachable via HTTP urls.
As of at least Django 1.8, there is a helper function static() that will set this up for you and ensure that it only functions in debug mode.
Your urls.py should look something like this:
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
...to simply quote the documentation.
Make sure that your MEDIA_URL is set to a relative path like /media/ and that your MEDIA_ROOT is an absolute filesystem path like /home/foo/project/media.

Serving static files on Apache with Django (404 error)

I've been trying to setup an Apache (2.2.15) as a proxy with gunicorn and django (1.6.11) on a CentOS server (6.7), but I'm stuck on a problem regarding the static files. (I'm fairly new to django)
I have already looked at the great documentation that Django provides, as well as a few other stackoverflow's posts, but to no avail.
What I could check :
The problem doesn't seem to come from Django or the templates, as running the development server with 'DEBUG = False' and the option '--insecure' works fine.
It probably is a problem with the Alias and Directory block I added in my virtualhost, but I can't make sense of why it doesn't work.
Gunicorn shouldn't have any word to say in it, as it doesn't serve static files.
What my configuration looks like :
1) I got my project's static files into '/var/www/myproject/static' thanks to the 'collectstatic' command.
2) Then, I created the virtualhosts (where I think the problem is) :
(first one for the redirection to HTTPS)
<virtualhost *:80>
ServerAdmin user#domain.com
ServerName localhost
ServerSignature Off
RewriteEngine on
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [NC,R,L]
</virtualhost>
(second one for the actual work)
<virtualhost *:443>
ServerAdmin user#domain.com
ServerName localhost
ServerSignature Off
DocumentRoot /var/www/myproject
Alias /static/ "/var/www/myproject/static/"
<Directory "/var/www/myproject/static">
Order Allow,Deny
Allow from All
</Directory>
ProxyPass / http://127.0.0.1:8000/ connectiontimeout=150 timeout=300
ProxyPassReverse / http://127.0.0.1:8000/
ProxyPreserveHost On
ProxySet http://127.0.0.1:8000/ connectiontimeout=150 timeout=300
... here goes the SSL and Log configuration ...
</virtualhost>
After a service restart, my static files weren't loaded and I had a 404 error on their get. An 'httpd -S' didn't throw any error and the rest of the functionalities of the web interface are working great.
I also tried without the ending '/' for the '/static/' alias as it seemed to be a problem for some other people, tried to move the files directly under /var/www/myproject and have them accessed without an alias with the DocumentRoot...
If you want to have a look at the django settings.py (don't know if it's relevant, but some django guru could find something wrong there too) :
STATIC_ROOT = '/var/www/myproject/static/'
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(os.path.dirname(__file__),'static',),)
As well as the templates :
{% load staticfiles %}
....
<link href="{% static 'bower_components/bootstrap/dist/css/boostrap.min.css %}" rel="stylesheet">
Urls.py of the project :
from django.conf.urls import patterns, include, url
from django.shortcuts import redirect
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = patterns('',
url(r'^$', lambda x: redirect('/Collecte/')),
url(r'^Collecte/', include('Collecte.urls', namespace="Collecte")),
) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
And the urls.py of the app (named 'Collecte'):
from django.conf.urls import patterns, url
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from Collecte import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^Collectes/Execution/รน', views.CollExecution, name='CollExecution'),
... quite a lot of them ...
)
# Commented this line from a suggestion, was present at start
#urlpatterns += staticfiles_urlpatterns
If you feel like any file is missing for the question to be relevant, just ask for it and I'll do my best :).
Alright,
I found the answer to my question in another stackoverflow thread that had a similar configuration (but with flask instead of django).
As Ajay Gupta said, I think I had a problem in the urls.py file of the project as I had to add 'static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)' (switched from using the staticfiles app django provides to this other way).
The other problem was in the apache virtualhost configuration, as I wanted my static files to be served by apache and not gunicorn or django. I was redirecting everything to the gunicorn server, even the requests to static files. So I had to add 'ProxyPass /static/ !' so that apache serves the files.
I don't know if it's the right way to do it, but it worked for me.
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
is a helper function that works only when
debug = True
So for instance just set debug = True again, restart your server and check

Django Development - Admin CSS file 404

I'm using this guide to attempt to get this working. Basically, I'm exploring django 1.6 (with python 2.7.6 on Mac OS X Yosemite beta), still working with the stock development server. I'm trying to include a CSS file to override some styles in the admin area. I have a static folder in my project root. My settings.py is completely stock (that means I have DEBUG set to true and that I'm using django.contrib.staticfiles). Inspecting the source and request/response reveals that I'm calling for the CSS file at my expected path, but that I'm getting a 404 when attempting to load it. I also get a 404 when attempting to hit the CSS file directly in the browser. I've searched google and SO and have not, as of yet, been able to find an answer.
The requested CSS file:
http://*mysite*/static/admin/css/mysite-admin.css
The file system path to the CSS file:
*myprojectdir*/static/admin/css/mysite-admin.css
Yes it won't work because Django does not serve by default static assets, in order to have static assets served (mind though this should be the case only for local dev) in your main urls.py file add this to the top:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
And then at the end of your urls.py:
if settings.DEBUG:
urlpatterns = patterns('',
url(r'^media/(?P<path>.*)$', 'django.views.static.serve', # NOQA
{'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
) + staticfiles_urlpatterns() + urlpatterns
Make sure you have defined STATIC_URL, MEDIA_ROOT and MEDIA_URL in your settings.py, for development STATIC_ROOT IS NOT needed.

How do I serve CSS to Django in development?

I've been all through the documentation, and it just doesn't make sense to me. I ran collectstatic, I set up /static/ directories in both my app and my project directories, I added STATIC_URL and STATIC_ROOT to my settings.py file (but I have no idea how to know if they're set correctly) and {{ STATIC_URL }} still isn't rendering out to anything. It all seems like a heck of a lot of overkill just to connect html to css.
I think I'm lost in the details; could anyone supply a high-level breakdown of this static files idea? I'm afraid I may have mixed instructions for both production and development setups.
MORE: Here's the relevant bit from my settings.py file:
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
# Uncomment the next line to enable the admin:
'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
'django.contrib.staticfiles',
'dashboard.base',
)
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
)
STATIC_ROOT = ''
STATIC_URL = '/static/'
STATICFILES_DIRS = (
'C:/Users/Sean/Desktop/Work Items/dashboard/base/static/',
)
And this is the code I'm trying to use in my template:
<link rel="stylesheet" href="{{ STATIC_URL }}css/960.css" />
OK. I made the changes everybody recommended. Here's my new urls.py:
from django.conf.urls.defaults import *
from base.views import show_project
from django.conf import settings
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Example:
# (r'^dashboard/', include('dashboard.foo.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
# (r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
(r'^admin/', include(admin.site.urls)),
('^show_project/$', show_project),
)
if settings.DEBUG:
urlpatterns += patterns('',
url(r'^media/(?P<path>.*)$', 'django.views.static.serve',{'document_root': settings.MEDIA_ROOT, 'show_indexes': True }),
url(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT, 'show_indexes': True }))
urlpatterns += staticfiles_urlpatterns()
Am I missing something? Usually my problems turn out to be something really basic that CS pros take for granted but I miss.
Here's how mine is setup. It sounds like you might be missing the static context processor?
STATIC_ROOT and STATIC_URL
In the settings.py used in development:
STATIC_ROOT = ''
STATIC_URL = '/static/'
And the settings.py used on my production server:
STATIC_URL = '//static.MYDOMAIN.com/'
STATIC_ROOT = '/home/USER/public_html/static.MYDOMAIN.com/'
So, all the static files are located in static/. On the production server, all these files in static/ are collected to /home/USER/public_html/static.MYDOMAIN.com/ where they are served by a different web server (nginx in my case) and not Django. In other words, my django application (running on Apache) never even receives requests for static assets in production.
CONTEXT PROCESSOR
In order for templates to have the STATIC_URL variable available to them, you need to use the django.core.context_processors.static context processor, also defined in settings.py:
TEMPLATE_CONTEXT_PROCESSORS = (
# other context processors....
'django.core.context_processors.static',
# other context processors....
)
SERVER STATIC ASSETS IN DEVELOPMENT
Django doesn't get requests for static assets in production, however, in development we just let Django serve our static content. We use staticfiles_urlpatterns in urls.py to tell Django to serve requests for static/*.
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# .... your url patterns are here ...
urlpatterns += staticfiles_urlpatterns()
Have a look at Serving static files in development. You need to define the STATIC_URL and STATICFILES_DIRS to let django.contrib.staticfiles know where to look for files.
The idea behind the static files idea is that you can distribute your development related media file (css/js etc.) on a per-app basis, and allow the static files application to manage and collect all these resources from their various places.
So you tell the static files app where to look for static files (by settings STATICFILES_DIRS), where to copy to them (STATIC_ROOT) and what path to access them (STATIC_URL). When you run collectstatic, it search through the directories and copies all the files it finds into the static root.
The benefit of this is that you can manage your static files on a finer leve:
project/app1/static/css/ # These are css/js for a particular app
project/app2/static/css/
project/app3/static/css/
project/static/css # These might be general css/js for the whole project
static/ # This is where the collectstatic command will copy files to
and after you collectstatic them you will have:
project/app1/static/css/
project/app2/static/css/
project/app3/static/css/
project/static/css
static/app1/css/
static/app2/css/
static/app3/css/
static/css/
When you put your app/site on a production server, you let the webserver (apache, nginx) deal with serving the files by telling it to serve media files at /static/ or /media/ directly, while passing all other requests to the application. When developing though, it's easier to let the development server do this for you.
To do this, you have explicitly tell is server any request for media under /static/ (your STATIC_URL). In your urls.py, put the following (or similar)
from django.conf import settings
...
if settings.DEBUG:
urlpatterns += patterns('',
url(r'^media/(?P<path>.*)$', 'django.views.static.serve',{'document_root': settings.MEDIA_ROOT, 'show_indexes': True }),
url(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT, 'show_indexes': True }))
I have the same problem, and search many answers, but no one give me right answer.
The problem is you don't use RequestContext I think.
You should make a RequestContext as the parameter of Template like
c = RequestContext(request, {
'foo': 'bar',
})
In my views is:
return render_to_response('parts/test2.html', RequestContext(request, locals()))

Django + mod_python + apache: admin panel and urls don't work

Whole this day I was trying to configure django on production server. I use mod_python. When I open http: //beta.example.com I see my site but http: //beta.example.com/admin and http: //beta.example.com/441/abc/ doesn't work:
Page not found (404)
Request Method: GET
Request URL: http://beta.example.com/admin
{'path': u'admin'}
You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
Page not found (404)
Request Method: GET
Request URL: http://beta.example.com/441/abc/
{'path': u'441/abc/'}
You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
My urls:
from settings import MEDIA_ROOT
from django.conf.urls.defaults import *
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# static files
url(r'^static/javascripts/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': MEDIA_ROOT + '/javascripts'}, name='javascripts'),
url(r'^static/images/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': MEDIA_ROOT + '/images'}, name='images'),
url(r'^static/stylesheets/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': MEDIA_ROOT + '/stylesheets'}, name='stylesheets'),
url(r'^static/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': MEDIA_ROOT}, name='static'),
(r'^admin/', include(admin.site.urls)),
url(r'^/?$', 'content.views.index', name='root-url'),
url(r'^(?P<id>[0-9]{2,5})/(?P<slug>[a-z\-]+)/?$', 'content.views.show', name='show-url'),
)
Apache:
DocumentRoot "/var/www/django/beta.example.com/site"
<Location "/">
allow from all
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE site.settings
PythonOption django.root /
PythonDebug On
PythonPath "['/var/www/django/beta.example.com', '/var/www/django/beta.example.com/site'] + sys.path"
</Location>
<Location "/static" >
SetHandler none
</Location>
I have no idea what's wrong.
Not sure if that will solve your problem but in my site.conf for django I had to comment the line:
PythonOption django.root /
to make it work.
You really don't want to be using mod_python for deployment. I highly suggest moving to mod_wsgi for Django depoyment.
I'm just throwing this out there, but you have to enable the django admin middleware in your settings file. It's there but commented out right out of the box. If you've done that I don't have any idea what your problem is.

Categories

Resources