zoukankan      html  css  js  c++  java
  • 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信息了。

      

  • 相关阅读:
    pymssql连接Azure SQL Database
    Python升级后ssl模块不可用问题解决和浅析
    CentOS 7升级Python到3.6.6后yum出错问题解决总结
    Python监控SQL Server数据库服务器磁盘使用情况
    fastjason常用方法
    类型擦除真的能完全擦除一切信息吗?java 泛型揭秘
    spring boot打包成war包的页面该放到哪里?
    为什么delete后磁盘空间没有释放而truncate会释放?
    leetcode 977. Squares of a Sorted Array
    leetcode 844. Backspace String Compare
  • 原文地址:https://www.cnblogs.com/fireflow/p/5126151.html
Copyright © 2011-2022 走看看