【实战案例】Django框架表单处理及数据库交互

本文基于之前内容列表如下:
【图文指引】5分钟搭建Django轻量级框架服务
【实战案例】Django框架基础之上编写第一个Django应用之基本请求和响应
【实战案例】Django框架连接并操作数据库MySQL相关API
【实战案例】Django框架使用模板渲染视图页面及异常处理

更新编写的投票详细页面的模板"polls/detail.html"让它包含一个 form表单元素:
(超详细注释版)

<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>这是detail的模板渲染</title>
</head>
<body>
<!--action属性使用{\% url %}模板标签动态生成投票处理的URL。'polls:vote'是命名的URL模式,question.id是传递给该URL的参数(问题的ID)。-->
<!--method="post"指明表单数据通过POST请求提交,适合用于修改服务器端数据(这里是投票)-->
<form action="{% url 'polls:vote' question.id %}" method="post"><!--Django的跨站请求伪造(CSRF)保护机制。它在表单中插入一个隐藏字段,确保请求来自同一个站点,以防止恶意攻击。-->{% csrf_token %}<!--<fieldset>用于分组相关元素,通常与<legend>结合使用,提升可读性和可访问性。--><fieldset><legend><h1>{{ question.question_text }}</h1></legend><!--如果存在错误消息(如用户未选择选项),会显示在表单中。error_message是从视图传递到模板的上下文变量。-->{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}<!--这个循环遍历当前问题的所有选择项(choice_set是Django为一对多关系生成的反向关系管理器)。--><!--对于每个选择项,生成一个单选框(<input type="radio">)和对应的标签(<label>)。--><!--id="choice{\{ forloop.counter }}"为每个单选框生成唯一的ID,forloop.counter是Django模板中的内置变量,从1开始计数。--><!--value="{\{ choice.id }}"将每个单选框的值设置为选择项的ID,以便在提交表单时识别所选的选择项。-->{% for choice in question.choice_set.all %}<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}"><label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>{% endfor %}</fieldset><!--提交按钮,用于提交表单数据。--><input type="submit" value="Vote">
</form>
</body>
</html>

之前创建的URLconf位于polls/urls.py中

path("<int:question_id>/vote/", views.vote, name="vote"),

在polls/views.py中更新如下代码:

from django.db.models import F
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reversefrom .models import Choice, Question# ...
def vote(request, question_id):# 使用 get_object_or_404 函数获取指定问题对象。如果未找到,则返回404错误页面。question = get_object_or_404(Question, pk=question_id)try:# 从POST请求中获取选中的选择项ID,并在该问题的选择集中查找对应的选择项。selected_choice = question.choice_set.get(pk=request.POST["choice"])except (KeyError, Choice.DoesNotExist):# 如果在POST请求中没有找到选择项,或选择项不存在,执行以下操作:# Redisplay the question voting form with an error message.return render(request,  # 当前请求对象"polls/detail.html",  # 渲染的模板{"question": question,  # 重新传递问题对象,以便在模板中显示"error_message": "You didn't select a choice.",  # 错误消息,提示用户未选择任何选项},)else:# 如果成功找到选中的选择项,则增加其票数selected_choice.votes = F("votes") + 1  # 使用 F 表达式进行原子操作,避免竞争条件selected_choice.save()  # 保存更新后的选择项# 返回一个 HttpResponseRedirect,以防止用户在提交后刷新页面导致重复提交return HttpResponseRedirect(reverse("polls:results", args=(question.id,)))# 当有人对 Question 进行投票后, vote() 视图将请求重定向到 Question 的结果界面
def results(request, question_id):question = get_object_or_404(Question, pk=question_id)return render(request, "polls/results.html", {"question": question})

接下来创建polls/results.html模板:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>这是results的模板渲染</title>
</head>
<body>
<h1>{{ question.question_text }}</h1>
<!--<ul>标签用于创建一个无序列表-->
<!--{\% for choice in question.choice_set.all %}:这是一个循环,遍历当前问题的所有选择项。question.choice_set.all是Django的反向关系管理器,用于获取与该问题相关的所有选择项。-->
<!--vote{\{ choice.votes|pluralize }}:使用pluralize过滤器来处理单复数形式。如果得票数为1,显示“vote”,否则显示“votes”。这使得文本更自然,适应不同的得票数。-->
<ul>{% for choice in question.choice_set.all %}<li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>{% endfor %}
</ul>
<!--再次投票链接-->
<a href="{% url 'polls:detail' question.id %}">Vote again?</a>
</body>
</html>

