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

2019-02-02  本文已影响50人  9756a8680596

MTV设计模式

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

  1. Models:用来构建和操作web应用中的数据
  1. Views:用于封装负责处理用户请求及返回响应的逻辑
  1. Templates:使用模板可以动态地生成html

MTV实例

  1. 目标是通过分页功能来理解Django中MTV工作模式,并熟悉模板语言的使用。
  2. 在开始分页功能之前,先来学习一个概念:上下文(context),上下文会在render函数中使用。其实render函数其主要作用是将给定的模板与给定的上下文字典组合在一起,并以渲染的文本返回一个 HttpResponse 对象。
  3. 一般来说,render函数常用的参数有三个(实际不止三个)
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 %}
上一篇 下一篇

猜你喜欢

热点阅读