按照https://www.ibm.com/developerworks/cn/linux/l-django/#resources,http://www.ibm.com/developerworks/linux/library/l-django/?S_TACT=105AGX52&S_CMP=cn-a-l
上面的步骤创建django项目
centos6.2 python2.6.6 sqlite3 django1.4
一、执行
django-amdin.py startproject djproject
得到
djproject/
|-- djproject
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| `-- wsgi.py
`-- manage.py
注意:这里manage.py在djproject的根目录下,而settings.py等其它py文件在子目录djproject下面。这与上面的参照页面不符,这是django1.4较之前版本更新的地方。
Django 1.4 ships with an updated default project layout and manage.py filefor the startproject management command. These fix some issues withthe previousmanage.py handling of Python import paths that caused doubleimports, trouble moving from development to deployment, and otherdifficult-to-debug path issues.
二、修改settings.py
将原来的INSTALL_APP部分改为
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'djproject.jobs',
# Uncomment the next line to enable the admin:
# 'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
)
二、使用manage.py创建app
注意:此处要在子目录djproject里面执行命令
进入子目录djproject,执行
python ../manage.py startapp jobs
得到
djproject/
|-- djproject
| |-- __init__.py
| |-- __init__.pyc
| |-- jobs
| | |-- __init__.py
| | |-- models.py
| | |-- tests.py
| | `-- views.py
| |-- settings.py
| |-- settings.pyc
| |-- urls.py
| `-- wsgi.py
`-- manage.py
这样jobs与settings.py在同一级目录下,避免后面出现Error: No module named jobs的错误。具体是否可以通过修改配置文件来避免这类错误,我还不知道。只是原来在与manage.py同一级的目录下创建jobs时,出现了这个错误。然后改为在子目录下创建错误就消失了。
三、修改jobs下面的models.py
from django.db import models
class Location(models.Model):
city = models.CharField(max_length=50)
state = models.CharField(max_length=50, null=True, blank=True)
country = models.CharField(max_length=50)
def __str__(self):
if self.state:
return "%s, %s, %s" % (self.city, self.state, self.country)
else:
return "%s, %s" % (self.city, self.country)
class Job(models.Model):
pub_date = models.DateField()
job_title = models.CharField(max_length=50)
job_description = models.TextField()
location = models.ForeignKey(Location)
def __str__(self):
return "%s (%s)" % (self.job_title, self.location)
注意:这里也有与参照页面不同的地方,在这里使用的是max_length而不是maxlength,自1.0以后django的变化参照
Backwards-incompatible changes
四、在子目录下创建文件夹db,用于存放数据库,修改settings.py,配置数据库项
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'db/tdata.db', # Or path to database file if using sqlite3.
'USER': '', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
注意:此处需使用django.db.backends.sqlite3而不能使用sqlite3,否则后面出现错误
django.core.exceptions.ImproperlyConfigured: 'sqlite3' isn't an available database backend.
Try using django.db.backends.sqlite3 instead.
Error was: No module named base
执行
python ../manage.py sql jobs
得到
BEGIN;
CREATE TABLE "jobs_location" (
"id" integer NOT NULL PRIMARY KEY,
"city" varchar(50) NOT NULL,
"state" varchar(50),
"country" varchar(50) NOT NULL
)
;
CREATE TABLE "jobs_job" (
"id" integer NOT NULL PRIMARY KEY,
"pub_date" date NOT NULL,
"job_title" varchar(50) NOT NULL,
"job_description" text NOT NULL,
"location_id" integer NOT NULL REFERENCES "jobs_location" ("id")
)
;
COMMIT;
tree命令查看目录变化
djproject/
|-- djproject
| |-- db
| | `-- tdata.db
db目录下已经有数据库文件tdata.db了
五、通过python shell使用django API进行操作
python manage.py shell命令操作的时候,然后from jobs.models import Job,有可能会出现
>>> from jobs.models import Job
Traceback (most recent call last):
File "<console>", line 1, in <module>
ImportError: No module named jobs.models
找不到jobs.models这时,可以使用四种方法解决
1 在manage.py所在目录运行python,比如不能用python ../manage.py shell
2 在settings.py中加入jobs所在的路径,如
import sys
sys.path.append('/home/python/djproject/djproject')
3 将程序即jobs移动到与manage.py同一级目录下
4 使用绝对路径from djproject.jobs.models import Job
方法2和方法3任选一种,新版本的django推荐第3种,其实在创建程序时就可以指定其所在位置:参照updated-default-project-layout-and-manage-py
django-admin.py startapp myapp /path/to/new/app
django-admin.py startproject myproject /path/to/new/project
====
这里采用第1、3方法,将jobs移动到与manage.py相同的目录下,并修改settings.py中的INSTALL_APP中djproject.jobs为jobs,而且数据库中NAME却要由db/tdata.db改写成djproject/db/tdata.db,否则会找不到数据库文件,出现OperationalError: unable to open database file。然后在该目录执行
python manage.py shell
六、使用数据库API
打印所有job
>>> from jobs.models import Job
>>> for job in Job.objects.all():
... print job
排除和过滤职位
>>> from jobs.models import Job
>>> from datetime import datetime
>>> q1 = Job.objects.filter(pub_date__gte=datetime(2006, 1, 1))
>>> q2 = Job.objects.exclude(pub_date__lt=datetime(2006, 1, 1))
统计记录数
>>> from jobs.models import Job
>>> print "Count = ", Job.objects.count()
Count = 0
添加数据并保存
>>> from jobs.models import Job, Location
>>> Location.objects.all()
[]
>>> from django.utils import timezone
>>> from jobs.models import Job, Location
>>> Location.objects.all()
[]
>>> l = Location(id=1, city="NewYork", state="NewYork", country="US")
>>> l.save()
>>> l.id
1
>>> l.city
'NewYork'
>>> l.state
'NewYork'
>>> l.city = "New York"
>>> l.save
<bound method Location.save of <Location: New York, NewYork, US>>
>>> l.save()
>>> Location.objects.all()
[<Location: New York, NewYork, US>]
>>>
七、管理员工具
python ../manage.py syncdb
创建管理工具的超级用户
Creating tables ...
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_user_permissions
Creating table auth_user_groups
Creating table auth_user
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table jobs_location
Creating table jobs_job
You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (leave blank to use 'python'): djroot
E-mail address: djroot@v.python.centos
Password:
Password (again):
Superuser created successfully.
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
管理工具是 Django 提供的一个应用程序。与 jobs
应用程序一样,在使用之前也必须进行安装。使用web管理工具,可以使用python的简易web服务器,可以先测试一下使用python ../manage.py runserver,会提示使用http://127.0.0.1:8000访问,访问页面出现It worked,就说明服务器正常。如果想使用其它IP或端口可以像这样python ../manage.py runserver 10.7.6.8:8080就是使用10.7.6.8和8080端口了。
修改settings.py
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
#'djproject.jobs',
'jobs',
# Uncomment the next line to enable the admin: 'django.contrib.admin', # Uncomment the next line to enable admin documentation: # 'django.contrib.admindocs',)
每个应用程序占用一个表格,所以在使用前要为它们创建数据库表
安装管理工具自己的数据库模型,执行
[root@python djproject]# python ../manage.py syncdb
Creating tables ...
Creating table django_admin_log
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
[root@python djproject]#
使管理工具可以通过URL进行管理,修改urls.py
from django.conf.urls import patterns, include, url
# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'djproject.views.home', name='home'),
# url(r'^djproject/', include('djproject.foo.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
# url(r'^admin/', admin.site.urls),
url(r'^admin/', admin.site.urls),
)
使用测试服务器来查看管理工具
[root@python djproject]# python ../manage.py runserver
Validating models...
0 errors found
Django version 1.4, using settings 'djproject.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
使用http://127.0.0.1:8000/admin并登录,看到以下结果
注意:这里要使用admin,应该跟配置文件夹里r'^admin/'有关
在jobs目录下创建admin.py
#admin.py
from django.contrib import admin
from jobs.models import Location
class LocationAdmin(admin.ModelAdmin):
list_display = ('city', 'state', 'country')
admin.site.register(Location, LocationAdmin)

