关于“Python”的核心知识点整理大全55

发布时间:2024年01月02日

目录

注意

3. 模板

topic.html

4. 将显示所有主题的页面中的每个主题都设置为链接

topics.html

18.5 小结

第 19 章

用户账户

19.1 让用户能够输入数据

19.1.1 添加新主题

1. 用于添加主题的表单

forms.py

2. URL模式new_topic

urls.py

3. 视图函数new_topic()

views.py

4. GET请求和POST请求

5. 模板new_topic

new_topic.html

往期快速传送门👆(在文章最后):

感谢大家的支持!欢迎订阅收藏!专栏将持续更新!


?

--snip--
1 def topic(request, topic_id):
 """显示单个主题及其所有的条目"""
2 topic = Topic.objects.get(id=topic_id)
3 entries = topic.entry_set.order_by('-date_added')
4 context = {'topic': topic, 'entries': entries}
5 return render(request, 'learning_logs/topic.html', context)

这是第一个除request对象外还包含另一个形参的视图函数。这个函数接受正则表达式 (?P\d+)捕获的值,并将其存储到topic_id中(见1)。在2处,我们使用get()来获取 指定的主题,就像前面在Django shell中所做的那样。在3处,我们获取与该主题相关联的条目, 并将它们按date_added排序:date_added前面的减号指定按降序排列,即先显示最近的条目。我们将主题和条目都存储在字典context中(见4),再将这个字典发送给模板topic.html(见5)。


注意

2处和3处的代码被称为查询,因为它们向数据库查询特定的信息。在自己的项目中编 写这样的查询时,先在Django shell中进行尝试大有裨益。相比于编写视图和模板,再在 浏览器中检查结果,在shell中执行代码可更快地获得反馈。


3. 模板

这个模板需要显示主题的名称和条目的内容;如果当前主题不包含任何条目,我们还需向用 户指出这一点:

topic.html
{% extends 'learning_logs/base.html' %}
{% block content %}
1 <p>Topic: {{ topic }}</p>
 <p>Entries:</p>
2 <ul>
3 {% for entry in entries %}
 <li>
4 <p>{{ entry.date_added|date:'M d, Y H:i' }}</p>
5 <p>{{ entry.text|linebreaks }}</p>
 </li>
6 {% empty %}
 <li>
 There are no entries for this topic yet.
 </li>
 {% endfor %}
 </ul>
{% endblock content %}

像这个项目的其他页面一样,这里也继承了base.html。接下来,我们显示当前的主题(见1), 它存储在模板变量{{ topic }}中。为什么可以使用变量topic呢?因为它包含在字典context中。 接下来,我们开始定义一个显示每个条目的项目列表(见2),并像前面显示所有主题一样遍历 条目(见3)。

每个项目列表项都将列出两项信息:条目的时间戳和完整的文本。为列出时间戳(见4), 我们显示属性date_added的值。在Django模板中,竖线(|)表示模板过滤器——对模板变量的值 进行修改的函数。过滤器date: 'M d, Y H:i'以这样的格式显示时间戳:January 1, 2015 23:00。 接下来的一行显示text的完整值,而不仅仅是entry的前50个字符。过滤器linebreaks(见5)将 包含换行符的长条目转换为浏览器能够理解的格式,以免显示为一个不间断的文本块。在6处, 我们使用模板标签{% empty %}打印一条消息,告诉用户当前主题还没有条目。

4. 将显示所有主题的页面中的每个主题都设置为链接

在浏览器中查看显示特定主题的页面前,我们需要修改模板topics.html,让每个主题都链接 到相应的网页,如下所示:

topics.html
--snip--
 {% for topic in topics %}
 <li>
 <a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a>
 </li>
 {% empty %}
--snip-- 

我们使用模板标签url根据learning_logs中名为topic的URL模式来生成合适的链接。这个 URL模式要求提供实参topic_id,因此我们在模板标签url中添加了属性topic.id。现在,主题列 表中的每个主题都是一个链接,链接到显示相应主题的页面,如http://localhost:8000/topics/1/。 如果你刷新显示所有主题的页面,再单击其中的一个主题,将看到类似于图18-5所示的页面。

18.5 小结

在本章中,你首先学习了如何使用Django框架来创建Web应用程序。你制定了简要的项目规 范,在虚拟环境中安装了Django,创建了一个项目,并核实该项目已正确地创建。你学习了如何 创建应用程序,以及如何定义表示应用程序数据的模型。你学习了数据库,以及在你修改模型后, Django可为你迁移数据库提供什么样的帮助。你学习了如何创建可访问管理网站的超级用户,并 使用管理网站输入了一些初始数据。

你还探索了Django shell,它让你能够在终端会话中处理项目的数据。你学习了如何定义URL、 创建视图函数以及编写为网站创建网页的模板。最后,你使用了模板继承,它可简化各个模板的 结构,并使得修改网站更容易。

在第19章,我们将创建对用户友好而直观的网页,让用户无需通过管理网站就能添加新的主 题和条目,以及编辑既有的条目。我们还将添加一个用户注册系统,让用户能够创建账户和自己 的学习笔记。让任意数量的用户都能与之交互,是Web应用程序的核心所在。

第 19 章

用户账户

19.1 让用户能够输入数据

建立用于创建用户账户的身份验证系统之前,我们先来添加几个页面,让用户能够输入数据。 我们将让用户能够添加新主题、添加新条目以及编辑既有条目。

当前,只有超级用户能够通过管理网站输入数据。我们不想让用户与管理网站交互,因此我 们将使用Django的表单创建工具来创建让用户能够输入数据的页面。

19.1.1 添加新主题