通过上述更新,访问http://localhost:8000/polls/可见如下页面:
在这里插入图片描述
投票页面如下所示:
在这里插入图片描述
在这里插入图片描述
选择选项并点击vote按钮可进行投票,投票后显示票数页面且可再次投票
在这里插入图片描述
对应数据库的数据也会更新
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/455904.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【python实战】利用代理ip爬取Alibaba海外版数据

引言 在跨境电商的业务场景中&#xff0c;数据采集是分析市场、了解竞争对手以及优化经营策略的重要环节。然而&#xff0c;随着越来越多企业依赖数据驱动决策&#xff0c;许多跨境电商平台为了保护自身数据&#xff0c;采取了更严格的防护措施。这些平台通过屏蔽大陆IP地址或部…

qt项目使用其他项目的ui之单继承之成员变量

第一步添加.ui文件 第二步&#xff0c;点击编译(原理&#xff1a;qt的uic会将.ui界面编译成c文件) 第三步&#xff1a;在编译后的目录下找到#include “ui_pagewidget.h” 第四步&#xff1a; #ifndef USA_H #define USA_H#include <QWidget>#include "ui_pagew…

sql高级

数据库的范式 为了建立冗余较小、结构合理的数据库&#xff0c;设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式。 范式是符合某一种设计要求的总结。要想设计一个结构合理的关系型数据库&#xff0c;必须满足一定的范式。实际上&#xff0c;数据库范式…

Nest.js 实战 (十五):前后端分离项目部署的最佳实践

☘️ 前言 本项目是一个采用现代前端框架 Vue3 与后端 Node.js 框架 Nest.js 实现的前后端分离架构的应用。Vue3 提供了高性能的前端组件化解决方案&#xff0c;而 Nest.js 则利用 TypeScript 带来的类型安全和模块化优势构建了一个健壮的服务端应用。通过这种技术栈组合&…

微信小程序绘制轨迹

1、map | uni-app官网 根据官网描述&#xff1a;通过从数据库获取POI数据&#xff0c;并通过 uni-id-common 内的路线规划API&#xff0c;计算路线、距离、时间。 2、 <map style"width:100%;height:96%;" id"myMap" :scale"scale" :longi…

javaWeb项目-ssm+jsp大学生校园兼职系统功能介绍

本项目源码&#xff08;点击下方链接下载&#xff09;&#xff1a;java-ssmjsp大学生校园兼职系统实现源码(项目源码-说明文档)资源-CSDN文库 项目关键技术 开发工具&#xff1a;IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架&#xff1a;ssm、Springboot 前端&#x…

C++【string类的使用】(上)

文章目录 1. 为什么要学习string类2. 标准库的string类2.1 string的构造函数&#xff08;1&#xff09;无参构造&#xff08;重点&#xff09;&#xff08;2&#xff09;用字符串初始化&#xff08;重点&#xff09;&#xff08;3&#xff09;用字符串的前n个字符初始化(4)拷贝…

前端处理返回的number类型超出16位的问题 ,在axios中统一处理

前端处理返回的number类型超出16位的问题 &#xff0c;在axios中统一处理 造成原因&#xff1a;js的number类型有个最大安全值&#xff0c;即2的53次方&#xff08;9007199254740992&#xff09;&#xff0c;超过这个值就会出现精度丢失的问题。 后端处理&#xff1a;将数字类…

MATLAB Simulink (二)高速跳频通信系统

MATLAB & Simulink &#xff08;二&#xff09;高速跳频通信系统 写在前面1 系统原理1.1 扩频通信系统理论基础1.1.1 基本原理1.1.2 扩频通信系统处理增益和干扰容限1.1.3 各种干扰模式下抗干扰性能 1.2 高速跳频通信系统理论基础1.2.1 基本原理1.2.2 物理模型 2 方案设计2…

使用docker-compose搭建redis7集群-3主3从

下面是一个用于搭建 Redis 集群的 docker-compose.yml 示例文件&#xff0c;它会启动 6 个 Redis 节点&#xff08;3 主节点 3 从节点&#xff09;来构成一个最小的 Redis 集群。 同一个容器内网通讯没问题&#xff0c;但是你要是需要暴露到外网你需要用第二个yml 内网的 v…

