Django Web开发【3】创建网络收藏夹

  这一节我们将继续一个创建网络收藏夹应用,并学习视图、模型以及模板的处理过程。

  Django是一个MVC开发框架,但是它的控制器对应的为view,而视图对应为模板(template),模型对应model,所以Django也成为MTV框架。

  URLS和视图函数(Views)

  view(视图函数)通过生成页面来响应某个用户请求,首先我们在项目中先创建一个应用,应用是包含视图与数据模型的容器,在django_boookmarks目录下运行下面的命令:

$ python manage.py startapp bookmarks

  创建应用的语法与创建项目的语法类似。运行上述命令之后,Django会自动在bookmarks目录下生成下面的文件。

  • __init__.py 表明这是一个包
  • views.py  包含视图函数
  • models.py 包含数据模型

  接下来,创建主页视图:

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的工作流程如下所示:

  • 当用户请求http://127.0.0.1:8000/时,Django会在urls.py中查找匹配的URL,匹配通过正则表达式完成。
  • 如果Django找到匹配的URL,就会调用相应的视图函数,视图函数就收用户浏览器提交的数据信息,然后生成响应页面返回给用户。
  • 如果Django没有找到匹配的URL,Django将抛出404异常,同时展示Page Not Found页面。在调试模式下,Django会打印丰富的帮助信息,当然,在部署环境中饭可以关闭调试模式。

  数据模型

  现在几乎所有的Web站点都会使用数据库管理保存数据,数据库现在已经是网站的重要组成部分。接下里,我们将使用数据库管理用户账号与网络收藏夹。如果你习惯了使用SQL语句对处理数据库,那么你将发现Django处理数据库的方式不太一样,Django是通过Python类对数据库进行管理的。

  下面通过例子来讲解,对于我们的网路收藏夹,我们需要在数据库中保存如下信息:

  • User(ID,username,password,email)
  • Links(ID,URL)
  • Bookmarks(ID,title,user_id,link_id)

  为了将上面的数据表设计转换成Python代码,需要再bookmarks目录下的models.py进行编辑,models.py用来保存数据模型。

  ♥Link数据模型

  打开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再执行的。这样做的好处是非常明显的:

  • 不需要非常了解SQL语句
  • Django透明的处理Python对象与数据表的转换,你只需要与Python打交道。
  • 开发者不需要担心不同数据库而导致的SQL差异。不管使用哪种数据库,Django提供的接口都是一样的。
  ♥User数据模型

  接下来创建用户数据模型,幸运的是,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数据模型

   最后我们定义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硬编码到代码中,创建了一个简单的应用主页,这样有很多缺点:

  • 优秀的软件工程实践一直强调UI与业务逻辑的分离,因为这样才会增强代码的重用性。而在Python代码中编辑HTML违反了这一原则。
  • 修改嵌套在Python中的HTML代码需要了解Python知识,但是作为前端开发者,很多都不了解Python,所以这样做也不实际。
  • 在Python中处理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。

  1.设计URL

  这个视图的URL格式为:user/username,username是书签所有者的用户名,这个URL与我们之前添加的URL不太一样,它包含了一个动态部分,我们需要使用正则表达式来表示这个URL,编辑urls.py,

urlpatterns = patterns('',
    (r'^$', main_page),
    (r'^user/(w+)/$', user_page),
)

  w代表任意一个字母数字或者下划线,+代表一个或者多个。

  2.创建视图函数

  打开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会自动检查不同模型之间的关系,然后生成这样的属性。

  3.设计模板

  在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信息了。

  

原文地址:https://www.cnblogs.com/fireflow/p/5126151.html