Isolated Python Runtime
When developing in Python, installing packages via pip pulls them into a global location like /usr/local/lib/pythonX.Y/site-packages. This becomes problematic when multiple projects require conflicting versions of the same package. An isolated environment ensures each project operates independently.
All such environments reside under the hidden directory ~/.virtualenvs.
Creation Steps
Install the tooling:
pip install virtualenv
pip install virtualenvwrapper
Create a new environment:
mkvirtualenv py_web
To target a specific interpreter:
mkvirtualenv -p /usr/bin/python3 py_web
Deactivation and Removal
Leave the environment:
devactivate
Remove it entirely:
rmvirtualenv py_web
Adding Django
Install a fixed version:
pip install django==1.8.2
Scaffolding a Book Management Project
A Django project groups functionality into apps, each representing a distinct module. For example, create a project named lib_mgmt containing an app catalog for handling books and their heroes.
Project Initialization
Choose a user-writable path:
cd ~/Desktop
mkdir dev_projects
In PyCharm: File → New Project, select the above directory, and confirm creation.
Key generated items:
manage.py— entry point for runing commandslib_mgmt/— configuration package__init__.py— marks as a Python packagesettings.py— project-wide settingsurls.py— URL routing tablewsgi.py— WSGI server hook (used in deployment)
App Generation
Inside the project root, run:
python manage.py startapp catalog
Resulting layout:
__init__.py— package markertests.py— placeholder for test cases- Other files (
models.py,views.py, etc.) will be used later.
Registering the App
Add 'catalog' to the INSTALLED_APPS tuple in lib_mgmt/settings.py:
INSTALLED_APPS = (
...
'catalog',
)
Development Server
Launch locally:
python manage.py runserver
Defaults to 127.0.0.1:8000. Omitting host/port uses these defaults. Changes to Python files trigger automatic reload; stop with Ctrl+C.
Modeling Data
Django’s ORM lets you define data structures as Python classes instead of writing raw SQL.
Steps:
- Declare models in
models.py - Generate migration files
- Apply migrations to create tables
- Use model instances for CRUD operations
Model Definitions
In catalog/models.py:
from django.db import models
class Literature(models.Model):
name = models.CharField(max_length=20)
publish_date = models.DateField()
def __str__(self):
return f"{self.pk}"
class Protagonist(models.Model):
name = models.CharField(max_length=20)
gender = models.BooleanField()
bio = models.CharField(max_length=100)
related_book = models.ForeignKey(Literature, on_delete=models.CASCADE)
def __str__(self):
return f"{self.pk}"
A Literature can have many Protagonist entries (one-to-many).
Database Configuration
By default SQLite is used; file appears as db.sqlite3 in project root. It can be inspected via PyCharm’s database panel.
Migrations
Generate migrasion scripts:
python manage.py makemigrations
Apply them:
python manage.py migrate
Tables matching the models appear in the DB along with built-in Django tables.
Admin Interface
Automated admin pages save effort for routine data management tasks.
Localization
Set language and time zone in lib_mgmt/settings.py:
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
Superuser Creation
python manage.py createsuperuser
Visit http://127.0.0.1:8000/admin/ and log in.
Model Registration
In catalog/admin.py:
from django.contrib import admin
from .models import Literature, Protagonist
admin.site.register(Literature)
admin.site.register(Protagonist)
Refresh the admin page to see both models listed with add/edit/delete capabilities.
Customizing List Display
Extend admin.ModelAdmin to control visible columns:
class LiteratureAdmin(admin.ModelAdmin):
list_display = ['pk', 'name', 'publish_date']
class ProtagonistAdmin(admin.ModelAdmin):
list_display = ['pk', 'name', 'gender', 'bio']
admin.site.register(Literature, LiteratureAdmin)
admin.site.register(Protagonist, ProtagonistAdmin)
Views and URL Routing
The MVT pattern maps URLs to view functions that process requests and return responses.
View Definition
In catalog/views.py:
from django.http import HttpResponse
def home(request):
return HttpResponse("home")
URL Configuration
Create catalog/urls.py:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.home),
]
Include it in project’s lib_mgmt/urls.py:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^', include('catalog.urls')),
]
Visiting / renders the home view output.
Templates
Templates separate presentation from logic, allowing HTML with dynamic placeholders.
Template Setup
Create templates/catalog/home.html. Set lookup path in settings.py:
TEMPLATES[0]['DIRS'] = [os.path.join(BASE_DIR, 'templates')]
Template Syntax
Variables: {{ var_name }}
Logic blocks: {% statements %}
Example home.html:
<html>
<head><title>Books</title></head>
<body>
<h1>{{ heading }}</h1>
{% for item in items %}
{{ item }}<br>
{% endfor %}
</body>
</html>
Rendering from View
Using loader and context:
from django.http import HttpResponse
from django.template import loader, RequestContext
def home(request):
tpl = loader.get_template('catalog/home.html')
ctx = RequestContext(request, {'heading': 'Books', 'items': range(10)})
return HttpResponse(tpl.render(ctx))
Or using shortcut:
from django.shortcuts import render
def home(request):
ctx = {'heading': 'Books', 'items': range(10)}
return render(request, 'catalog/home.html', ctx)
Finalizing the Sample Project
Views Implementation
catalog/views.py:
from django.shortcuts import render
from .models import Literature
def index(request):
books = Literature.objects.all()
return render(request, 'catalog/index.html', {'book_list': books})
def detail(request, book_id):
volume = Literature.objects.get(pk=book_id)
return render(request, 'catalog/detail.html', {'volume': volume})
URL Patterns
catalog/urls.py:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index),
url(r'^(\d+)/$', views.detail),
]
Templates
templates/catalog/index.html:
<html>
<head><title>Index</title></head>
<body>
<h1>Book List</h1>
<ul>
{% for b in book_list %}
<li><a href="{{ b.id }}">{{ b.name }}</a></li>
{% endfor %}
</ul>
</body>
</html>
templates/catalog/detail.html:
<html>
<head><title>Detail</title></head>
<body>
<h1>{{ volume.name }}</h1>
<ul>
{% for p in volume.protagonist_set.all %}
<li>{{ p.name }} — {{ p.bio }}</li>
{% endfor %}
</ul>
</body>
</html>