Python Django Web Development - kimduho/webdev GitHub Wiki

Python Django Web Development

Requirements and Setup

  • Requirements
$ hostname; // check hostname
$ hostname -f; /// check hostname with fully qualified domain name (FQDN)
$ sudo yum install python mysql
$ sudo yum install httpd httpd-devel
$ rpm -qa | grep httpd
$ sudo updatedb; locate apxs
/usr/bin/apxs
/usr/share/man/man1/apxs.1.gz
$ sudo yum install mod_wsgi
$ python setup.py install; // install 'pip'
$ pip install mod_wsgi; // or
$ sudo yum install mod_wsgi-httpd; // basically, this is also possible
  • Installation
$ pip install django
$ pip install django-admin-tools
  • Checks
$ mod_wsgi-express start-server; // check if mod-wsgi is installed properly, or alternately
$ mod_wsgi-express start-server --port 8001; // change the port to 8001 instead of 8000
$ wget http://localhost:8000/
$ mod_wsgi-express setup-server wsgi.py --port=80 \
    --user www-data --group www-data \
    --server-root=/etc/mod_wsgi-express-80;
$ /etc/mod_wsgi-express-80/apachectl start
$ /etc/mod_wsgi-express-80/apachectl stop
$ /etc/mod_wsgi-express-80/apachectl restart
  • Using mod_wsgi express with Django
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'mod_wsgi.server',
)
$ python manage.py runmodwsgi
  • django-admin-bootstrapped
$ pip install django-admin-bootstrapped;
  • add into INSTALLED_APPS before 'django.contrib.admin' as follows:
'django_admin_bootstrapped',

Basics

  • django-admin
$ djang-admin
Type 'django-admin help <subcommand>' for help on a specific subcommand.

Available subcommands:

[django]
    check
    compilemessages
    createcachetable
    dbshell
    diffsettings
    dumpdata
    flush
    inspectdb
    loaddata
    makemessages
    makemigrations
    migrate
    runfcgi
    runserver
    shell
    showmigrations
    sql
    sqlall
    sqlclear
    sqlcustom
    sqldropindexes
    sqlflush
    sqlindexes
    sqlmigrate
    sqlsequencereset
    squashmigrations                                                                                                                                         
    startapp                                                                                                                                                 
    startproject
    syncdb
    test
    testserver
    validate
Note that only Django core commands are listed as settings are not properly configured (error: Requested setting INSTALLED_APPS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.).
  • hello django project
$ django-admin.py startproject MyApp; // create a new <MyApp> project
$ cd ./myapp; tree;
.
├── db.sqlite3; // default database (MySQL / SQLite 3 / PostgreSQL) settings
├── manage.py; // main program
└── myapp
    ├── __init__.py; // treat the directory as a package (or a group of modules)
    ├── settings.py; // Settings/configuration
    ├── urls.py; // django website urls
    └── wsgi.py

1 directory, 5 files
$ python manage.py syncdb; // database synchronization (delete database and recreate tables with new model)
Operations to perform:
  Synchronize unmigrated apps: staticfiles, messages
  Apply all migrations: admin, contenttypes, auth, sessions
Synchronizing apps without migrations:
  Creating tables...
    Running deferred SQL...
  Installing custom SQL...
Running migrations:
  No migrations to apply.

You have installed Django's auth system, and don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (leave blank to use 'duho'): duho
Email address: [email protected]
Password: 
Password (again): 
Superuser created successfully.
$ python manage.py migrate; // database migration
$ python manage.py runserver; // or start django web server with the port 8080
$ python manage.py runserver 8090; // or start with the specific port 8090
$ python manage.py runserver 0.0.0.0:8090;
$ wget http://localhost:8090/;
  • django shell
$ python ./manage.py shell;
  • simple view test
$ vi ./myapp/views.py;
from django.http import HttpResponse
import datetime

def test(request):
    return HttpResponse('Hello, Duho!')

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>Current time is %s.</body></html>" % now
    return HttpResponse(html)

def hours_plus(request, offset):
    offset = int(offset)
    dt = datetime.datetime.now() + datetime.timedelta(hours=offset)
    html = "<html><body>In %s hour(s), it will be %s.</body></html>" %(offset, dt)
    return HttpResponse(html)
$ vi ./myapp/urls.py;
urlpatterns = [
    url(r'^test/$', 'myapp.views.test', name='test'),
    url(r'^time/$', 'myapp.views.current_datetime', name='time'),
    url(r'^time/hoursplus/(\d+)/$', 'myapp.views.hours_plus', name='time'),
]
$ python ./manage.py runserver 8090;
$ wget http://localhost:8090/test/;
$ wget http://localhost:8090/time/;
$ wget http://localhost:8090/time/hoursplus/10/;
  • simple template (html form) test
  • django shell test
$ python ./manage.py shell;
>>> from django.Template import Template, Context
>>> t = Template("My name is {{ name }}.")
>>> print t
<django.template.Template object at 0xa8c3e35d>
>>> c = Context({"name": "Duho"})
>>> t.render(c)
'My name is Duho.'
>>> person = {'name': 'Duho', 'age': '30'}
>>> person.name
Duho
>>> t2 = Template('{{ person.name }} is {{ person.age }} years old.')
>>> c2 = Context({'person': person})
>>> t2.render(c2)
'Duho is 30 years old.'
>>> class Person(object):
...     def __init__(self, first_name, last_name):
...         self.first_name, self.last_name = first_name, last_name
>>> t3 = Template('Hello, {{ person.first_name }} {{ person.last_name }}.')
>>> c3 = Context({'person': Person('Duho', 'Kim')})
>>> t3.render(c3)
'Hello, Duho Kim.'
  • example: Inline Template