创建添加页面,使用list_display后,管理页面就有添加页面了,如下
这里使用fieldset创建添加页面,修改admin.py
#admin.py
from django.contrib import admin
from jobs.models import Location
from jobs.models import Job
class JobAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['pub_date','job_title','job_description']}),
('More info', {'fields': ['location'], 'classes': ['collapse']}),
]
list_display = ('job_title', 'job_description', 'pub_date')
class LocationAdmin(admin.ModelAdmin):
list_display = ('city', 'state', 'country')
admin.site.register(Job,JobAdmin)
admin.site.register(Location, LocationAdmin)

九、创建视图
The first step of writing views is to design your URL structure. You do this by creating a Python module, called a URLconf. URLconfs are how Django associates a given URL with given Python code.
When a user requests a Django-powered page, the system looks at the ROOT_URLCONF setting, which contains a string in Python dotted syntax. Django loads that module and looks for a module-level variable called urlpatterns, which is a sequence of tuples in the following format:
(regular expression, Python callback function [, optional dictionary])
Django starts at the first regular expression and makes its way down the list, comparing the requested URL against each regular expression until it finds one that matches.
When it finds a match, Django calls the Python callback function, with an HttpRequest object as the first argument, any "captured" values from the regular expression as keyword arguments, and, optionally, arbitrary keyword arguments from the dictionary (an optional third item in the tuple).
这个职位公告板应用程序会在启动时打开一个索引和一个详细视图,它们可以通过以下的 URL 映射进行访问:
/jobs 索引视图:显示最近的 10 个职位
/jobs/1 详细视图:显示 ID 为 1 的职位信息
这两个视图(索引视图和详细视图)都是在这个 jobs 应用程序的 views.py 模块中实现的。在项目的 urls.py 文件中实现这种配置看起来如下所示:
url(r'^jobs/$', 'jobs.views.index'),
url(r'^jobs/(?P<job_id>\d+)/$', 'jobs.views.detail'),
使用http://127.0.0.1:8000/jobs出错
Request URL: http://127.0.0.1:8000/jobs
Django Version: 1.4
Exception Type: ViewDoesNotExist
Exception Value: Could not import jobs.views.index. View does not exist in module jobs.views.
视图是一个简单的 Python 方法,它接受一个请求对象,负责实现:
任何业务逻辑(直接或间接)
上下文字典,它包含模板数据
使用一个上下文来表示模板
响应对象,它将所表示的结果返回到这个框架中都已经正确设置。
在 Django 中,当一个 URL 被请求时,所调用的 Python 方法称为一个视图(view),这个视图所加载并呈现的页面称为模板(template)。由于这个原因,Django 小组将 Django 称为一个 MVT(model-view-template)框架。另一方面,TurboGears 把自己的方法称作控制器(controller),将所呈现的模板称为视图(view),因此缩写也是 MVC。其区别在于广义的语义,因为它们所实现的内容是相同的。
最简单的视图可能会返回一个使用字符串初始化过的 HttpResponse 对象。创建下面的方法,并生成一个 /jobs HTTP 请求,以确保 urls.py 和 views.py 文件都已经正确设置。
修改jobs目录下的views.py
# Create your views here.
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the job index.")
def detail(request, job_id):
return HttpResponse("You're looking at job %s." % job_id)
http://127.0.0.1:8000/jobs/
Hello, world. You're at the job index.
http://127.0.0.1:8000/jobs/1/
You're looking at job 1.
下面的代码将获取最近的 3 个职位,并通过一个模板呈现出来,然后返回响应。views.py
# Create your views here.
from django.template import Context, loader
from jobs.models import Job
from django.http import HttpResponse
def index(request):
object_list = Job.objects.order_by('-pub_date')[:1]
t = loader.get_template('jobs/job_list.html')
c = Context({
'object_list': object_list,
})
return HttpResponse(t.render(c))
def detail(request, job_id):
return HttpResponse("You're looking at job %s." % job_id)
没有模板文件,会出现下面的错误
Exception Type: TemplateDoesNotExist
Exception Value: jobs/job_list.html
相应的模板文件job_list.html,创建模板的细节见下节
{% block title %}Job List{% endblock %}
{% block content %}
<h1>Job List</h1>
<ul>
{% for job in object_list %}
<li><a href="{{ job.id }}">{{ job.job_title }}</a></li>
{% endfor %}
</ul>
{% endblock %}
结果为
重新修改views.py并修改details的响应内容
在上面的views.py的代码中,模板是由 jobs/job_list.html
字符串进行命名的。该模板是使用名为 object_list
的职位列表的上下文呈现的。所呈现的模板字符串随后被传递到 HTTPResponse 构造器中,后者通过这个框架被发送回请求客户机那里。
加载模板、创建内容以及返回新响应对象的步骤在下面都被 render_to_response
方法取代了。新增内容是详细视图方法使用了一个get_object_or_404
方法,通过该方法使用所提供的参数获取一个 Job 对象。如果没有找到这个对象,就会触发 404 异常。这两个方法减少了很多 Web 应用程序中的样板代码。
# Create your views here.
from django.shortcuts import get_object_or_404, render_to_response
from jobs.models import Job
def index(request):
object_list = Job.objects.order_by('-pub_date')[:3]
return render_to_response('jobs/job_list.html', {'object_list': object_list})
def detail(request, job_id):
job = get_object_or_404(Job, pk=job_id)
return render_to_response('jobs/job_detail.html', {'object': job})
十、创建模板
在djproject项目目录下创建目录templates
djproject/
|-- db
|-- djproject
|-- jobs
|-- manage.py
`-- templates
templates下创建目录jobs
修改settings.py
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
'templates',
)
在templates与templates/jobs目录下创建模板文件
templates/base.html
<!DOCTYPE html PUBLIC "-//w3c//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" >
<head>
<title>Company Site: {% block title %}Page{% endblock %}</title>
{% block extrahead %}{% endblock %}
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
templates/jobs/base.html
{% extends "base.html" %}
{% block extrahead %}
<style>
body {
font-style: arial;
}
h1 {
text-align: center;
}
.job .title {
font-size: 120%;
font-weight: bold;
}
.job .posted {
font-style: italic;
}
</style>
{% endblock %}
templates/jobs/job_list.html
{% extends "jobs/base.html" %}
{% block title %}Job List{% endblock %}
{% block content %}
<h1>Job List</h1>
<ul>
{% for job in object_list %}
<li><a href="{{ job.id }}">{{ job.job_title }}</a></li>
{% endfor %}
</ul>
{% endblock %}
templates/jobs/job_detail.html
{% extends "jobs/base.html" %}
{% block title %}Job Detail{% endblock %}
{% block content %}
<h1>Job Detail</h1>
<div class="job">
<div class="title">
{{ job.job_title }}
-
{{ job.location }}
</div>
<div class="posted">
Posted: {{ job.pub_date|date:"d-M-Y" }}
</div>
<div class="description">
{{ job.job_description }}
</div>
</div>
{% endblock %}
所有代码:详细
使用通用视图,参照generic view
djproject/urls.py
from django.conf.urls import patterns, include, url
#from django.conf.urls.defaults import *
from django.views.generic import DetailView, ListView
from jobs.models import Job
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$',
ListView.as_view(
queryset=Job.objects.order_by('-pub_date')[:3],
context_object_name='job_list',
template_name='jobs/job_list.html')),
url(r'^(?P<pk>\d+)/$',
DetailView.as_view(
model=Job,
template_name='jobs/detail.html')),
# url(r'^admin/', admin.site.urls),
url(r'^admin/', admin.site.urls),
)
jobs/views.py
# Create your views here.
from django.shortcuts import get_object_or_404, render_to_response
from jobs.models import Job
#def index(request):
# object_list = Job.objects.order_by('-pub_date')[:3]
# return render_to_response('jobs/job_list.html', {'object_list': object_list})
#def detail(request, job_id):
# j = get_object_or_404(Job, pk=job_id)
# return render_to_response('jobs/job_detail.html', {'job': j})
访问使用http://127.0.0.1:8000/
参考:Django tutorial 01 https://docs.djangoproject.com/en/dev/intro/tutorial01/
02https://docs.djangoproject.com/en/dev/intro/tutorial02/
03https://docs.djangoproject.com/en/dev/intro/tutorial03/
04 https://docs.djangoproject.com/en/dev/intro/tutorial04/
http://www.tdd-django-tutorial.com/tutorial/1/
https://docs.djangoproject.com/en/dev/releases/1.4/#updated-default-project-layout-and-manage-py