建立第一个项目
新建工程
- 进入你要建立工程的目录,键入如下命令(其中mysite是你的项目名称):
django-admin startproject mysite
- 建立完成之后,目录结构是这个样子的:
.
└── mysite
├── manage.py
└── mysite
├── init.py
├── settings.py
├── urls.py
└── wsgi.py
- init.py:
让Python 把该目录当成一个开发包 (即一组模块)所需的文件。 这是一个空文件,一般你不需要修改它。
- manage.py:
一种命令行工具,允许你以多种方式与该 Django 项目进行交互。 键入python manage.py help,看一下它能做什么。 你应当不需要编辑这个文件;在这个目录下生成它纯是为了方便。
- settings.py:
该 Django 项目的设置或配置。 查看并理解这个文件中可用的设置类型及其默认值。
- urls.py:
Django项目的URL设置。 可视其为你的django网站的目录。 目前,它是空的。
- 启动开发服务器
进入你的网站目录,运行如下命令:
python manage.py runserver
会显示这样
Validating models...
0 errors found.
Django version 1.0, using settings 'mysite.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.`
默认使用的是8000端口,但是现在外网还不能访问。
使用如下命令就可以实现外网访问:
python manage.py runserver 0.0.0.0:8000
视图和URL配置
通常我们需要将html文件放到服务器,然后访问服务器,此时我们用到了两个东西html(视图也就是页面的内容,在这里我们就认为是html页面就好了,就像cgi输出html一样)和url(也就是网址)。
页面的内容是靠view function(视图函数,对应的是你的html也就是说这个html是通过视图来产生的)来产生,URL定义在 URLconf 中(对应的是你的网址)
第一个视图
- views.py
视图就是包含n个函数的py文件
我们随便建立一个py文件,比如叫做views.py,然后输入如下代码,当然,文件的位置是在你的mysite工程下面就是跟urls.py同一个目录,不过不是同一个目录也没有关系,我们看下面的代码:
from django.http import HttpResponse
def hello(request):
return HttpResponse("Hello world")
新建立一个views.py文件,然后定义了一个函数,名字叫hello,这就是一个视图函数。参数request是django.http.HttpRequest的一个实例,他必须是视图的第一个参数, 是包含当前请求信息的对象,当然,名字你可以随意取,叫r也可以,但是他必须位于第一个位置,也就是第一个位置留给request。
一个视图就是Python的一个函数。这个函数第一个参数的类型是HttpRequest;它返回一个
HttpResponse实例。为了使一个Python的函数成为一个Django可识别的视图,它必须满足这两个条件。
- urlconf
既然有了视图(也就是我们有了html页面),那么我们就需要绑定网址和页面,让django知道访问哪一个网址需要跳转哪一个页面,所以我们需要将网址和视图进行绑定,此时就需要修改文件urls.py了,其内容如下:
"""mysite URL Configuration
The urlpatterns
list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.9/topics/http/urls/
Examples:
Function views
Add an import: from my_app import views
Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
Add an import: from other_app.views import Home
Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
Import the include() function: from django.conf.urls import url, include
Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
]
注意
urlpatterns = [
url(r'^admin/', admin.site.urls),
]
urlpatterns是一个数组,里面存储了url()元素,url()中是一个网址接口和一个视图函数的对应,当然,网址接口可以使用正则表达式,r代表的是原始字符串,也就是里面的''什么的不会看成转义字符,视图函数需要你在前面导入进来,比如,我们要将我们的views.py文件中的hello视图函数跟网址/hello进行绑定,那么我们需要这么写,添加头部进行函数的导入:
from mysite.views import hello
然后我们修改urlpatterns如下:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^hello/$', hello),
]
** 另外需要注意的是,我们把hello视图函数作为一个对象传递,而不是调用它。 这是 Python (及其它动态语言的) 的一个重要特性: 函数是一级对象(first-class objects), 也就是说你可以像传递其它变量一样传递它们。 很酷吧!**
python学习:元组()不可变,数组[即列表],字典{}。
搜索路径:在python交互解释器中输入
import sys
print sys.path
python3是print(sys.path)
假设输出结果是['', '/usr/bin', '/usr/lib/python35.zip', '/usr/lib/python3.5']
Python 路径第一项的空字符串表示当前目录,那么会在当前目录进行搜索
- URLpattern的语法
需要了解一些正则表达式的知识[占个坑](../../linux学习笔记/* shell学习/shell学习之正则表达式.md)
不需要写前面的‘/’,django会自动移除请求前面的‘/’
正则一定要对,否则匹配不了就访问不了网页
网站根目录
匹配模式一般写作r'^$'
,代表的是一个空串,例如:
urlpatterns = [url(r'^$', mysite), ]
那么你访问主页也就是跟目录,就会跳转到mysite
- 启动服务器
python2.7 manage.py runserver
,然后访问http://127.0.0.1:8000/hello
django如何处理请求
引用自the django book
在继续我们的第二个视图功能之前,让我们暂停一下去了解更多一些有关Django是怎么工作的知识. 具体地说,当你通过在浏览器里敲http://127.0.0.1:8000/hello/来访问Hello world消息得时候,Django在后台有些什么动作呢?
所有均开始于setting文件。当你运行python manage.py runserver,脚本将在于manage.py同一个目录下(包括子目录)查找名为setting.py的文件。这个文件包含了所有有关这个Django项目的配置信息,均大写: TEMPLATE_DIRS , DATABASE_NAME , 等. 最重要的设置时ROOT_URLCONF,它将作为URLconf告诉Django在这个站点中那些Python的模块将被用到。
还记得什么时候django-admin.py startproject创建文件settings.py和urls.py吗?自动创建的settings.py包含一个ROOT_URLCONF配置用来指向自动产生的urls.py. 打开文件settings.py你将看到如下:
ROOT_URLCONF = 'mysite.urls'
相对应的文件是mysite/urls.py
当访问 URL /hello/ 时,Django 根据 ROOT_URLCONF 的设置装载 URLconf 。 然后按顺序逐个匹配URLconf里的URLpatterns,直到找到一个匹配的。 当找到这个匹配 的URLpatterns就调用相关联的view函数,并把 HttpRequest 对象作为第一个参数。 (稍后再给出 HttpRequest 的更多信息) (我们将在后面看到HttpRequest的标准)
正如我们在第一个视图例子里面看到的,一个视图功能必须返回一个HttpResponse。 一旦做完,Django将完成剩余的转换Python的对象到一个合适的带有HTTP头和body的Web Response,(例如,网页内容)。
总结一下:
- 进来的请求转入/hello/.
- Django通过在ROOT_URLCONF配置来决定根URLconf.
- Django在URLconf中的所有URL模式中,查找第一个匹配/hello/的条目。
- 如果找到匹配,将调用相应的视图函数
- 视图函数返回一个HttpResponse
- Django转换HttpResponse为一个适合的HTTP response, 以Web page显示出来
你现在知道了怎么做一个 Django-powered 页面了,真的很简单,只需要写视图函数并用 URLconfs把它们和URLs对应起来。 你可能会认为用一系列正则表达式将URLs映射到函数也许会比较慢,但事实却会让你惊讶。
第二个视图 动态视图
尝试一下这个,应该可以看懂,然后关联一下函数和url就可以了
from django.http import HttpResponse
import datetime
def current_datetime(request):
now = datetime.datetime.now()
html = "It is now %s." % now
return HttpResponse(html)
然后我们在urls.py
中导入这个函数并添加一个映射就可以了
urlpatterns=[
url(r'^time/$', current_datetime),
]
以上就是一个简单的动态视图
这并不是html应该的写法,只是一个简单的例子
python2.7中字符串格式化
print("i am %s, and i am %s year old" % ('abc', 19))
"this is a %s string" % ("long")
%s会将后面的内容转化成字符串
关于时区
需要在settings.py文件中更改这个值
URL配置和松耦合(背后的哲学)说到这我觉得应该看一些软件开发哲学的书籍
在Django的应用程序中,URL的定义和视图函数之间是松 耦合的,换句话说,决定URL返回哪个视图函数和实现这个视图函数是在两个不同的地方。 这使得 开发人员可以修改一块而不会影响另一块。这就是说,我们最好写代码的时候功能要单一,比如类有自己的功能,函数有自己的功能,不可以这个类或者函数可以进行各种功能,这样我们只需要在需要某一个功能的时候调用就好了。关于高内聚低耦合,大体就是前面加粗部分的意思吧
当然,url配置里面我们可以随便对应,这部分不会影响实现部分。
第三个视图 动态url
url建议,一般有通用的东西django希望能够使用url,比如在url中添加数字,我们不使用查询字符串?d=3
对于先写url对应还是先写视图,两者都可以
r表示的是原始字符串,正则表达式是用圆括号来从文本里 提取 数据的
注意:第一个参数必须是request,第二个参数一般是url中的匹配值
- 推荐使用正则表达式表示,比如选定数字页面,我们可以使用\d来表示数字页面:
r'^time/\d{1, 2}$'
这样我们就设计完成了一个动态url,我们可以访问/time/0,可以访问/time/1.../time/99,这个是正则表达式匹配的数字。
现在我们需要获取url中匹配到的数字内容,在正则中,我们可以通过分组捕获的方法来获得指定的内容,同样,我们在这里也可以通过分组捕获的方法
r'^time/(\d{1, 2})$'
我们可以通过匹配偏移获得参数
- 我们有了动态url,那么我们需要动态url对应的视图,视图应该可以获取url中的数字。
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)
现在,函数定义中出现了两个参数了,第一个是千年不变的request(当然可以取别的名字,但是其位置是留给request对象的,变量名无关紧要,重要的是他的位置,当然我们也可以直接使用关键字来定义key=?),第二个参数是offset,offset 是从匹配的URL里提取出来的。从来都是字符串。
错误提示
可以通过出错页面来调试
可以在语句中添加
assert False
来设置错误进行调试,也就是触发错误不过这些都应该是在debug模式下进行的,在互联网上我们不能让别人了解这些信息,所以需要禁用debug模式,django服务默认开启debug模式
出错页面是精华,可以提供大量信息
**引用自the django book **
在页面顶部,你可以得到关键的异常信息: 异常数据类型、异常的参数 (如本例中的 "unsupported type" )、在哪个文件中引发了异常、出错的行号等等。
在关键异常信息下方,该页面显示了对该异常的完整 Python 追踪信息。 这类似于你在 Python 命令行解释器中获得的追溯信息,只不过后者更具交互性。 对栈中的每一帧,Django 均显示了其文件名、函数或方法名、行号及该行源代码。
点击该行代码 (以深灰色显示),你可以看到出错行的前后几行,从而得知相关上下文情况。
点击栈中的任何一帧的“Local vars”可以看到一个所有局部变量的列表,以及在出错 那一帧时它们的值。 这些调试信息相当有用。
注意“Traceback”下面的“Switch to copy-and-paste view”文字。 点击这些字,追溯会 切换另一个视图,它让你很容易地复制和粘贴这些内容。 当你想同其他人分享这些异常 追溯以获得技术支持时(比如在 Django 的 IRC 聊天室或邮件列表中),可以使用它。
你按一下下面的“Share this traceback on a public Web site”按钮,它将会完成这项工作。 点击它以传回追溯信息至http://www.dpaste.com/,在那里你可以得到一个单独的URL并与其他人分享你的追溯信息。
接下来的“Request information”部分包含了有关产生错误的 Web 请求的大量信息: GET 和 POST、cookie 值、元数据(象 CGI 头)。 在附录H里给出了request的对象的 完整参考。
Request信息的下面,“Settings”列出了 Django 使用的具体配置信息。 (我们已经提及过ROOT_URLCONF,接下来我们将向你展示各式的Django设置。 附录D覆盖了所有可用的设置。)