$ vi ./myapp/views.py
from django.template import Template, Context
from django.http import HttpResponse
import datetime

def current_datetime_template(request):
    now = datetime.datetime.now()
    t = Template("<html><body>Current time is {{ current_date }}.</html></body>")
    html = t.render(Context({'current_date': now}))
    return HttpResponse(html)
$ vi ./myapp/urls.py
urlpatterns = [
    url(r'^time_t/$', 'myapp.views.current_datetime_template', name='time'),
]
$ python ./manage.py runserver 8090;
$ wget http://localhost:8090/time_t/;
  • example: Template file
$ mkdir -p ./myapp/templates/;
$ vi ./myapp/templates/currentdateView.html;
<html>
<body>
    <p>Current Time: {{ current_date }}.<br/></p>
</body>
</html>
$ vi ./myapp/views.py
from django.template import Template, Context, loader
from django.http import HttpResponse
import datetime

def current_datetime_template2(request):
    now = datetime.datetime.now()
    t = loader.get_template("currentdateView.html")
    html = t.render(Context({'current_date': now}))
    return HttpResponse(html)
$ vi ./myapp/urls.py
urlpatterns = [
    url(r'^time_t2/$', 'myapp.views.current_datetime_template2', name='time'),
]
$ vi ./myapp/settings.py
...
TIME_ZONE = 'America/Los_Angeles'   # TIME_ZONE = 'UTC'  # TIME_ZONE = 'America/Chicago'
...
PROJECT_ROOT = os.path.dirname(__file__)
SETTINGS_PATH = os.path.normpath(PROJECT_ROOT)
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(SETTINGS_PATH, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
...
$ python ./manage.py runserver 8090;
$ wget http://localhost:8090/time_t2/;
  • example: Template file + render_to_response()
$ vi views.py
from django.shortcuts import render_to_response
...
def current_datetime_template_render(request):
    now = datetime.datetime.now()
    return render_to_response("currentdateView.html", Context({'current_date': now}))
...
$ vi urls.py
urlpatterns = [
    url(r'^time_tr/$', 'myapp.views.current_datetime_template_render', name='time'),
]
$ python ./manage.py runserver 8090;
$ wget http://localhost:8090/time_tr/;
  • example: url patterns + input variations
$ mkdir ./test/; vi ./test/admin.py;
from django.contrib import admin

# Register your models here.
$ vi ./test/__init__.py;

$ vi ./test/models.py;
from django.db import models

# Create your models here.
$ vi ./test/views.py;
from django.shortcuts import render

# Create your views here.
$ vi ./test/urls.py;
from keys import authentication

__author__ = 'Duho Kim'

from django.conf.urls import url

urlpatterns = [
    #ex: /test/validate/
    url(r'^(?P<val_type>\s+)$', example.validate0, name="validate0"),
    url(r'^validate1/$', example.validate1, name="validate1"),
    url(r'^validate2/(\d+)/(\d+)$', example.validate2, name="validate2"),
    url(r'^validate3/(?P<val_type>\s+)/(?P<key>[0-9]+)$', example.validate3, name="validate3"),

    # ex: /test/532/
    #url(r'^(?P<val_type>[0-9]+)/$', example.validate4, name='validate4'),
    url(r'^(?P<val_type>\d+)/$', example.validate4, name='validate4'),

    # ex: /test/validate5/532/
    url(r'^validate5/(?P<val_type>[0-9]+)/$', example.validate5, name='validate5'),

    # ex: /test/validate6/s532a/
    # ex: /test/validate6/s532a
    url(r'^validate6/(?P<val_type>\w+)/+$', example.validate6, name='validate6'),

    # ex: /test/validate7/key/s8329a7a/
    url(r'^validate7/(?P<val_type>\w+)/(?P<key_val>\w+)/+$', example.validate7, name='validate7'),

    # ex: /test/validate8/key/
    url(r'^validate8/(?P<val_type>\s+)/$', example.validate8, name='validate8'),
]
$ vi ./test/example.py;
#-*- coding: utf-8 -*-
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

__author__ = 'Duho Kim'

@csrf_exempt
def validate(request, val_type, key_val):    # variable names should be same with those in urls.py
    response = "val_type: " + val_type + ", key_val: " + key_val
    return HttpResponse(response)
$ vi ./myapp/settings.py;
...
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'test', # add sub directory 'test'
)
...
$ from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'test/', include('test.urls')),     # include sub directory 'test'
    url(r'^admin/', include(admin.site.urls)),
]
$ tree
.
├── db.sqlite3
├── test
│   ├── admin.py
│   ├── example.py
│   ├── __init__.py
│   ├── models.py
│   ├── urls.py
│   └── views.py
├── manage.py
├── manager
└── myapp
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py
$ python ./manage.py migrate; python ./manage.py runserver;
$ wget http://localhost:8000/test/validate/key/s3297d32/;
⚠️ **GitHub.com Fallback** ⚠️