Leetcode 最长公共前缀

java solution class Solution {public String longestCommonPrefix(String[] strs) {if(strs null || strs.length 0) {return "";}//用第一个字符串作为模板,利用indexOf()方法匹配,由右至左逐渐缩短第一个字符串的长度String prefix strs[0];for(int i 1; i …

stm32单片机基于rt-thread 的 串行 Flash 通用驱动库 SFUD 的使用

1024程序员节&#xff5c;征文 一、sfud 通用驱动库介绍 SFUD 是一款开源的串行 SPI Flash 通用驱动库。由于现有市面的串行 Flash 种类居多&#xff0c;各个 Flash 的规格及命令存在差异&#xff0c; SFUD 就是为了解决这些 Flash 的差异现状而设计&#xff0c;能够支持不同品…

【OpenAI】第六节(语音生成与语音识别技术)从 ChatGPT 到 Whisper 的全方位指南

前言 在人工智能的浪潮中&#xff0c;语音识别技术正逐渐成为我们日常生活中不可或缺的一部分。随着 OpenAI 的 Whisper 模型的推出&#xff0c;语音转文本的过程变得前所未有的简单和高效。无论是从 YouTube 视频中提取信息&#xff0c;还是将播客内容转化为文本&#xff0c;…

K8S系列-Kubernetes网络

一、Kubernetes网络模型 ​ Kubernetes网络模型设计的一个基础原则是&#xff1a;每个Pod都拥有一个独立的IP地址&#xff0c;并假定所有Pod都在一个可以直接连通的、扁平的网络空间中&#xff0c;不管它们是否运行在同一个Node&#xff08;宿主机&#xff09;中&#xff0c;都…

【Java SE 题库】LeetCode 热题 100--->两数之和

&#x1f525;博客主页&#x1f525;&#xff1a;【 坊钰_CSDN博客 】 欢迎各位点赞&#x1f44d;评论✍收藏⭐ 目录 1. 题目 2. 解析 2.1 判断两个数相加是否等于目标值 2.2 相等后&#xff0c;如何返回两个下标 3. 代码 4. 小结 取于力扣-->LeetCode 热题 100 - 学…

nginx的配置

nginx 通过nginx来进行配置&#xff0c;功能如下 通过nginx的反向代理功能访问后端的网关资源通过nginx的静态服务器功能访问前端静态页面 nginx配置步骤&#xff1a; ①&#xff1a;解压下载下来的nginx的压缩包nginx-1.18.0.zip&#xff0c;安装完成并启动后&#xff0c;访…

面经之一:Synchronized与ReentrantLock区别

Synchronized与ReentrantLock是Java中用于实现线程同步的两种主要机制&#xff0c;它们各有特点和适用场景。以下是它们的主要区别&#xff1a; 实现方式&#xff1a; Synchronized&#xff1a;是Java语言内置的关键字&#xff0c;通过JVM层面的监视器&#xff08;Monitor&…

基于vue3封装了一个coverflow轮播图(层叠轮播图)组件

最近公司有这个需求, 但是网上找了一圈 , 没有合适的能用在vue3里面的、且长这样的组件, 干脆自己动手写了一个; 效果如下, 可以适配多张图片 ,小于五张会是平铺展示; 大于五张按顺序轮播 , 每次切换有动画 <template><div class"Swiper"><div v-i…

COSCon'24 志愿者招募令:共创开源新生活!

亲爱的开源爱好者们&#xff0c; 第九届中国开源年会&#xff08;COSCon24&#xff09;即将在北京中关村国家自主创新示范区会议中心于2024年11月2日至3日隆重举行。今年的主题是“Open Source, Open Life&#xff5c;开源新生活”&#xff0c;旨在探索开源技术如何在各个领域推…

APP综合应用之业务场景脚本测试任务(5)--多重继承与总结

在脚本中&#xff0c;有三个子类继承自父类Test_login,那么怎么同时获得三个子类的继承呢&#xff1f; 1、多重继承 下面用Test_flowdriver的子类继承自上面的三个子类。 新建一个工作流驱动的文件testtest_run_workflowV1.py 主要是创建驱动类时&#xff0c;要把三个子类都继…