前面两节我们已经讲了如何创建一个项目和配置数据库和后台,现在我们看看怎样创建自己的网页.
一.写第一个视图
首先在应用程序中的view.py写一个最简单的视图:
polls/views.py
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world! Django!")
首先导入django的HTTP响应类,index函数就是视图函数,request参数是必须要的,用来接受HTTP请求,然后是响应一个最简单的回复:Hello world ! Django!
现在视图已经写好了,但是怎样访问我们的视图了?这里就需要进行URL配置了,根据官方文档和其他资料这里有两种配置URL的方案:
方案一:(The Django Book 2.0中用的方法)
直接在mysite文件夹(settings.py所在的文件夹)下找到urls.py,进行配置:如下
from django.conf.urls import patterns, include, url
from django.contrib import admin
from polls.views import *
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'DjangoS.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^index/$',index),
)
首先是导入刚刚编辑的views.py,以便与导入我们的index函数,然后在下面的元组中配置URL,给了相应的例子,url()函数的第一个参数就是访问的URL路径,这里用的是正则表达式,正则表达式不熟的自己查一下相关只知识,很简单的(最下面的附录中也有一些简单的参考);第二个参数就是用该那个函数来处理这个请求,这里我们用的是views.py中的index函数来处理请求.开启服务器,然后通过http://127.0.0.1:8000/index 来访问我们的视图,会看到页面显示Hello world! Django! 是不是很简单!!!!!比struts简单多了!
方案二:(Django1.7官方文档用的方法,推荐方案)
views.py不用改动和方案一一样,然后在polls中新建一个urls.py文件,内容如下:
polls/urls.py
from django.conf.urls import patterns, url
from polls import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
)
url()函数中的第一个参数还是正则表达式,第二个蚕参数为处理请求的函数,第三个参数只是其标识作用,可以不要,不过最好写上,前两个蚕参数时必需的!
最后在mysite文件夹中的urls.py中进行配置,如下:
mysite/urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
urlpatterns = patterns('',
url(r'^index/', include('polls.urls')),
url(r'^admin/', include(admin.site.urls)),
)
启动服务器,通过
http://127.0.0.1:8000/index来访问视图,效果和方案一是一样的.
注意方案一和方案二的异同点,方案二虽然麻烦一些,给人一种多此一举的感觉,但是官方文档用的就是方案二,方案一根本就没提,不过方案二这样做肯定有他的好处,至于好处嘛,马上你就会知道了!
大致讲一下处理视图的流程和原理吧:
-
进来的请求转入/index/.
-
Django通过在ROOT_URLCONF配置来决定根URLconf.(创建项目时以自动配置了)
-
ROOT_URLCONF = 'mysite.urls'
-
Django在URLconf中的所有URL模式中,查找第一个匹配/index/的条目。
-
如果找到匹配,将调用相应的视图函数
-
视图函数返回一个HttpResponse
-
Django转换HttpResponse为一个适合的HTTP response, 以Web page显示出来
二.获取URL传递过来的参数
有时候我们还有根据URL传递过来的参数进行不同的操作,比如/polls?id=5,但这样的URL并不优雅漂亮,还可能受到脚本小子的SQL注入攻击,Django中用/polls/5/的方式来代替前面的参数传递.
这里还是分两种方案,对应上面的两种URL配置方案.
方案一:(The Django Book 2.0中用的方法)
首先时/polls/views.py文件中的视图:
polls/views.py
def detail(request, question_id):
return HttpResponse("You're looking at question %s." % question_id)
def results(request, question_id):
response = "You're looking at the results of question %s."
return HttpResponse(response % question_id)
def vote(request, question_id):
return HttpResponse("You're voting on question %s." % question_id)
注意:每个函数都多了一个参数,这个就是URL传递的参数,不过类型为字符串,如果要当数字用的话,注意转换类型和转换异常处理.
然后是/mysite/urls.py中的URL配置了:
from django.conf.urls.defaults import *
from mysite.views import hello, current_datetime, hours_ahead
urlpatterns = patterns('',
(r'^polls/(\d{1,2})/$', hours_ahead),
)
这里的数字为一个一位数或者两位数,可以通过:
http://127.0.0.1:8000/polls/2来访问
方案二:(Django1.7官方文档用的方法,推荐方案)
首先还时views.py不变,views.py在两种方案中都是一样的,然后就是/polls/urls.py文件了配置如下:
from django.conf.urls import patterns, url
from polls import views
urlpatterns = patterns('',
# ex: /polls/
url(r'^$', views.index, name='index'),
# ex: /polls/5/
url(r'^(?P<question_id>\d+)/$', views.detail, name='detail'),
# ex: /polls/5/results/
url(r'^(?P<question_id>\d+)/results/$', views.results, name='results'),
# ex: /polls/5/vote/
url(r'^(?P<question_id>\d+)/vote/$', views.vote, name='vote'),
)
仔细观察红色字体的地方,然后就是配置
/mysite/urls.py文件了:
其实/mysite/urls.py已经不用配置了,因为在第一步中已经配好了,不需要表变动!现在体会到方案二的方便性了吧!
注意:/polls/view.py中的函数参数名question_id和/polls/urls.py中的正则表达式中的question_id要一致,否则参数传递不进来!
三.使用模板
如果把HTML页面放在views.py中返回那就太麻烦了,这里就用到了模板,就是建立一个html文件,里面设置一些参数,通过views.py加载html然后传递参数到html中,在返回给浏览器,学过JSP的朋友应该很熟悉,就是类似于JSP.
这里我们建立一个模板:
polls/templates/polls/index.html
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
但是Django并不知道该到哪加载这个模板,所以要在settings.py中告诉Django该到哪加载模板:
mysite/settings.py
TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'templates')]
或者是:
TEMPLATE_DIRS = [os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/')]
然后在/polls/view.py中加载模板,添加参数:
polls/views.py
from django.http import HttpResponse
from django.template import RequestContext, loader
from polls.models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
template = loader.get_template('polls/index.html')
context = RequestContext(request, {
'latest_question_list': latest_question_list,
})
return HttpResponse(template.render(context))
或者是:
polls/views.py
from django.shortcuts import render
from polls.models import Question
def index(request):
latest_question_list = Question.objects.all().order_by('-pub_date')[:5]
context = {'latest_question_list': latest_question_list}
return render(request, 'polls/index.html', context)
或者:
polls/views.py
from django.http import Http404
from django.shortcuts import render
from polls.models import Question
# ...
def detail(request, question_id):
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404
return render(request, 'polls/detail.html', {'question': question})
或者:
polls/views.py
from django.shortcuts import get_object_or_404, render
from polls.models import Question
# ...
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
或者最快的方法:
from django.shortcuts import render_to_response
import datetime
def current_datetime(request):
now = datetime.datetime.now()
return render_to_response('current_datetime.html', {'current_date': now})
以上代码均来自Django1.7官方文档,除了最后一个例子
简单的介绍就到折这了,关于更多详情关于模板的,请参看Django的官方文档,这里就不多说了.
附录:简单的正则表达式
符号 | 匹配 |
---|
. (dot) | 任意单一字符 |
\d | 任意一位数字 |
[A-Z] | A 到 Z中任意一个字符(大写) |
[a-z] | a 到 z中任意一个字符(小写) |
[A-Za-z] | a 到 z中任意一个字符(不区分大小写) |
+ | 匹配一个或更多 (例如, \d+ 匹配一个或 多个数字字符) |
[^/]+ | 一个或多个不为‘/’的字符 |
* | 零个或一个之前的表达式(例如:\d? 匹配零个或一个数字) |
* | 匹配0个或更多 (例如, \d* 匹配0个 或更多数字字符) |
{1,3} | 介于一个和三个(包含)之前的表达式(例如,\d{1,3}匹配一个或两个或三个数字) |