美文网首页
【爬虫】-008-Django-2-MTV实例

【爬虫】-008-Django-2-MTV实例

作者: 9756a8680596 | 来源:发表于2019-02-02 01:16 被阅读50次

MTV设计模式

Django框架接收了用户请求和参数后,通过正则表达式匹配URL,转发给对应视图views进行处理,视图调用模型models处理数据,再调用模板templates返回界面给浏览器。

  1. Models:用来构建和操作web应用中的数据
  • 继续讲解models之前,必须说下对象关系映射(Object Relational Mapping,简称ORM),ORM使用对象和数据库建立映射,即将程序中的对象自动持久化到关系数据库中。ORM是业务逻辑层和数据库层之间的桥梁。
  • Django项目的settings.py文件中,配置数据库连接信息,包括数据库名称等信息。之后,通过models实现对数据库表的操作和数据存储。通常每个model对应数据库中唯一的一张表,关于ORM和数据库表的关系如下图。
    ORM和数据库表关系
  1. Views:用于封装负责处理用户请求及返回响应的逻辑
  • Views可以看作是前端页面与数据库的中间人,它会将前端想要的数据从数据库中读出来给前端,也会将用户要想保存的数据写到数据库。
  1. Templates:使用模板可以动态地生成html
  • 模板包含所需html输出的静态部分
  • 同时,模板语法可以描述如何将动态内容插入到html页面中。

MTV实例

  1. 目标是通过分页功能来理解Django中MTV工作模式,并熟悉模板语言的使用。
  2. 在开始分页功能之前,先来学习一个概念:上下文(context),上下文会在render函数中使用。其实render函数其主要作用是将给定的模板与给定的上下文字典组合在一起,并以渲染的文本返回一个 HttpResponse 对象。
  3. 一般来说,render函数常用的参数有三个(实际不止三个)
  • request,用于生成此响应的请求对象
  • template_name,要使用的模板的全名或模板名称的序列
  • context,要添加到模板上下文的值的字典。 默认情况下,这是一个空的字典。 如果字典中的值是可调用的,则视图将在渲染模板之前调用它。简单来说,context参数就是把数据库中要在网页显示的内容读取,然后填充到模板中动态显示。
context示意图
  1. 看一个render函数示例
def index(request):
    context = {
        'title': 'Context-Test',
        'description':  'Just some words.'
    }
    return render(request, 'index.html', context)

对应templates中的html代码如下:

      <li>
        <img src="{% static 'images/0002.jpg' %}" width="100" height="90">
        <h3><a href="#">{{ title }}</a></h3>
        <p>{{ description }}</p>
      </li>

这样在views调用teplates的时候就会加载context中内容,如果把context与数据库结合使用,那么就可以动态加载数据

  1. 理解了context功能之后,接下里要考虑如何从数据库获取数据来。这个时候就用到来models。如开头所讲models相当于数据库的代理,它对数据进行操作。以mongoDB为例,首先需要在settings.py中配置数据库信息:
from mongoengine import connect
connect(database_name, host='127.0.1', port=27017)
  1. 现在根据第一部分介绍的ORM,建立数据模型
# 定义一个类
class ArtiInfo(Document):
    # 类的属性(collection中的字段名),右侧是字段类型
    description = StringField()
    title = StringField()
    # 在数据库中创建一个collection,名为arti_info
    meta = {
        'collection': 'arti_info'
    }

ArtiInfo对象每一个实际是collection中的一行数据,例如:

for item in ArtiInfo.objects:
    print(item.title, item.description)

输出的结果就是数据表collection中每行数据

  1. 对应的在views中修改代码可以使得数据填充到templages构成的页面上下文中,但是因为页面结构的限制,我们需要对数据进行分页保证页面的样式不被破坏,这里需要使用到Django提供的分页器类Paginator,基本知识可参考这里

  2. 在views中使用Paginator类(Paginator Django 用法可参考如下代码),修改后如下:

def index(request):
    # 设置页面每页显示的数据数目
    limit = 4
    # 获取数据对象构成的列表
    arti_info = ArtiInfo.objects

    # 构建分页器对象
    paginator = Paginator(arti_info, limit)
    
    # 设置request请求中GET方式的参数,这个参数是字典格式数据,即page默认为1
    # www.google.com?thisIsAGetVarKey=3&thisIsAnotherOne=hello
    # request.GET would be: {"thisIsAGetVarKey": 3, "thisIsAnotherOne":"hello"}
    # Because request.GET is a dictionary, 
    # it has the method .get() which retrieves a value for a key in the dictionary
    page = request.GET.get('page', 1)

    # 获取某个页面对象,可调用相关方法和属性,包括数据和页面等信息
    loaded = paginator.page(page)

    context = {
        'ArtiInfo': loaded,
    }

    return render(request, 'index.html', context)

关于page = request.GET.get('page', 1),可以解释为寻找名为pageGET参数,而且如果参数没有提交,返回1,详细解释可参考这里

  1. 接下里使用模板语言修改templates对应的代码,是的数据正常动态显示
        {% if ArtiInfo.has_previous %}
            <a href="?page={{ ArtiInfo.previous_page_number }}"> < Pre </a>
        {% endif %}
        <spam> {{ ArtiInfo.number }} of {{ ArtiInfo.paginator.num_pages }} </spam>
        {% if ArtiInfo.has_next %}
            <a href="?page={{ ArtiInfo.next_page_number }}"> Next > </a>
        {% endif %}

相关文章

网友评论

      本文标题:【爬虫】-008-Django-2-MTV实例

      本文链接:https://www.haomeiwen.com/subject/ethhsqtx.html