Django笔记 —— 高级视图和URL配置
最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过。Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧~
本篇笔记(其实我的所有笔记都是),并不会过于详细的讲解。因此如果有大家看不明白的地方,欢迎在我正版博客下留言,有时间的时候我很愿意来这里与大家探讨问题。(当然,不能是简简单单就可以百度到的问题-.-)
我所选用的教材是《The Django Book 2.0》,本节是第八章,高级视图和URL配置。
在基础部分的学习中,我体会到了一点经验:傻瓜教程最适合作为本书的笔记了~因为本书对于原理讲得很细,看一遍也就能基本理解,但由于讲得太细,具体操作步骤正是其不足。因此,读这本书,如果配上操作教程式的笔记,那复习起来就很舒服了 ^.^
因此,高级部分的笔记,将给出很多操作教程,没看过书的同学请先看了书再来看笔记~
0. 目录
1. 设置DEBUG参数
(1) 在settings.py中,将DEBUG参数设置为False
(2) 在settings.py中,将原本是空的ALLOWED_HOSTS参数中加入'127.0.0.1'。否则,当你尝试运行网站时,会在命令行中报错:
CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False.
2. URL回顾与初试
关于URLconf,即urls.py中urlpatterns参数中的每一项正则表达式,有些很方便的技巧可以大大简化代码。
先通过几个例子,来回忆一下URLconf(正则表达式)的写法:
| URL地址 | 视图函数 |
| http://127.0.0.1:8000/ | def index(request): |
| http://127.0.0.1:8000/hello/ | def hello(request): |
| http://127.0.0.1:8000/diary/diary_title/ | def diary_title(request, title, count=''): |
| http://127.0.0.1:8000/admin/ | # Django内置 |
就以上面这些视图为例,他们对应的URLconf代码如下:
from django.conf.urls import include, url
from django.contrib import admin
from mysite import views urlpatterns = [
url(r'^$', views.index),
url(r'^hello/$', views.hello),
url(r'^diary/(\w+)/$', views.diary_title),
url(r'^admin/', include(admin.site.urls)),
]
那么,在此基础上,我们再介绍新的技巧,把上面的例子不断扩展。
首先,看版本1:
from django.conf.urls import include, url
from django.contrib import admin
from django.conf import settings urlpatterns = [
url(r'^$', 'mysite.views.index'),
url(r'^hello/$', 'mysite.views.hello'),
url(r'^diary/(?P<title>\w+)/$', 'mysite.views.diary_title'),
] if settings.DEBUG:
urlpatterns += [
url(r'^admin/', include(admin.site.urls)),
]
这时,仅在DEBUG模式下才能进入admin,而且传入的title变量URLconf可读性更高,且连接URL与视图函数时省去了import的麻烦,改为直接写地址。
再来看版本2:
from django.conf.urls import include, url
from django.contrib import admin
from django.conf import settings urlpatterns = [
url(r'^$', 'mysite.views.index', {'visitor': 'icedream'}),
url(r'^hello/$', 'mysite.views.hello', {'visitor': 'icedream'}),
url(r'^diary/(?P<title>\w+)/$', 'mysite.views.diary_title', {'visitor': 'icedream'}),
] if settings.DEBUG:
urlpatterns += [
url(r'^admin/', include(admin.site.urls)),
]
这次,又在版本1的基础上,向视图函数多传入了一个变量visitor,当然,视图函数也应该多接收一个变量了。
可能有人已经注意到,我们在 视图函数diary_title 中设置了一个 count='10' 的默认值,那么下面是版本3:
from django.conf.urls import include, url
from django.contrib import admin
from django.conf import settings urlpatterns = [
url(r'^$', 'mysite.views.index', {'visitor': 'icedream'}),
url(r'^hello/$', 'mysite.views.hello', {'visitor': 'icedream'}),
url(r'^diary/(?P<title>\w+)/$', 'mysite.views.diary_title', {'visitor': 'icedream'}),
url(r'^diary/(?P<title>\w+)/(?P<count>\d+)$', 'mysite.views.diary_title', {'visitor': 'icedream'}),
] if settings.DEBUG:
urlpatterns += [
url(r'^admin/', include(admin.site.urls)),
]
这样一来,便可以在传入count时改变默认值,而不传入时依旧可以匹配默认值下的视图函数。
3. URLconf的一些特性
注意,如果URL中接收了一个参数title,同时后面字典中所传参数也有一个title,那么URL中接收的title会被忽略。
还有,URLconf的匹配是短路逻辑,这点提一下,可以适当使用。
还有,URLconf中传入视图函数的参数,全都是字符串,这点需要注意(注意count的默认值,为了保持一直,我也设置成了字符串)。
还有,URLconf匹配时,会忽略请求方法部分(例如GET),这点无需担心。
4. 视图中的调度函数
为了视图的结构更好,我们可以写一些函数起到调度的作用,就像这样:
# views.py from django.http import Http404, HttpResponseRedirect
from django.shortcuts import render_to_response def method_splitter(request, GET=None, POST=None):
if request.method == 'GET' and GET is not None:
return GET(request)
elif request.method == 'POST' and POST is not None:
return POST(request)
raise Http404 def some_page_get(request):
assert request.method == 'GET'
do_something_for_get()
return render_to_response('page.html') def some_page_post(request):
assert request.method == 'POST'
do_something_for_post()
return HttpResponseRedirect('/someurl/') # urls.py from django.conf.urls import url
from mysite import views urlpatterns = [
# ...
url(r'^somepage/$', views.method_splitter, {'GET': views.some_page_get, 'POST': views.some_page_post}),
# ...
]
在此基础上,我们还可以把 method_splitter 函数做如下改进:
def method_splitter(request, *args, **kwargs):
get_view = kwargs.pop('GET', None)
post_view = kwargs.pop('POST', None)
if request.method == 'GET' and get_view is not None:
return get_view(request, *args, **kwargs)
elif request.method == 'POST' and post_view is not None:
return post_view(request, *args, **kwargs)
raise Http404
这样,便可以把向视图函数中传递的参数也都传递进去了。
4+. 动态参数的传递
Python中,支持动态参数的传递。写法如下:
def foo(*args, **kwargs):
print "Positional arguments are:"
print args
print "Keyword arguments are:"
print kwargs
当运行时,效果如下:
>>> foo(, , )
Positional arguments are:
(, , )
Keyword arguments are:
{}
>>> foo(, , name='Adrian', framework='Django')
Positional arguments are:
(, )
Keyword arguments are:
{'framework': 'Django', 'name': 'Adrian'}
5. 视图中的预处理函数
我们还可以让一些函数在进入之前,先进行预处理,其预处理的视图函数就像这样:
def requires_login(view):
def new_view(request, *args, **kwargs):
if not request.user.is_authenticated():
return HttpResponseRedirect('/accounts/login/')
return view(request, *args, **kwargs)
return new_view
其对应的URL部分是这样的:
from django.conf.urls import url
from mysite.views import requires_login, my_view1, my_view2, my_view3 urlpatterns = [
url(r'^view1/$', requires_login(my_view1)),
url(r'^view2/$', requires_login(my_view2)),
url(r'^view3/$', requires_login(my_view3)),
]
而原来,它原本要实现的视图逻辑则是这样的:
def my_view1(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/accounts/login/')
# ...
return render_to_response('template1.html') def my_view2(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/accounts/login/')
# ...
return render_to_response('template2.html') def my_view3(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/accounts/login/')
# ...
return render_to_response('template3.html')
6. URL中的include函数
在admin的URL中,用到了include函数,而且URLconf的末尾不能有$。例如下面这段代码:
from django.conf.urls import include, url urlpatterns = [
(r'^weblog/', include('mysite.blog.urls')),
(r'^photos/', include('mysite.photos.urls')),
(r'^about/$', 'mysite.views.about'),
]
如你所见,include函数包含了另一个urls.py,其内容就像这样:
# mysite.blog.urls from django.conf.urls import url urlpatterns = [
url(r'^(\d\d\d\d)/$', 'mysite.blog.views.year_detail'),
url(r'^(\d\d\d\d)/(\d\d)/$', 'mysite.blog.views.month_detail'),
]
那么,其对应的网址就像这样:
| URL地址 | 视图函数 |
| /weblog/2007/ | 'mysite.blog.views.year_detail' |
| /weblog/2007/09/ | 'mysite.blog.views.month_detail' |
| ... | ... |
而且,你向视图函数中传的参数(无论是URL中接收的、还是字典中手动传的),都会实际传到每一个匹配的视图中。
举个例子,下面两段代码的效果是完全相同的 ——
代码1:
# urls.py from django.conf.urls import * urlpatterns = [
url(r'^blog/', include('inner'), {'blogid': 3}),
] # inner.py from django.conf.urls import * urlpatterns = [
url(r'^archive/$', 'mysite.views.archive'),
url(r'^about/$', 'mysite.views.about'),
url(r'^rss/$', 'mysite.views.rss'),
]
代码2:
# urls.py from django.conf.urls import * urlpatterns = [
url(r'^blog/', include('inner')),
] # inner.py from django.conf.urls import * urlpatterns = [
url(r'^archive/$', 'mysite.views.archive', {'blogid': 3}),
url(r'^about/$', 'mysite.views.about', {'blogid': 3}),
url(r'^rss/$', 'mysite.views.rss', {'blogid': 3}),
]
至此,“高级视图和URL配置”内容完结,下一篇是——“模板高级进阶”。
Django笔记 —— 高级视图和URL配置的更多相关文章
- Django学习day4——视图和URL配置
创建一个简单的hello world 在day3中我们第一次运行了服务器,里面是一个django的欢迎页面,那是因为我们没有配置URL和视图,django在底层会自动跳转这个页面上 我们在mysite ...
- django1.8高级视图和URL配置读书笔记
一.在url配置中可以通过导入视图函数来将url模式和对应的函数对象进行映射,也可以通过字符串的形式进行映射.字符串包含应当是模块名.函数名的组合例如: 之前: from mysite import ...
- 测试开发之Django——No8.Django中的视图与URL配置
在Django中,页面内容是靠views function(视图函数)来产生,URL定义在URLconf中. 这是一个纯净项目的url配置文件,他存在的目录,是与setting文件在同一个目录中. u ...
- Django框架1——视图和URL配置
三个命令 1.创建一个django项目 在cmd中:django-admin.py startproject project_name D:\python\django_site>django- ...
- Django之高级视图与URL
Urls.py中有我们所有的路由映射关系.但是随着网站功能的增多,需要配置的URL也变得多了起来.并且维护这些导入也变得很麻烦.因此介绍一些优化和简洁的方法: 一 使用多个视图前缀: 之前所有的路由关 ...
- django-高级视图和url配置
高级视图和url配置 一.URLconf技巧 1.流线型化函数导入 对于配置url,我们可以使用以下几种方式: (1)引入view中的函数 from firstSite.view import cur ...
- 视图和URL配置
视图和URL配置 实验简介 上一章里我们介绍了如何创建一个Django项目并启动Django的开发服务器.本章你将学到用Django创建动态网页的基本知识. 同时,也教会大家怎么在本地机器上建立一个独 ...
- 视图的URL配置,找不到我设置的第一个Page
问题:视图的URL配置,找不到我设置的第一个Page 我的代码如下: 结果访问/test/时说找不到这个page 原因:patterns方法的参数有两个,一个是prefix,一个是参数元祖,详见下 ...
- django学习笔记(一)视图和url配置
1.开始一个项目: 进入创建的目录,然后: django-admin startproject myblog 2.启动开发服务器: python manage.py runserver 注:默认是80 ...
随机推荐
- 【转】同步的HttpClient使用详解
http://blog.csdn.net/angjunqiang/article/details/54340398 背景 服务端以及客户端在开发过程中不可避免的会使用到网络请求,网络请求可以使用Jav ...
- linux系统命令与常识
之前短期学过linux,用到时才发现已经忘得一干二净了. 现在对学过的和了解到的做一个总结: 先明确一些使用工具: winscp : WinSCP是一个Windows环境下使用SSH的开源图形化SFT ...
- 由inline-block小例子引申出的一些问题,及IE6、IE7兼容性解决方案
使用场景分析: 常见的对块与块之间的横向排列处理 对同级所有元素使用display:inline-block; , 之后块与块直接会产生间隙问题 解决办法: 给父级设 font-size:0; 别高兴 ...
- Python 学习笔记(七)Python字符串(二)
索引和切片 索引 是从0开始计数:当索引值为负数时,表示从最后一个元素(从右到左)开始计数 切片 用于截取某个范围内的元素,通过:来指定起始区间(左闭右开区间,包含左侧索引值对应的元素,但不包含右测 ...
- TCP和UDP的现实应用
以下应用的区分是基于TCP可靠传输,UDP不可靠传输 TCP一般用于文件传输(FTP HTTP 对数据准确性要求高,速度可以相对慢),发送或接收邮件(POP IMAP SMTP 对数据准确性要求高,非 ...
- Oracle之视图
Oracle之视图 2018.9.12 由于视图的数据与表数据互相关联,所以切记谨慎操作 建立视图 使用下面sql语句来完成视图的创建 create or replace view 视图名 as se ...
- iOS 让视图UIView单独显示某一侧的边框线
iOS 让视图UIView 单独显示某一侧的边框线 有时候需要让view显示某一侧的边框线,这时设置layer的border是达不到效果的.在网上查阅资料发现有一个投机取巧的办法,原理是给view ...
- oracle中connect by语句的优化
很多应用中都会有类似组织机构的表,组织机构的表又通常是典型的层次结构(没有循环节点).于是通过组织控制数据权限的时候,许多人都喜欢通过connect by获得组织信息,然后再过滤目标数据. 在有些情况 ...
- Linux运维一定要知道的六类好习惯和23个教训,避免入坑!
Linux运维一定要知道的六类好习惯和23个教训,避免入坑! 从事运维三年半,遇到过各式各样的问题,数据丢失,网站挂马,误删数据库文件,黑客攻击等各类问题. 今天简单整理一下,分享给各位小伙伴. 一. ...
- vue项目中缓存问题
单页面应用总是存在缓存问题,特别是在微信端,更新页面之后访问的还是老页面,缓存的问题是因为用户访问的脚本地址并没有改变,浏览器就会读取原来的脚本 网上有几种解决办法,首先列举一下 1.加meta,禁止 ...