标签:
这一节我们将继续一个创建网络收藏夹应用,并学习视图、模型以及模板的处理过程。
Django是一个MVC开发框架,但是它的控制器对应的为view,而视图对应为模板(template),模型对应model,所以Django也成为MTV框架。
view(视图函数)通过生成页面来响应某个用户请求,首先我们在项目中先创建一个应用,应用是包含视图与数据模型的容器,在django_boookmarks目录下运行下面的命令:
$ python manage.py startapp bookmarks
创建应用的语法与创建项目的语法类似。运行上述命令之后,Django会自动在bookmarks目录下生成下面的文件。
接下来,创建主页视图:
from django.http import HttpResponse def main_page(request): output = ‘‘‘ <html> <head><title>%s</title></head> <body> <h1>%s</h1><p>%s</p> </body> </html> ‘‘‘ % ( ‘Django Bookmarks‘, ‘Welcome to Django Bookmarks‘, ‘Where you can store and share bookmarks!‘ ) return HttpResponse(output)
这段代码非常的简洁,首先,我们从Django.http 中导入HttpResponse类,通过这个类我们来生成响应页面。接着我们定义了一个视图函数main_page(),使用request作为参数,request中包含了一些用户的输入以及其他信息,如request.GET,request.POST,request.COOKIES等等。最后我们通过HttpResponse生成页面响应返回。
定义了视图函数之后,就需要再定义URL。
打开urls.py,在其中给主页视图添加URL配置。
from django.conf.urls.defaults import * from bookmarks.views import * urlpatterns = patterns(‘‘, (r‘^$‘, main_page), )
也来分下下这段代码,首先从django.conf.urls.defaults中导入定义URLS的相关函数,接着从bookmarks.views中导入所有的视图函数,最后定义URL表,将r‘^$‘映射到视图函数main_page。
r‘^$‘是一个正则表达式,r代表原始字符串,表示字符串中的特殊字符不会进行转义,^代表字符串的开头,$代表字符串的结尾。所以^$代表了空字符串。python中跟正则表达式相关的模块是re,具体用法可以查看官方文档。
接下来在浏览器中输入http://127.0.0.1:8000/即可看到创建的主页。
Django的工作流程如下所示:
现在几乎所有的Web站点都会使用数据库管理保存数据,数据库现在已经是网站的重要组成部分。接下里,我们将使用数据库管理用户账号与网络收藏夹。如果你习惯了使用SQL语句对处理数据库,那么你将发现Django处理数据库的方式不太一样,Django是通过Python类对数据库进行管理的。
下面通过例子来讲解,对于我们的网路收藏夹,我们需要在数据库中保存如下信息:
为了将上面的数据表设计转换成Python代码,需要再bookmarks目录下的models.py进行编辑,models.py用来保存数据模型。
打开bookmarks/models.py,输入以下代码:
from django.db import models class Link(models.Model): url = models.URLField(unique=True
models模块包含了一些用来定义数据模型的类,我们定义了一个Link类,它继承自models.Model,Model是所有模型类的基类,Link类定义了一个url字段,这个字段必须是唯一的。
models.URLField只是Django提供的众多数据字段类型之一,下面是其中一些常用的字段类型。
字段类型 描述
IntegerField 整型
TextField 文本类型
DateTimeField 日期时间类型
EmailField 电子邮件类型
URLField URL类型
FielField 文件类型
为了使用这个模型,需要现在settings.py中的INSTALLED_APPS中添加刚刚创建的应用名:
INSTALLED_APPS = ( ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.sites‘, ‘django_bookmarks.bookmarks‘, )
接下来使用下面的命令在数据库中创建相应的数据表:
$ python manage.py syncdb
注意,每当我们添加一个数据模型,都需要执行上面的命令。Django会自动分析Link模型,然后生成相应的SQL语句,并执行这些语句生成对应的数据表,Django会自动给每个模型添加id字段。这个字段是整个数据表的主键。
Django的数据库API不仅仅能够生成数据表,还可以对数据表进行增删改操作,接下来,我们将通过python交互窗口来探索这些功能,通过下面这条命令打开交互窗口:
$ python manage.py shell
这个命令窗口与标准的窗口不太一样,首先,打开这个窗口之前,Django会将当前项目的路径加入到sys.path中,这样就可以自动导入当前项目中的模块,其次有个特殊的环境变量可以保存我们当前使用的settings.py的路径。所以,每当我们需要使用命令窗口与当前项目交互时,使用上面的命令即可。
接下来,导入models模块中的所有内容:
>>> from bookmarks.models import *
添加一条新的URL,并保存到数据库中:
>>> link1 = Link(url=‘http://www.packtpub.com/‘) >>> link1.save() >>> link2 = Link(url=‘http://www.example.com/‘) >>> link2.save()
只有当调用save方法的时候,数据才会保存到数据库中,没调用之前,数据都只是缓存在内存中,如果关闭命令窗口,数据将会丢失。
数据表中的字段都会转换成对象的属性,通过下面的方法可修改Link的URL。
>>> link2.url ‘http://www.example.com/‘ >>> link2.url = ‘http://www.google.com/‘ >>> link2.save()
通过下面的方法可以获取所有的Link对象。
>>> links = Link.objects.all() >>> for link in links: ... print link.url ... http://www.packtpub.com/ http://www.google.com/
通过下面的方法获取指定ID的Link
>>> Link.objects.get(id=1)
<Link: Link object>
最后使用下面方法删除一条Link:
>>> link2.delete() >>> Link.objects.count() 1
输出结果1表明现在只剩一条Link,注意上面我们所有的操所都不是通过SQL来执行的,Django提供了几乎所有的数据接口,实际上上面的所有命令都是先转换成SQL再执行的。这样做的好处是非常明显的:
接下来创建用户数据模型,幸运的是,Django已经给开发者提供了一个内置的用户数据模型,它位于django.contrib.auth.models中,模型名为User。
>>> from django.contrib.auth.models import User >>> User.objects.all() [<User: root>]
可以发现数据表中已经包含了一个用户,这个用户是我们第一次执行syncdb时生成的用户。
使用dir()函数可以查看User模型的字段。
>>> user = User.objects.get(id=1)
>>> dir(user)
结果得到一个属性列表,其中包含了username,email以及password属性,这些刚好满足我们的要求,所以直接使用就行了。
最后我们定义Bookmark数据模型,User与Bookmark以及Link与Bookmark之间的关系都是一对多的关系。在数据表中的表现就是外键,所以在Bookmark数据模型中我们定义两个外键:
from django.contrib.auth.models import User class Bookmark(models.Model): title = models.CharField(maxlength=200) user = models.ForeignKey(User) link = models.ForeignKey(Link
接着执行python manage.py syncdb即可。
通过下面的命令可以得到Django实际上是如何处理外键的SQL语句:
$ python manage.py sql bookmarks
结果为:
BEGIN; CREATE TABLE "bookmarks_bookmark" ( "id" integer NOT NULL PRIMARY KEY, "title" varchar(200) NOT NULL, "user_id" integer NOT NULL REFERENCES "auth_user" ("id"), "link_id" integer NOT NULL REFERENCES "bookmarks_link" ("id"), ); CREATE TABLE "bookmarks_link" ( "id" integer NOT NULL PRIMARY KEY, "url" varchar(200) NOT NULL UNIQUE ); COMMIT;
注意,Django也自动给Bookmark添加了id属性。
在前面的部分,我们通过将HTML硬编码到代码中,创建了一个简单的应用主页,这样有很多缺点:
因此,最好将Django视图与HTML代码分离开来,幸运的是,Django提供了这样一个机制,那就是模板系统。
模板系统的机制很简单,它将HTML代码保存在模板中,在这个模板中有一些占位符,占位符的内容可以被视图所产生的动态内容所替换,当生成一个页面时,视图函数加载模板,然后将动态产生的值传递给它,然后模板将占位符替换成对应的内容,最终生成页面返回。
为了更好的理解这一机制,我们修来之前创建的main_page视图,首先在当前项目中创建一个templates目录,然后打开settings.py文件,找到TEMPLATES_DIRS变量,将templates的路径加到这里,如果你想支持跨平台,那就使用下面的代码:
import os.path TEMPLATE_DIRS = ( os.path.join(os.path.dirname(__file__), ‘templates‘), )
接下来在templates目录中创建main_page.html:
<html> <head> <title>{{ head_title }}</title> </head> <body> <h1>{{ page_title }}</h1> <p>{{ page_body }}</p> </body> </html>
模板的结构与HTML很相似,但是其中包含了一些特殊的语法,模板变量,例如{{ head_title }}表明它的内容将会被head_title的值所替换。模板变量的总是被两个花括号所包围。
接下来,再修改bookmarks/views.py中内容:
from django.http import HttpResponse from django.template import Context from django.template.loader import get_template def main_page(request): template = get_template(‘main_page.html‘) variables = Context({ ‘head_title‘: ‘Django Bookmarks‘, ‘page_title‘: ‘Welcome to Django Bookmarks‘, ‘page_body‘: ‘Where you can store and share bookmarks!‘ }) output = template.render(variables) return HttpResponse(output)
为了加载模板,我们使用了 get_template方法,它位于django.template.loader中,这个方法使用模板名作为参数,返回一个template对象。通过创建一个Context对象,来设置模板中的变量值,Context使用一个字典作为参数,字典使用模板变量为键,对应的值为变量的实际值。使用template对象的render方法替换模板中的变量值,最后通过HTTPResponse将得到输返回。
这样做的好处是非常明显的,我们不再需要在Python代码中处理HTML代码了,HTML部分可以直接交给前端工作者处理了。
前面我们介绍了视图,模板以及数据模型,最后,我们将使用这些知识创建一个用户页面,这个页面将展示属于这个用户的所有Bookmarks。
这个视图的URL格式为:user/username,username是书签所有者的用户名,这个URL与我们之前添加的URL不太一样,它包含了一个动态部分,我们需要使用正则表达式来表示这个URL,编辑urls.py,
urlpatterns = patterns(‘‘, (r‘^$‘, main_page), (r‘^user/(\w+)/$‘, user_page), )
\w代表任意一个字母数字或者下划线,+代表一个或者多个。
打开bookmarks/views.py视图,添加如下代码:
from django.http import HttpResponse, Http404 from django.contrib.auth.models import User def user_page(request, username): try: user = User.objects.get(username=username) except: raise Http404(‘Requested user not found.‘) bookmarks = user.bookmark_set.all() template = get_template(‘user_page.html‘) variables = Context({ ‘username‘: username, ‘bookmarks‘: bookmarks }) output = template.render(variables) return HttpResponse(output)
跟之前的视图不太一样,这个视图提供了第二个参数,这个参数是从url中获取到的。通过User.object.get()函数获取用户名为username的用户,如果没找到或者找到多个同名用户,就抛出404异常。为了获取指定用户所拥有的bookmarks,我们使用user对象的bookmark_set属性,Django会自动检查不同模型之间的关系,然后生成这样的属性。
在templates目录下创建user_page.html:
<html> <head> <title>Django Bookmarks - User: {{ username }}</title> </head> <body> <h1>Bookmarks for {{ username }}</h1> {% if bookmarks %} <ul> {% for bookmark in bookmarks %} <li><a href="{{ bookmark.link.url }}"> {{ bookmark.title }}</a></li> {% endfor %} </ul> {% else %} <p>No bookmarks found.</p> {% endif %} </body> </html>
这个模板比之前那个更加复杂,。它还是用了if标签以及for循环标签,bookmarks变量也是个列表对象。if标签可以判断变量是否包含了数据,如果有,则输出下面的信息,如果没有,则输出else下面的语句。for标签用来循环一个列表。
最后在浏览器中输入http://127.0.0.1:8000/user/your_username,就得到了最后的结果。虽然模板成功展示了,但是现在用户还没有对应的bookmark数据。我们可以通过交互窗口创建一写bookmarks。
运行python manage.py shell
然后执行下面的命令:
>>> from django.contrib.auth.models import User >>> from bookmarks.models import * >>> user = User.objects.get(id=1) >>> link = Link.objects.get(id=1) >>> user.bookmark_set.all() [] >>> bookmark = Bookmark( ... title=‘Packt Publishing‘, ... user=user, ... link=link ... ) >>> bookmark.save() >>> user.bookmark_set.all() [<Bookmark: Bookmark object>]
这样,页面中就会展示bookmarks信息了。
标签:
原文地址:http://www.cnblogs.com/fireflow/p/5126151.html