整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

小白必看!Django 模板语言基础来啦

者 | 单雨

责编 | 胡巍巍

出品 | CSDN(ID:CSDNnews)

前言

为了实现模板封装和复用,提高HTML界面调试便捷性以及前后端解耦等目标,Django定义了自己的网络模板语言。

当前介绍模板语言的官方文档已经非常完备,几乎涵盖了开发中需要用到的知识点和需要注意的问题,但同时官方文档也存在一些问题:

  • 翻译不够完善,带来阅读的困难;

  • 一些知识点的介绍过于简短,存在大量的页内链接,阅读时需要跳转到不同的页面,阅读不连贯。

本文基于官方文档系统介绍了Django模板语言的基础知识点,方便快速了解Django模板语言。

模板系统设计哲学

Django的模板系统不是简单的把Python嵌入到HTML中。

它的设计宗旨是:模板系统旨在展示内容, 而不是程序逻辑,因此不在HTML页面中嵌入Python。

简单的说,模板只负责渲染数据,大多数逻辑应该交给视图(view)进行处理。

模板简介

模板是一个简单的文本文件。它可以生成任何基于文本的格式(如 HTML,XML,CSV等)。除了基本的HTML标签外,模板还包含两种额外的元素——变量和标签。

模板中包含的变量可以被替换为变量的值,标签则被替换为相应的模板控制逻辑。示例:

django

{% extends "base_generic.html" %}

{% block title %}{{ section.title }}{% endblock %}

{% block content %}

<h1>{{ section.title }}</h1>

{% for story in story_list %}

<h2>

<a href="{{ story.get_absolute_url }}">

{{ story.headline|upper }}

</a>

</h2>

<p>{{ story.tease|truncatewords:"100" }}</p>

{% endfor %}

{% endblock %}

`{{ section.title }}`在模板渲染时将会被变量的值替换,for标签可以实现模板的循环渲染。

基础语法

变量

变量实现从模板上下文字典(返回HTTP响应时传递过来的字典)中输出一个值,这是一个类似于dict的对象,包含键值对。当模板引擎遇到一个变量时,它会计算该变量,并用结果替换它。

变量名由字母、数字字符和下划线("_")组成,但不能以下划线开头。点(".")也出现在变量中,代表属性调用,变量名中不能有空格或标点符号。

示例:

django

My first name is {{ first_name }}. My last name is {{ last_name }}.

当传入一个上下文字典`{'first_name': 'John', 'last_name': 'Doe'}`时,将会渲染得到:

django

My first name is John. My last name is Doe.

模板中的变量被字典中的值替换了。

变量还可以使用点表示法实现字典查找、属性查找和列表索引查找等操作:

django

{{ my_dict.key }}

{{ my_object.attribute }}

{{ my_list.0 }}

点表示法底层原理

当模板系统遇到一个点,它会按顺序尝试下面的动作:

1. 字典查询

2. 属性或方法查找

3. 数字索引查询

如果结果值是可调用的,则调用该值时将不带参数,调用的结果成为新的模板值。

当进行能覆盖字典查找的操作时,这种查找顺序可能会造成一些意想不到的行为。例如:如果试图循环一个collection .defaultdict字典对象:

django

{% for k, v in defaultdict.items %}

{其他操作}

{% endfor %}

因为字典查找是首先发生的,所以这个行为会先提供一个默认值,而不是使用预期的.items方法。在这种情况下,应该首先考虑使用字典查找,而不是使用字典的属性调用。

注意

属性通常被解释为一个文本字符串,防止和同名的变量冲突。例如{{foo.bar}}中的属性“bar”将被解释为一个文本字符串,如果模板上下文中存在变量“bar”,则不会使用该变量的值。

以下划线开头的变量属性可能不能访问,因为它们通常被认为是私有的。

如果引用不存在的变量,模板系统将插入string_if_invalid选项的值,该选项默认设置为“”(空字符串)。

标签

标签在模板渲染过程中提供任意逻辑。标签可以输出内容,作为控制结构,例如“if”语句或“for”循环,从数据库获取内容,甚至允许访问其他模板标签。

(1)标签声明

标签的一般形式为:

django

{% tag %}

示例:

django

{% csrf_token %}