首先来让用户能够添加新主题。创建基于表单的页面的方法几乎与前面创建网页一样:定义 一个URL,编写一个视图函数并编写一个模板。一个主要差别是,需要导入包含表单的模块 forms.py。

1. 用于添加主题的表单

让用户输入并提交信息的页面都是表单,那怕它看起来不像表单。用户输入信息时,我们需 要进行验证,确认提供的信息是正确的数据类型,且不是恶意的信息,如中断服务器的代码。然 后,我们再对这些有效信息进行处理,并将其保存到数据库的合适地方。这些工作很多都是由 Django自动完成的。

在Django中,创建表单的最简单方式是使用ModelForm,它根据我们在第18章定义的模型中 的信息自动创建表单。创建一个名为forms.py的文件,将其存储到models.py所在的目录中,并在 其中编写你的第一个表单:

forms.py
from django import forms
from .models import Topic
1 class TopicForm(forms.ModelForm):
 class Meta:
2 model = Topic
3 fields = ['text']
4 labels = {'text': ''}

我们首先导入了模块forms以及要使用的模型Topic。在1处,我们定义了一个名为TopicForm 的类,它继承了forms.ModelForm。

最简单的ModelForm版本只包含一个内嵌的Meta类,它告诉Django根据哪个模型创建表单,以 及在表单中包含哪些字段。在?处,我们根据模型Topic创建一个表单,该表单只包含字段text (见?)。?处的代码让Django不要为字段text生成标签。

2. URL模式new_topic

这个新网页的URL应简短而具有描述性,因此当用户要添加新主题时,我们将切换到 http://localhost:8000/new_topic/。下面是网页new_topic的URL模式,我们将其添加到learning_logs/ urls.py中:

urls.py
--snip--
urlpatterns = [
 --snip--
 # 用于添加新主题的网页
 url(r'^new_topic/$', views.new_topic, name='new_topic'),
] 

这个URL模式将请求交给视图函数new_topic(),接下来我们将编写这个函数。

3. 视图函数new_topic()

函数new_topic()需要处理两种情形:刚进入new_topic网页(在这种情况下,它应显示一个 空表单);对提交的表单数据进行处理,并将用户重定向到网页topics:

views.py
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from .models import Topic
from .forms import TopicForm
--snip--
def new_topic(request):
 """添加新主题"""
1 if request.method != 'POST':
 # 未提交数据:创建一个新表单
2 form = TopicForm()
 else:
 # POST提交的数据,对数据进行处理
3 form = TopicForm(request.POST)
4 if form.is_valid():
5 form.save()
6 return HttpResponseRedirect(reverse('learning_logs:topics'))
7 context = {'form': form}
 return render(request, 'learning_logs/new_topic.html', context)

我们导入了HttpResponseRedirect类,用户提交主题后我们将使用这个类将用户重定向到网 页topics。函数reverse()根据指定的URL模型确定URL,这意味着Django将在页面被请求时生成 URL。我们还导入了刚才创建的表单TopicForm。

4. GET请求和POST请求

创建Web应用程序时,将用到的两种主要请求类型是GET请求和POST请求。对于只是从服务 器读取数据的页面,使用GET请求;在用户需要通过表单提交信息时,通常使用POST请求。处理 所有表单时,我们都将指定使用POST方法。还有一些其他类型的请求,但这个项目没有使用。

函数new_topic()将请求对象作为参数。用户初次请求该网页时,其浏览器将发送GET请求; 用户填写并提交表单时,其浏览器将发送POST请求。根据请求的类型,我们可以确定用户请求 的是空表单(GET请求)还是要求对填写好的表单进行处理(POST请求)。

1处的测试确定请求方法是GET还是POST。如果请求方法不是POST,请求就可能是GET, 因此我们需要返回一个空表单(即便请求是其他类型的,返回一个空表单也不会有任何问题)。 我们创建一个TopicForm实例(见2),将其存储在变量form中,再通过上下文字典将这个表单发 送给模板(见7)。由于实例化TopicForm时我们没有指定任何实参,Django将创建一个可供用户 填写的空表单。

如果请求方法为POST,将执行else代码块,对提交的表单数据进行处理。我们使用用户输 入的数据(它们存储在request.POST中)创建一个TopicForm实例(见3),这样对象form将包含 用户提交的信息。

要将提交的信息保存到数据库,必须先通过检查确定它们是有效的(见?)。函数is_valid() 核实用户填写了所有必不可少的字段(表单字段默认都是必不可少的),且输入的数据与要求的 字段类型一致(例如,字段text少于200个字符,这是我们在第18章中的models.py中指定的)。这 种自动验证避免了我们去做大量的工作。如果所有字段都有效,我们就可调用save()(见?), 将表单中的数据写入数据库。保存数据后,就可离开这个页面了。我们使用reverse()获取页面topics的URL,并将其传递给HttpResponseRedirect()(见6),后者将用户的浏览器重定向到页 面topics。在页面topics中,用户将在主题列表中看到他刚输入的主题。

5. 模板new_topic

下面来创建新模板new_topic.html,用于显示我们刚创建的表单:

new_topic.html
{% extends "learning_logs/base.html" %}
{% block content %}
 <p>Add a new topic:</p>
1 <form action="{% url 'learning_logs:new_topic' %}" method='post'>
2 {% csrf_token %}
3 {{ form.as_p }}
4 <button name="submit">add topic</button>
 </form>
{% endblock content %}

?

关于“Python”的核心知识点整理大全37-CSDN博客

关于“Python”的核心知识点整理大全25-CSDN博客

关于“Python”的核心知识点整理大全12-CSDN博客

往期快速传送门👆(在文章最后):

感谢大家的支持!欢迎订阅收藏!专栏将持续更新!

文章来源:https://blog.csdn.net/lzy302810/article/details/135284118
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。