Hello World - on Shared Host
In the previous chapters, we've learned how to setup "Hello World" example on a local host.
In this chapter, we'll do it on a shared host environment.
"Although WSGI is the preferred deployment platform for Django, many people use shared hosting, on which protocols such as FastCGI, SCGI or AJP are the only viable options." - from How to use Django with FastCGI, SCGI, or AJP
Another reference: Using Django with FastCGI.
$ mkdir ~/python $ cd ~/python $ wget http://www.python.org/ftp/python/2.7.2/Python-2.7.2.tgz $ tar zxfv Python-2.7.2.tgz $ rm -rf Python-2.7.2.tgz $ find ~/python -type d | xargs chmod 0755 $ cd Python-2.7.2 $ ./configure --prefix=$HOME/python $ make $ make install $ cd .. $ rm -rf Python-2.7.2
Add the following lines of code to ~/.bashrc and do source it:
export PATH=$HOME/python/bin:$PATH source ~/.bashrc
$ wget http://pypi.python.org/packages/source/s/setuptools/setuptools-0.6c11.tar.gz $ tar xzvf setuptools-0.6c11.tar.gz $ rm setuptools-0.6c11.tar.gz $ cd setuptools-0.6c11 $ python setup.py install $ cd .. $ rm -rf setuptools-0.6c11
$ wget http://pypi.python.org/packages/source/p/pip/pip-1.2.1.tar.gz $ tar xzvf pip-1.2.1.tar.gz $ rm pip-1.2.1.tar.gz $ cd pip-1.2.1 $ python setup.py install $ cd .. $ rm -rf pip-1.2.1
$ pip install Django $ pip install flup $ pip install MySQL-python
We can find where the Django has been installed:
$ python Python 2.7.2 (default, Jun 11 2014, 13:22:49) [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux3 Type "help", "copyright", "credits" or "license" for more information. >>> import django >>> django <module 'django' from '/home2/bogotob1/python/lib/python2.7/site-packages/django/__init__.pyc'>
$ mkdir ~/djangoproject $ cd ~/djangoproject $ django-admin.py startproject djangoproject $ cd ~/public_html/djangoproject
Note that the name (djangoproject) itself doesn't matter. We can use any name.
Then, we need to create a simple FCGI program under our ~/public_html/djangoproject/ directory. It will be executed that will dispatch web requests to our Django site. So, let's make djangoproject.fcgi file.
#!/home/your_username/python/bin/python import sys, os sys.path.insert(0, "/home/username/python") sys.path.insert(13, "/home/username/djangoproject") os.environ['DJANGO_SETTINGS_MODULE'] = 'djangoproject.settings' from django.core.servers.fastcgi import runfastcgi runfastcgi(method="threaded", daemonize="false")
Change the file permission:
$ chmod 0755 djangoproject.fcgi
Let's make a Django Application (djangoapp):
$ python manage.py startapp djangoapp
We need to create .htaccess file under the root directory of our Django project which is ~/public_html/djangoproject:
$ cd ~/public_html/djangoproject
Add the following to .htaccess:
AddHandler fcgid-script .fcgi RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ mysite.fcgi/$1 [QSA,L]
~/public_html/djangoproject/djangoproject.fcgi file should look like this:
#!/home/directory/bin/python import sys, os sys.path.insert(0, "/home/directory/python") sys.path.insert(13, "/home/directory/djangoproject") os.environ['DJANGO_SETTINGS_MODULE'] = 'djangoproject.settings' from django.core.servers.fastcgi import runfastcgi runfastcgi(method="threaded", daemonize="false")
# djangoproject/urls.py from django.conf.urls import patterns, include, url from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', # Examples: url(r'^$', 'djangoapp.views.home', name='home'), # url(r'^blog/', include('blog.urls')), url(r'^admin/', include(admin.site.urls)), )
# djangoapp/views.py from django.shortcuts import render from django.http import HttpResponse def home(request): return HttpResponse("Hello World")
As shown in the introduction, we get this on our browser:
Until this section, we set the root directory as ~/public_html/djangoproject. However, we can switch it to any directory, for example, we can use ~/public_html/dj by putting the following two files into the root folder: ~/public_html/dj/djangoproject.fcgi and ~/public_html/dj/.htaccess. The contents of the files remain the same:
~/public_html/dj/djangoproject.fcgi:
#! /home2/bogotob1/python/bin/python import sys, os sys.path.insert(0, "/home2/bogotob1/python") sys.path.insert(13, "/home2/bogotob1/djangoproject") os.environ['DJANGO_SETTINGS_MODULE'] = 'djangoproject.settings' from django.core.servers.fastcgi import runfastcgi runfastcgi(method="threaded", daemonize="false")
~/public_html/dj/.htaccess:
# django AddHandler fcgid-script .fcgi RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ djangoproject.fcgi/$1 [QSA,L]
The urls of the two pictures below are defined in ~/djangoproject/djangoproject/urls.py (remains the same, not modified):
from django.conf.urls import patterns, include, url from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', # Examples: url(r'^$', 'djangoapp.views.home', name='home'), # url(r'^blog/', include('blog.urls')), url(r'^admin/', include(admin.site.urls)), )
We can make the home view dynamic by modifying the ~/djangoproject/djangoapp/views.py:
from django.http import HttpResponse def home(request): name = "Bogotobogo Django" html = "<html><body>Hello %s </body></html>" % name return HttpResponse(html)
The third line of home() within the view constructs an HTML response using Python's "format-string" capability. The %s within the string is a placeholder, and the percent sign after the string means "Replace the %s in the preceding string with the value of the variable name." This will result in an HTML string such as "
Hello Bogotobogo Django.". Finally, the view returns an HttpResponse object that contains the generated response$ cd djangoapp $ mkdir -p templates/helloDJ $ touch templates/helloDJ/base.html
The base.html looks like this:
<html> <head> <title>This is Hello World app!</title> </head> <body> <h1>Welcome to Django at bogotobogo.com</h1> {% block content %} {% endblock %} </body> </html>
Everything is a normal html except for the {% block %} part. Djangle template language provides us dynamic contents and something will happen in the block portion. Actually, Django equips us for tags, filters, and output.
We may want to create another template called home.html:
{% extends "helloDJ/base.html" %} {% block content %} {{ Testing }} {{ HelloHello }} {% endblock %}
This demonstrates the inheritance of the template. The extends block tag means home.html will be shown inside base.html. The two braces "{{" and "}}" are basically a print statement.
Our base.html will stay with little change throughout several html pages. But the extension will take any specifics of a certain page within the frame of the base.html. In other words, any block in home.html will show up in the same named block in base.html
.The {{ HelloHello }} will output the variable HelloHello passed by the views. So, we need to go back and fix our views.py. With the following views.py:
from django.shortcuts import render_to_response def home(request): return render_to_response("helloDJ/home.html", {"Testing" : "Django Template Inheritance ", "HelloHello" : "Hello World - Django"})
we get the the page shown below:
Note that the HelloHello is a variable and it's a key for dictionary feed for the template. Django will take over and properly render a page for us.
From stackoverflow.
- response = HttpResponse("Text of a web page.")
This will create a new HttpResponse object with HTTP code 200 (OK), and the content passed to the constructor. In General, we should only use this for really small responses (like an AJAX form return value, if its really simple - just a number or so). - HttpResponseRedirect("http://example.com/")
This will create a new HttpResponse object with HTTP code 302 (Found/Moved temporarily). This should be used only to redirect to another page (e.g. after successful form POST)
class HttpResponseRedirect : The constructor takes a single argument -- the path to redirect to. This can be a fully qualified URL (e.g. 'http://www.yahoo.com/search/') or an absolute URL with no domain (e.g. '/search/'). Note that this returns an HTTP status code 302. - render_to_response(template[, dictionary][, context_instance][, mimetype]) :
This renders a given template with a given context dictionary and returns an HttpResponse object with that rendered text.
This is a call to render a template with given dictionary of variables to create the response for us. This is what we should be using most of the time, because we want to keep our presentation logic in templates and not in code.
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization