http://blog.csdn.net/pipisorry/article/details/38964249
上篇:python web框架 - Django
安装 Django 之后,您现在应该已经有了可用的管理工具 django-admin.py。可以使用 django-admin.py来创建一个项目:
django-admin.py的命令:
# django-admin.py
Usage: django-admin.py subcommand [options] [args]
Options:
-v VERBOSITY, --verbosity=VERBOSITY
Verbosity level; 0=minimal output, 1=normal output,
2=verbose output, 3=very verbose output
--settings=SETTINGS The Python path to a settings module, e.g.
"myproject.settings.main". If this isn't provided, the
DJANGO_SETTINGS_MODULE environment variable will be
used.
--pythonpath=PYTHONPATH
A directory to add to the Python path, e.g.
"/home/djangoprojects/myproject".
--traceback Raise on exception
--version show program's version number and exit
-h, --help show this help message and exit
Type 'django-admin.py help ' for help on a specific subcommand.
Available subcommands:
[django]
check
cleanup
compilemessages
createcachetable
... ...
Note:阅读django-admin.py documentation来了解manage.py工具能做的所有事情。
在文件系统哪里创建项目:有过 PHP 编程背景的话,你可能习惯于将代码都放在 Web 服务器的文档根目录 (例如 /var/www 这样的地方)。 而在 Django 中,把任何Python代码和web server的文档根(root)放在一起并不是一个好主意。因为这样做有使人能通过网路看到你原代码的风险。
django-admin startproject VoteSite
Note:如果用的是 setup.py 工具安装的 Django , django-admin.py 应该已被加入了系统路径中。如果你使用一个trunk版本,你会在 djtrunk/django/bin下发现 django-admin.py 。你将来会常用到django-admin.py,考虑把它加到你的系统路径中去比较好。
Note: 也可以通过pycharm中 > file > new project > django > VoteSite创建新Django项目,这种方法创建的django项目还会自动生成templates 目录, templates作用在后面讲到。
# tree VoteSite |-- VoteSite | |-- __init__.py | |-- settings.py | |-- urls.py | `-- wsgi.py `-- manage.py
目录说明:(下面还有添加)
进入 VoteSite目录, 在pycharm/terminal中输入
python manage.py runserver
Note:
1. 通常情况下,你每次修改过一个文件后开发服务器都会自动载入,但是创建一个新文件却不会触发自动载入的逻辑。
2. 这时启动的服务只能在本机访问,这是因为服务只向本机(127.0.0.1:8000)提供,所以局域网的其他机器不能访问。在另一台机器上访问django开放的界面会出现Page not found (404)错误。
3.默认情况下,:djadmin:runserver 命令启动的开发服务器只监听本地 IP 的 8000 端口。如果你想改变服务器的端口,把它作为一个命令行参数传递即可。例如以下命令启动的服务器将监听 8080 端口:python manage.py runserver 8080
完成后在本机浏览器中输入127.0.0.1:8000就可以访问自己的网站了。如果正常启动,输出
python manage.py runserver 0.0.0.0:8000
Note: 如果你想改变服务器 IP ,把它和端口号一起传递即可。因此,要监听所有公共 IP 地址(0.0.0.0让其他电脑上可以访问服务器,用于多人测试,局域网内测试通过),使用:python manage.py runserver 0.0.0.0:8000
在其他电脑浏览器输入服务器/电脑的ip(Windows的用户在cmd中输入ipconfig; Unix用户输入ifconfig)及端口号,如果正常启动,输出
Start a static HTTP server in any directory
[10:26] $ python -m SimpleHTTPServer 5000
Serving HTTP on 0.0.0.0 port 5000 ...
Note:关于开发网络服务器的提示。虽然 django 自带的这个 web 服务器对于开发很方便,但是,千万不要在正式的应用布署环境中使用它。 在同一时间,该服务器只能可靠地处理一次单个请求,并且没有进行任何类型的安全审计。
{接下来说明要配置/修改的文件及作用}
# models.py (the database tables)
from django.db import models
class Book(models.Model):
name = models.CharField(max_length=50)
pub_date = models.DateField()
# views.py (the business logic)
from django.shortcuts import render_to_response
from models import Book
def latest_books(request):
book_list = Book.objects.order_by('-pub_date')[:10]
return render_to_response('latest_books.html', {'book_list': book_list})
# urls.py (the URL configuration)
from django.conf.urls.defaults import *
import views
urlpatterns = patterns('',
(r'^latest/$', views.latest_books),
)
# latest_books.html (the template)
Books
Books
{% for book in book_list %}
- {{ book.name }}
{% endfor %}
Note:不用关心语法细节;只要用心感觉整体的设计,几个文件:
这些部分松散遵循的模式称为模型-视图-控制器(MVC)。这种设计模式关键的优势在于各种组件都是 松散结合 的。这样,每个由 Django驱动 的Web应用都有着明确的目的,并且可独立更改而不影响到其它的部分。比如,开发者 更改一个应用程序中的 URL 而不用影响到这个程序底层的实现。 设计师可以改变 HTML 页面 的样式而不用接触 Python 代码。 数据库管理员可以重新命名数据表并且只需更改一个地方,无需从一大堆文件中进行查找和替换。
{这样就可以通过127.0.0.1:8000/*访问特定内容了,如127.0.0.1:8000/music}
在先前创建的 DjangoPIPI目录下的 DjangoPIPI目录新建一个 view.py 文件,并输入代码:
from django.http import HttpResponse def hello(request): return HttpResponse("Hello pipi!")
Note:
1. 这里的view还是没有和数据分开,比较low.
2. 定义一个叫做hello 的视图函数。每个视图函数至少要有一个参数,通常被叫作request。 这是一个触发这个视图、包含当前Web请求信息的对象,是类django.http.HttpRequest的一个实例。在这个示例中,我们虽然不用request做任何事情,然而它仍必须是这个视图的第一个参数。注意视图函数的名称并不重要.这个函数只有简单的一行代码: 它仅仅返回一个HttpResponse对象,这个对象包含了文本“Hello world”。
3. 一个视图就是Python的一个函数。这个函数第一个参数的类型是HttpRequest;它返回一个HttpResponse实例。为了使一个Python的函数成为一个Django可识别的视图,它必须满足这两个条件。(也有例外)
{为了绑定视图函数和URL,我们使用URLconf。通过一个详细描述的URL来显式的告诉它并且激活这个视图。URLconf 就像是 Django 所支撑网站的目录。它的本质是 URL 模式以及要为该 URL 模式调用的视图函数之间的映射表。的‘}
打开 urls.py 文件,注释掉url(r'^admin/', include(admin.site.urls))替换为以下代码:
from django.conf.urls import patterns, url from .view import hello urlpatterns = patterns('', # Examples: # url(r'^$', 'VoteSite.views.home', name='home'), # url(r'^blog/', include('blog.urls')), # url(r'^admin/', include(admin.site.urls)), url('^hello/$', hello), )
Note:
1. url函数结构: url(regex,view,kwargs=None,name=None,prefix='')
2. patterns函数的第一个参数即是view的前缀[Django的url用法]
3. 告诉 Django,所有指向 URL /hello/ 的请求都应由hello 这个视图函数来处理
4. Django在检查URL模式前,移除每一个申请的URL开头的斜杠(/)。 这意味着我们为/hello/写URL模式不用包含斜杠(/)。如果有人申请访问/hello(尾部没有斜杠/)会怎样。 因为我们的URL模式要求尾部有一个斜杠(/),那个申请URL将不匹配。 然而,默认地,任何不匹配或尾部没有斜杠(/)的申请URL,将被重定向至尾部包含斜杠的相同字眼的URL。 (这是受配置文件setting中APPEND_SLASH项控制的)
5. 把hello视图函数作为一个对象传递,而不是调用它。
整个目录结构如下:
# tree . |-- HelloWorld | |-- __init__.py | |-- __init__.pyc | |-- settings.py | |-- settings.pyc | |-- urls.py # url 配置 | |-- urls.pyc #可能没有,不要紧 | |-- view.py # 添加的视图文件 | |-- view.pyc # 编译后的视图文件 | |-- wsgi.py | `-- wsgi.pyc `-- manage.py
6.之前设置的host和port如下
'HOST': '127.0.0.1', 'PORT': '3306'否则会出错:django.db.utils.operationalerror:<2003, "can't connect to mysql server on '127.0.0.1'(winerror 10061] No connection could be made because the target machine actively refused it)")
完成后,启动 Django 开发服务器,并在浏览器访问打开浏览器并访问:127.0.0.1:8000/hello/
输出:
Note: 项目中如果代码有改动,服务器会自动监测代码的改动并自动重新载入,所以如果你已经启动了服务器则不需手动重启。
关于“404错误”
目前,我们的URLconf只定义了一个单独的URL模式: 处理URL /hello/ 。 当请求其他URL会怎么样呢?运行Django开发服务器并访问类似 http://127.0.0.1:8000/goodbye/甚至 http://127.0.0.1:8000/ (网站根目录)。 你将会看到一个 “Page not found” 页面。 因为你的URL申请在URLconf中没有定义,所以Django显示Django的404 Error页.
这个页面比原始的404错误信息更加实用。 它同时精确的告诉你Django调用哪个URLconf及其包含的每个模式。 这样,你应该能了解到为什么这个请求会抛出404错误。当然,这些敏感的信息应该只呈现给你-开发者。如果是部署到了因特网上的站点就不应该暴露 这些信息。 出于这个考虑,这个“Page not found”页面只会在调试模式(debug mode) 下 显示。
Django是怎么处理请求的
所有均开始于setting文件。当你运行python manage.pyrunserver,脚本将在于manage.py同一个目录下查找名为setting.py的文件。这个文件包含了所有有关这个Django项目的配置信息,均大写: TEMPLATE_DIRS , DATABASE_NAME, 等. 最重要的设置时ROOT_URLCONF,它将作为URLconf告诉Django在这个站点中那些Python的模块将被用到。
当访问 URL /hello/ 时,Django 根据 ROOT_URLCONF 的设置装载 URLconf 。 然后按顺序逐个匹配URLconf里的URLpatterns,直到找到一个匹配的。 当找到这个匹配 的URLpatterns就调用相关联的view函数,并把 HttpRequest 对象作为第一个参数。
一个视图功能必须返回一个HttpResponse。 一旦做完,Django将完成剩余的转换Python的对象到一个合适的带有HTTP头和body的Web Response(例如,网页内容)。
总结:
进来的请求转入/hello/.
Django通过在ROOT_URLCONF配置来决定根URLconf.
Django在URLconf中的所有URL模式中,查找第一个匹配/hello/的条目。
如果找到匹配,将调用相应的视图函数
视图函数返回一个HttpResponse
Django转换HttpResponse为一个适合的HTTP response, 以Web page显示出来
前面网页的内容一直是一样的. 每次去查看/hello/,你将会看到相同的内容,它类似一个静态HTML文件。
下面的网页是计算当前日期和时间,并返回包含这些值的HttpResponse。
view.py中加入current_datetime视图函数
import datetime from django.http import HttpResponse def hello(request): return HttpResponse("Hello pipi!") def current_datetime(request): now = datetime.datetime.now() html = "It is now %s." % now return HttpResponse(html)Note:目前HTML是有错误的,但我们这样做是为了保持例子的简短。
还要在urls.py中添加URL模式,以告诉Django由哪一个URL来处理这个视图:
from django.conf.urls import patterns, url
from .view import hello, current_datetime
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'VoteSite.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
# url(r'^admin/', include(admin.site.urls)),
url('^hello/$', hello),
('^time/$', current_datetime),
)
Django时区
视乎你的机器,显示的日期与时间可能和实际的相差几个小时。 这是因为Django是有时区意识的,并且默认时区为America/Chicago。 (它必须有个值,它的默认值是Django的诞生地:美国/芝加哥)如果你处在别的时区,你需要在settings.py文件中更改这个值。请参见它里面的注释,以获得最新世界时区列表。
Django和URL配置背后的哲学: 松耦合 原则。 简单的说,松耦合是一个 重要的保证互换性的软件开发方法。
Django的URL配置就是一个很好的例子。 在Django的应用程序中,URL的定义和视图函数之间是松 耦合的,换句话说,决定URL返回哪个视图函数和实现这个视图函数是在两个不同的地方。 这使得 开发人员可以修改一块而不会影响另一块。例如,考虑一下current_datetime视图。 如果我们想把它的URL 从原来的/time/ 改变到/currenttime/ ,我们只需要快速的修改一下URL配置即可, 不用担心这个函数的内部实现。同样的,如果我们想要修改这个函数的内部实现也不用担心会影响 到对应的URL。
此外,如果我们想要输出这个函数到 一些 URL, 我们只需要修改URL配置而不用 去改动视图的代码。 在这个例子里,current_datetime被两个URL使用。
urlpatterns = patterns('', ('^hello/$', hello), ('^time/$', current_datetime), ('^another-time-page/$', current_datetime), )
设计具有动态URL的视图
创建第三个视图来显示当前时间和加上时间偏差量的时间,设计是这样的: /time/plus/1/ 显示当前时间+1个小时的页面/time/plus/2/ 显示当前时间+2个小时的页面/time/plus/3/ 显示当前时间+3个小时的页面,以此类推。
新手可能会考虑写不同的视图函数来处理每个时间偏差量,URL配置看起来就象这样:
urlpatterns = patterns('', ('^time/$', current_datetime), ('^time/plus/1/$', one_hour_ahead), ('^time/plus/2/$', two_hours_ahead), ('^time/plus/3/$', three_hours_ahead), ('^time/plus/4/$', four_hours_ahead), )如果你有其它web平台的开发经验(如PHP或Java),你可能会想用查询字符串参数吧! 就像/time/plus?hours=3里面的小时应该在查询字符串中被参数hours指定(问号后面的是参数)。
Django的URL配置系统可以使你很容易的设置漂亮的URL,使用通配符(wildcard URLpatterns)。我们把它限制在最大允许99个小时:
from django.conf.urls.defaults import * from mysite.views import hello, current_datetime, hours_ahead urlpatterns = patterns('', (r'^hello/$', hello), (r'^time/$', current_datetime), (r'^time/plus/(\d{1,2})/$', hours_ahead), )Note:正则表达式字符串的开头字母“r”。 它告诉Python这是个原始字符串,不需要处理里面的反斜杠(转义字符)。 在普通Python字符串中,反斜杠用于特殊字符的转义。由于反斜杠在Python代码和正则表达式中有冲突,因此建议你在Python定义正则表达式时都使用原始字符串。 从现在开始,本文所有URL模式都用原始字符串。
view代码:
from django.http import Http404, HttpResponse import datetime def hours_ahead(request, offset): try: offset = int(offset) except ValueError: raise Http404() dt = datetime.datetime.now() + datetime.timedelta(hours=offset) html = "In %s hour(s), it will be %s." % (offset, dt) return HttpResponse(html)Note:
1. 视图函数, hours_ahead , 有两个 参数:request 和offset .
request 是一个HttpRequest 对象, 就像在current_datetime 中一样. 每一个视图总是 以一个 HttpRequest 对象作为 它的第一个参数。
offset 是从匹配的URL里提取出来的。 例如:如果请求URL是/time/plus/3/,那么offset将会是3。请注意:捕获值永远都是字符串(string)类型,而不会是整数(integer)类型。(从技术上来说,捕获值总是Unicode objects,而不是简单的Python字节串)变量名是无关紧要的,重要的是它的位置,它是这个函数的第二个 参数 (在 request 的后面)。 你还可以使用关键字来定义它,而不是用 位置。
2. datetime.timedelta函数要求hours参数必须为整数类型。
3. 最终,返回一个HTML的HttpResponse。 如今,这种方式已经过时了。从别人那里clone下来的django项目怎么运行,首先要开启你当前项目python_workspace的django支持
pycharm > settings > language & framworks > django > Enable django support
这时可以发现再打开python console就会自动变成django console了
要关闭django console,只要去掉enable django support前面的√就可以了。
下篇:Django项目实践2 - Django模板