(2)传入参数

django

{% cycle 'odd' 'even' %}

(3)成对使用的标签

有些标签需要开始和结束标签:

django

{% if user.is_authenticated %}Hello, {{ user.username }}.{% endif %}

(4)常用标签

for:循环数组中的每个元素. 比如, 显示列表 `athlete_list` 中每个元素的 `name` 属性。

django

<ul>

{% for athlete in athlete_list %}

<li>{{ athlete.name }}</li>

{% endfor %}

</ul>

if 、elif和else:在上面,如果athlete_list不为空,则{{athlete_list|length}}变量将显示运动员的数量。

否则,如果athlete_in_locker_room_list不为空,则会显示“Athletes should be out…”消息。如果两个列表都为空,则显示“No athletes”。

也可以在if标签里使用过滤器和各种操作符:

django

{% if athlete_list|length > 1 %}

Team: {% for athlete in athlete_list %} ... {% endfor %}

{% else %}

Athlete: {{ athlete_list.0.name }}

{% endif %}

注意

虽然上面的示例可以工作,但是要注意,大多数模板过滤器都返回字符串,因此使用过滤器进行数学比较通常不会正常工作,而长度是个例外。

(5)更多

Django有很多内置标签,更多关于内置标签的信息请参考官方文档:

https://docs.djangoproject.com/zh-hans/2.2/ref/templates/builtins/ref-templates-builtins-tags

如果需要编写自定义标签,请参考官方文档

https://docs.djangoproject.com/zh-hans/2.2/howto/custom-template-tags/howto-writing-custom-template-tags

如果需要对使用的标签和自定义的标签做一份说明文档,可以使用Django提供的文档工具,详情请参考:

https://docs.djangoproject.com/zh-hans/2.2/ref/contrib/admin/admindocs/

过滤器

简介

过滤器可以对变量做一些操作,例如给变量赋值,改变变量的值等。

修改变量显示

过滤器可以修改变量的显示。例如:

django

{{ name|lower }}

通过过滤器lower变量{{ name }}变为了小写字符,通过管道符(|)间隔变量和过滤器来使用过滤器。

链式调用过滤器

一个过滤器的输出可以作为下一个过滤器的输入。

{{ text|escape|linebreaks }}是一种常用的转换方式, 在这之后换行符被替换为了 <p> 标签。

转换变量和标签参数

过滤器转换变量和标签参数的值。示例:

django

{{ django|title }}

传入`{'django': 'the web framework for perfecalist With deadline '}`上下文字典时,该模板呈现为:

django

The Web Framework For Perfectionists With Deadlines

传入参数给过滤器

示例1:

django

{{ my_date|date:"Y-m-d" }}

my_date将会被替换为当前日期。

示例2:

django

{{ bio|truncatewords:30 }}

将会会显示 `bio` 变量的前30个字符

注意

过滤器参数中如果包含空格和标点符号,必须使用引号“”括起来,例如,要用逗号和空格连接列表,可以使用{{list|join:", "}}。

Django提供了大约60个内置模板过滤器,请参考官方文档:

https://docs.djangoproject.com/zh-hans/2.2/ref/templates/builtins/ref-templates-builtins-filters

下面列举一些常用的过滤器:

default

如果变量为false或空,则使用给定的默认值。否则,使用变量的值。例如:

django

{{ value|default:"nothing" }}

如果 `value` 没有提供或者为空,那么将它显示为 "`nothing`" 。

length

返回值的长度。这对字符串和列表都适用。例如:

django

{{ value|length }}

如果 `value` 为 `['a', 'b', 'c', 'd']`, 那么他将被显示为 `4`。

filesizeformat

将值格式化为“人类可读的”文件大小(即“13kb”、“4.1 MB”、“102字节”等)。例如:

django

{{ value|filesizeformat }}

如果值为123456789,则输出为117.7 MB。

如果需要自定义过滤器,请参考请官方文档:

https://docs.djangoproject.com/zh-hans/2.2/howto/custom-template-tags/

注释

示例:

单行注释

django

