Setting Up an Isolated Python Environment and Building a Basic Django Project

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 commands
  • lib_mgmt/ — configuration package
    • __init__.py — marks as a Python package
    • settings.py — project-wide settings
    • urls.py — URL routing table
    • wsgi.py — WSGI server hook (used in deployment)

App Generation

Inside the project root, run:

python manage.py startapp catalog

Resulting layout:

  • __init__.py — package marker
  • tests.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:

  1. Declare models in models.py
  2. Generate migration files
  3. Apply migrations to create tables
  4. 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>

Tags: python Virtual Environment Django web development ORM

Posted on Fri, 24 Jul 2026 16:25:24 +0000 by mpower