{ this won't be rendered }

多行注释:{% comment %} 和{% endcomment %}

django

<p>Rendered text with {{ pub_date|date:"c" }}</p>

{% comment "Optional note" %}

<p>Commented out text with {{ create_date|date:"c" }}</p>

{% endcomment %}

注意:Comment标签不能嵌套使用。

作者简介:单雨,90后工科男,伪文艺青年。目前就读于北京理工大学宇航系,喜欢研究AI,网络爬虫,微信小程序以及机器人,痴迷于Coding,睡前必撸码。

【END】

家好,我是皮皮。

一、前言

还是昨天的那个网络爬虫问题,大佬们,帮忙看看这个网络爬虫代码怎么修改?那个粉丝说自己不熟悉pandas,用pandas做的爬虫,虽然简洁,但是自己不习惯,想要在他自己的代码基础上进行修改,获取数据的代码已经写好了,就差存储到csv中去了。

他的原始代码如下:

import requests
from lxml import etree
import csv
import time
import pandas as pd 


def gdpData(page):
    url = f'https://www.hongheiku.com/category/gdjsgdp/page/{page}'
    headers ={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'}
    resp = requests.get(url,headers = headers)
# print(resp.text)
    data(resp.text)
file = open('data.csv',mode='a',encoding='utf-8',newline='')
csv_write=csv.DictWriter(file,fieldnames=['排名','地区','GDP','年份'])
csv_write.writeheader()
def data(text):
    e = etree.HTML(text)
    lst = e.xpath('//*[@id="tablepress-48"]/tbody/tr[@class="even"]')
    for l in lst:
        no = l.xpath('./td[1]/center/span/text()')
        name = l.xpath('./td[2]/a/center/text()')
        team = l.xpath('./td[3]/center/text()')  
        year = l.xpath('./td[4]/center/text()')
        data_dict = {
            '排名':no,
            '地区':name,
            'GDP':team,
            '年份':year
        }
        print(f'排名:{no} 地区:{name} GDP:{team} 年份:{year} ')
        csv_write.writerow(data_dict)
file.close()
url = 'https://www.hongheiku.com/category/gdjsgdp'
headers ={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'}
resp = requests.get(url,headers = headers)
# print(resp.text)
data(resp.text)
e = etree.HTML(resp.text)
#//*[@id="tablepress-48"]/tbody/tr[192]/td[3]/center
count = e.xpath('//div[@class="pagination pagination-multi"][last()]/ul/li[last()]/span/text()')[0].split(' ')[1]
for index in range(int(count) - 1):
    gdpData(index + 2)

二、实现过程

这里粉丝给了一瓶冰红茶的费用,一个热心市民给了一份代码,在他的代码基础上进行修改的,代码如下:

import requests
from lxml import etree
import csv
import time
import pandas as pd


def gdpData(page):
    url = f'https://www.hongheiku.com/category/gdjsgdp/page/{page}'
    headers ={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'}
    resp = requests.get(url,headers = headers)
# print(resp.text)
    data(resp.text)

def data(text):
    file = open('data.csv', mode='a', encoding='utf-8', newline='')
    csv_write = csv.DictWriter(file, fieldnames=['排名', '地区', 'GDP', '年份'])
    csv_write.writeheader()
    e = etree.HTML(text)
    lst = e.xpath('//*[@id="tablepress-48"]/tbody/tr[@class="even"]')
    for l in lst:
        no = ''.join(l.xpath('./td[1]/center/span/text()'))
        name = ''.join(l.xpath('./td[2]/a/center/text()')[0])
        team = ''.join(l.xpath('./td[3]/center/text()'))
        year = ''.join(l.xpath('./td[4]/center/text()'))
        data_dict = {
            '排名':no,
            '地区':name,
            'GDP':team,
            '年份':year
        }
        print(f'排名:{no} 地区:{name} GDP:{team} 年份:{year} ')
        csv_write.writerow(data_dict)
    file.close()

url = 'https://www.hongheiku.com/category/gdjsgdp'
headers ={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'}
resp = requests.get(url,headers = headers)
# print(resp.text)
data(resp.text)

e = etree.HTML(resp.text)
#//*[@id="tablepress-48"]/tbody/tr[192]/td[3]/center
count = e.xpath('//div[@class="pagination pagination-multi"][last()]/ul/li[last()]/span/text()')[0].split(' ')[1]
for index in range(int(count) - 1):
    gdpData(index + 2)

代码运行之后,数据就存储到csv中去了。

顺利地解决了粉丝的问题!

三、总结

大家好,我是皮皮。这篇文章主要盘点了一个Python网络爬虫后数据存储的问题,文中针对该问题,给出了具体的解析和代码实现,帮助粉丝顺利解决了问题。

最后感谢粉丝【蓝桉】提问,感谢【热心市民】给出的思路和代码解析,感谢【eric】等人参与学习交流。

人可能会与您分享需要的PDF 文档。要向文档添加更多内容,您可能会发现需要向其中添加页面。但即使只是编辑 PDF 文档上的现有内容也可能非常困难。如何向 PDF 添加页面?

通过您选择使用的 PDF 页面编辑器,可以更轻松地向 PDF 文档添加页面。在本文中,我们将介绍一些可以给PDF添加页面的编辑器,并向您展示如何使用它们。

为什么您可能需要将页面插入 PDF

您想要向现有 PDF 文档添加页面的原因有很多,其中包括:

  • 给PDF 文档添加页面的最常见原因是您可以向文档添加更多内容。
  • 在 PDF 中插入页面也是将新内容从其他来源导入到现有 PDF 的好方法。例如从另一个 PDF 添加页面。

以下解决方案将帮助您在需要时给PDF 文档添加页面。

将页面添加到 PDF 的最佳工具

如果您正在寻找一种可以轻松向 PDF 文档添加页面的解决方案,那么UPDF - PDF 编辑器是您的最佳选择。此PDF 编辑器是编辑 PDF 文档的最佳方法之一,它最擅长的是允许您管理 PDF 上的页面。这意味着您可以将页面添加到文档的几乎任何部分。

我们将在本文的下一部分中了解此过程的工作原理。但在此之前,让我们先看看 UPDF 的其他功能。

  • UPDF 是管理现有 PDF 文档页面的最佳方法之一。您可以使用它来提取PDF页面、添加新页面、旋转页面,甚至提取特定页面。
  • 这也是编辑 PDF 中图像的最佳方法之一。您可以选择图像、调整图像大小、复制、删除图像,甚至将新图像添加到文档中。
  • 同样,您可以轻松地将新文本内容添加到文档中,并通过更改字体样式、颜色和大小来编辑现有内容。
  • 您可以向 PDF 文档添加突出显示、便签、文本框和其他注释。
  • 它提供了几种阅读PDF文档的好模式,您也可以向PDF添加书签。
  • 您可以将 PDF 转换为 MS Office 格式、图像、CSV、RTF、文本、XML、HTML、PDF/A 等。

方法1:如何在 PDF 中添加空白页?

如果您使用 UPDF 打印 PDF 文档,您可以通过以下方式旋转 PDF 页面:

第1步:打开 PDF。

在主界面中,单击“打开文件”按钮,然后浏览要编辑的PDF文档。

第2步:将空白页插入 PDF。

在 UPDF 中打开文档后,单击左侧的“组织页面”选项卡。这将打开页面管理界面。

方法2:如何从另一个文件将页面插入 PDF?

有时您想将两个PDF文件合并在一起,但又希望将第二个PDF文件放置在某个位置,那么您可以使用UPDF的插入选项来帮助您。您可以直接将另一个 PDF 文件插入到当前 PDF 文件中。

第1步:选择“来自文件”选项

如果您想从另一个 PDF 文档添加页面,您应该单击页面来选择要插入的位置。现在单击“插入”选项并选择“来自文件”。

第 2步:插入另一个 PDF 文档中的页面。

然后,您可以浏览计算机查找要添加到当前文档的 PDF。然后单击“打开”按钮。

PDF 文件将被插入到您选择的位置。您可以重新排序、编辑、注释或转换 PDF 文件。

方法3:如何通过组合将页面添加到PDF

UPDF 提供了另一种方法来帮助您将整个 PDF 插入到另一个 PDF 文件中。如果您想将两个或多个 PDF 文件的所有页面插入在一起,可以按照以下步骤操作:

步骤1:在UPDF的欢迎页面上,您将看到有一个“批量”选项,点击它。

步骤 2:该工具提供了许多批处理选项。根据需要选择“组合”选项。

步骤 3:在新窗口中,您可以添加要插入的PDF文件并将它们组合在一起。单击“应用”开始该过程。完成此过程后,您可以轻松地重新排列 PDF 文件中的页面。

方法4:如何一次将页面插入多个 PDF 文件?

如果想将一个 PDF 一次性插入到其他多个 PDF 文件中。UPDF 也可以帮助您。请按照以下说明操作:

步骤1:与方法3相同,请点击“批量”>“插入”选项。

步骤2:在右侧区域,您需要选择要插入到多个PDF文件中的单个文件。您可以设置该文件的位置:在前面、在末尾或在哪一页之后。

步骤 3:在左侧区域,您需要添加多个PDF文件。

步骤4:点击“应用”。

方法5:如何在Adob​e Reader中将页面添加到PDF?

首先,您无法使用Adobe Reader向PDF添加页面,因为Reader DC是免费版本,只能用于阅读和注释PDF文档。

如果您想向 PDF 添加页面,则必须升级到 Adob​​e Acrobat Standard DC 或 Pro DC,这非常昂贵(每年 239.88 美元)。

升级到 Adob​​e Acrobat Pro 后,您可以按照以下步骤操作:

步骤1:单击“工具”选项并选择“组织页面”工具。

步骤2:打开您的 PDF 文档。

步骤3:单击“插入”选项,您可以开始使用 Adob​​e Acrobat Pro DC 将页面插入 PDF。

既然Acrobat太贵了,而且使用起来有点复杂,为什么不改用UPDF呢?一款更具成本效益的PDF编辑器,它具有向PDF添加页面、编辑PDF文本和图像、将PDF文档转换为其他格式、OCR以及许多其他功能等功能。

方法6.如何在线将页面插入PDF

有一些网络工具可用于在线将页面添加到 PDF。例如iLovePDF、SmallPDF、Sejda等。使用在线工具的步骤类似,您可以按照以下步骤操作:

步骤1:转到任何支持组织页面功能的在线工具。您可以使用关键字“在线将页面插入 PDF”在 Google 上搜索。谷歌会展示很多解决方案。

步骤2:将您的 PDF 文件上传到在线网站。所有在线工具都要求您上传 PDF 文件,并且大多数工具都对文件大小或页码有限制。如果您想免费使用它,则必须满足其限制要求。

步骤3:成功上传后,您现在可以找到将页面插入 PDF 的工具。大多数在线工具只允许您插入空白页面,但不允许插入其他 PDF 文件。

步骤4:修改后下载文件。

但是,使用在线工具将页面添加到 PDF 并不稳定,因为您必须连接到互联网。如果网络不好,会影响结果,甚至损坏你的PDF文档。

在线解决方案的另一个问题是您必须担心文档的安全性。为什么不使用 UPDF 来代替呢?它是桌面版本,非常稳定且使用速度快。您的所有文档都将保存到本地存储,您可以使用 UPDF 轻松编辑、转换、保护和组织它们。

有关向 PDF 添加页面的常见问题解答

1. 如何向现有PDF添加空白页?

您可以使用 UPDF 等 PDF 页面编辑器向现有 PDF 添加空白页面。为此,您可以将 PDF 上传到 UPDF,然后单击“组织页面”图标。接下来,您可以点击顶部的“插入”选项,然后选择“空白页”选项。这样就完成了!

2. 如何在 PDF 中添加和替换页面?

使用 UPDF,您可以快速添加和替换页面。为此,您可以进入“组织页面”模式并选择要替换的页面。然后您只需单击顶部的“替换”图标并选择一个文件来替换页面即可。

3. 我可以更改 PDF 页面吗?

是的,当然可以。使用UPDF,您可以轻松更改PDF中的页面,例如替换、添加、删除、旋转、提取、分割和裁剪PDF中的页面。

结论

当您忘记在 PDF 中添加页面时,您不必从头开始文档创建过程,而是可以使用 UPDF 在文档的任何部分添加页面。能够做到这一点并让事情变得简单明了的最佳解决方案是 UPDF。无需了解任何内容,只需几个简单的步骤即可将页面添加到文档的任何部分。