Python前端系列(一)

一、Python 前端开发概述

  • Flask框架
    • 前端开发: HTML、CSS、JavaScript、JQuery、BootStrap
    • 数据库:MySQL
  • Web开发:Django 框架

1. 网站的本质

在这里插入图片描述

2. Flask 框架

(1). 前言

  • 这里介绍Flask框架并不是为了利用Flask框架进行网页开发,而是利用这个介绍 HTML、CSS、JavaScript、JQuery、BootStrap等相关内容,实际开发还是会使用Django框架

(2). 简单上手

  • 第一步环境安装
    进入Pycharm中,在终端命令行输入下面命令进行安装:
    pip install flask
    

在这里插入图片描述

  • 第二步:创建简单的项目这里起名 “MySite”,并写入代码,查看运行效果
    from flask import Flask     # 导入包
    
    app = Flask(__name__)       #__name__前面说过,判断是不是程序入口
    
    # http://127.0.0.1:9000/home
    @app.route('/home')          #设置网址标签
    def home():
        #....
    
        return "HOME"            #返回字符串,也可以返回HTML文件等
    
    if __name__ == '__main__':
        app.run(host='127.0.0.1', port=9000)    # 运行,设置为主机IP,端口号任意,最好5000以上
    

在这里插入图片描述

  • 第三步:运行查看结果:
    运行后在终端命令行有 " http://127.0.0.1:9000/" 的网址:
    在这里插入图片描述
    点击进入后,在原来网址后加上 /home 即可访问页面

在这里插入图片描述

(3). 函数返回的几种情况

  • 情况一:根据Flask框架的规则搭建基本的开发架子 ——返回一个字符串

    from flask import Flask     # 导入包
    
    app = Flask(__name__)       #__name__前面说过,判断是不是程序入口
    
    # http://127.0.0.1:9000/home
    @app.route('/home')          #设置网址标签
    def home():
        #....
    
        return "HOME"            #返回字符串,也可以返回HTML文件等
    
    if __name__ == '__main__':
        app.run(host='127.0.0.1', port=9000)    # 运行,设置为主机IP,端口号任意,最好5000以上
    
  • 情况二:HTML标签包裹数据返回 ——》浏览器返回,查看

    from flask import Flask     # 导入包
    
    app = Flask(__name__)       #__name__前面说过,判断是不是程序入口
    
    # http://127.0.0.1:9000/home
    @app.route('/home')          #设置网址标签
    def home():
        #....
    
        return "<h1>中国电信</h1> <h6>中国联通</h6>"      # HTML标签包裹数据返回     
    
    if __name__ == '__main__':
        app.run(host='127.0.0.1', port=9000)    # 运行,设置为主机IP,端口号任意,最好5000以上
    

在这里插入图片描述

  • 情况三:HTML标签包裹数据+ CSS样式 ——》浏览器返回,查看

    • CSS : 层叠样式表
      <h1 style = "color:red;">中国电信</h1>
      <h6>中国联通</h6>
      
    from flask import Flask     # 导入包
    
    app = Flask(__name__)       #__name__前面说过,判断是不是程序入口
    
    # http://127.0.0.1:9000/home
    @app.route('/home')          #设置网址标签
    def home():
        #....
    
        return "<h1 style = "color:red;">中国电信</h1> <h6>中国联通</h6>"      # HTML标签包裹数据+CSS     
    
    if __name__ == '__main__':
        app.run(host='127.0.0.1', port=9000)    # 运行,设置为主机IP,端口号任意,最好5000以上
    

在这里插入图片描述

  • 情况四:HTML标签包裹数据+ CSS样式 + JavaScript——》浏览器返回,查看
    JavaScript,简称 js,可以让我们的标签动态和交互
    from flask import Flask     # 导入包
    
    app = Flask(__name__)       #__name__前面说过,判断是不是程序入口
    
    # http://127.0.0.1:9000/home
    @app.route('/home')          #设置网址标签
    def home():
        #....
    
        return "<h1 style = "color:red;" onclick = 'alert(111)'>中国电信</h1> <h6>中国联通</h6>"      # # HTML标签包裹数据+CSS +JS       
    
    if __name__ == '__main__':
        app.run(host='127.0.0.1', port=9000)    # 运行,设置为主机IP,端口号任意,最好5000以上
    

在这里插入图片描述

(4). 直接返回HTML包裹数据+CSS+JS 的文件

有前面可以知道,我们可以给浏览器返回html + CSS +JS 格式的字符串,但是这种情况过于麻烦,因此, 可以直接返回一个html + CSS +JS的文件

在这里插入图片描述

在这里插入图片描述

from flask import Flask,render_template

app = Flask(__name__)

# http://127.0.0.1:9000/home
@app.route('/home')
def home():
    #....

    return render_template("home.html")

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=9000)

在这里插入图片描述


二、HTML— 数据的展示

1. HTML----head 部分

  • 在html中,文件的head部分通过一对<head></head> 表示,内部可以设置 标题,图标,关键字(例如:百度搜索时的输入)、描述语句(description,就是百度搜索后显示词条的内容描述)
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    
  • 示例:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>信息系统</title>
        <link rel="shortcut icon" href="/static/icon_2.png">
        <meta name="keywords" content="CSDN博客,CSDN学院,CSDN论坛,CSDN直播">
        <meta name="description" content="CSDN是全球知名中文IT技术交流平台.">
    </head>
    <body>
    <h1 style = "color:red;" onclick = 'alert(111)'>中国电信</h1>
    <h6>中国联通</h6>
    </body>
    </html>
    

在这里插入图片描述

2. 标题

  • 1-6级标题
    <body>
        <h1>一级标题</h1>
        <h2>二级标题</h2>
        <h3>三级标题</h3>
        <h4>四级标题</h4>
        <h5>五级标题</h5>
        <h6>六级标题</h6>
    </body>
    

在这里插入图片描述

3. HTML---- div/span

在HTML中,<div><span> 是两个常用的通用容器元素,用于组织和样式化内容。它们的主要区别在于默认显示方式典型用途

  • <div>(块级容器)

    • 默认显示:块级元素 (独占一行,宽度默认100%)
    • 用途:用于布局结构,分组大块内容(如页眉、侧边栏、卡片等)。
    • 特点
      • 前后会自动换行。
      • 通常搭配CSS设置宽度、边距、背景等样式。
      • 可以嵌套其他块级或行内元素。
    <div class="header">
      <h1>标题</h1>
      <p>这是一个段落</p>
    </div>
    
  • <span>(行内容器)

    • 默认显示:行内元素(不换行,宽度由内容决定)。
    • 用途:包裹小段文本或行内元素,单独设置样式或脚本操作。
    • 特点
      • 不会破坏文本流,适合标记部分文字(如高亮、图标等)。
      • 不能直接设置宽度/高度(需通过display: inline-block等修改)。
    <p>这是一段<span class="highlight">高亮</span>文本。</p>
    

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>新闻咨询</title>
    <link rel="shortcut icon" href="/static/icon_1.png">
</head>
<body>
<div>
    <h1>日方称辽宁舰经过日南部岛屿前往西太平洋,外交部回应</h1>
    <div>
            <span style = "color:red;" >发布人</span>
            <span>北京日报客户端</span>
            <span style = "color:red;" >发布时间</span>
            <span>2025-05-28 15:32</span>
    </div>
    <div>
        <div>5月28日,外交部发言人毛宁主持例行记者会。</div>
        <div>日本防卫省表示,辽宁舰航母经过日本南部岛屿并正在驶向太平洋的西部,日方正在密切监视这一举动。中方航母为何如此靠近日本?这是否在向日美以及台湾地区发出信号?</div>
        <div>资料图“具体问题请你向中方的主管部门了解。”毛宁对此表示,“我可以告诉你的是,中国军舰在有关海域的活动完全符合国际法和国际惯例,希望日方客观理性看待。”</div>
    </div>

</div>


</body>
</html>

注意:上面的模块中可以实现标签之间的嵌套
在这里插入图片描述

4. 模板渲染 —> 信息替换

Flask 中,模板渲染 是指将动态数据与预定义的 HTML 模板结合,生成最终的 HTML 页面并返回给用户的过程。

  1. Flask 应用代码 (app.py)
    from flask import Flask, render_template
    
    app = Flask(__name__)
    
    # http://127.0.0.1:9000/index
    @app.route("/index")
    def home():
    	
    	# 1. 读取index.html文件里的内容
    	# 2. 渲染 == 替换
    	# 3. 将替换完的结果返回给用户浏览器
    
    
    
    
        # 示例数据:列表、字典、嵌套字典
        users = ["张三", "李四", "王五"]  # 简单列表
        
    	infos = {"name":"朱十六","age":26,"city":"安徽"}
    
        user_info = {  # 嵌套字典
            "张三": {"age": 25, "job": "工程师", "skills": ["Python", "SQL"]},
            "李四": {"age": 30, "job": "设计师", "skills": ["Photoshop", "UI/UX"]},
            "王五": {"age": 22, "job": "学生", "skills": ["Java", "C++"]},
        }
        
        posts = [  # 列表 + 字典混合
            {"title": "Flask入门指南", "tags": ["Python", "Web"], "published": True},
            {"title": "设计模式", "tags": ["编程", "OOP"], "published": False},
        ]
    
        return render_template(
            "index.html",
            users=users,
            infos = infos ,
            user_info=user_info,
            posts=posts,
            title="信息管理系统"
        )
    
    if __name__ == "__main__":
        app.run(host='127.0.0.1', port=9000)
    

  1. 模板文件 (templates/index.html)
    <!DOCTYPE html>
    <html>
    <head>
        <title>{{ title }}</title>
        <style>
            body { font-family: Arial, sans-serif; margin: 20px; }
            table { border-collapse: collapse; width: 50%; margin-bottom: 20px; }
            th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
            th { background-color: #f2f2f2; }
            .tag { background-color: #e0f7fa; padding: 2px 6px; border-radius: 3px; }
            .unpublished { color: #ff5722; font-style: italic; }
        </style>
    </head>
    <body>
        <h1>{{ title }}</h1>
    
    	<!-- 1. 渲染简单列表方式一: -->
        <h2>用户列表</h2>
        <ul>
            <li>{{ users[0] }}</li>
            <li>{{ users[1] }}</li>
            <li>{{ users[2] }}</li>
        </ul>
    
        <!-- 1. 渲染简单列表方式二 -->
        <h2>用户列表</h2>
        <ul>
            {% for user in users %}
                <li>{{ user }}</li>
            {% endfor %}
        </ul>
    
    
    	<!-- 2. 渲染简单字典方式一: -->
        <h2>用户列表</h2>
        <ul>
            <li>{{ infos.name }}</li>
            <li>{{ infos["age"] }}</li>
            <li>{{ infos["city"] }}</li>
        </ul>
        
    	<h2>列表+字典嵌套</h2>
    	</ul>
          	<li>{{ posts[0].title }}</li>
            <li>{{ posts[0]["published"] }}</li>
            <li>{{ posts[0]["tags"][0] }}</li>
            <li>{{ posts[0]["tags"][1] }}</li>
            <li>{{ posts[1].title }}</li>
            <li>{{ posts[1]["published"] }}</li>
            <li>{{ posts[1]["tags"][0] }}</li>
            <li>{{ posts[1]["tags"][1] }}</li>
    	</ul>
    	 
        <!-- 2. 渲染字典的键值对方式二: -->
        <h2>用户详细信息</h2>
        <table>
            <tr>
                <th>姓名</th>
                <th>年龄</th>
                <th>职业</th>
                <th>技能</th>
            </tr>
            {% for name, info in user_info.items() %}
                <tr>
                    <td>{{ name }}</td>
                    <td>{{ info.age }}</td>
                    <td>{{ info.job }}</td>
                    <td>
                        {% for skill in info.skills %}  <!-- 嵌套列表遍历,skill中是列表存储的 -->
                            <span class="tag">{{ skill }}</span>
                        {% endfor %}
                    </td>
                </tr>
            {% endfor %}
        </table>
    
        <!-- 3. 条件判断 + 嵌套数据 -->
        <h2>文章列表</h2>
        {% for post in posts %}            <!-- 列表中存储的是字典 -->
            <div {% if not post.published %}class="unpublished"{% endif %}>
                <h3>{{ post.title }}</h3>
                <p>
                    标签:
                    {% for tag in post.tags %}    <!-- tags 中存储的也是列表 -->
                        <span class="tag">{{ tag }}</span>
                    {% endfor %}
                    {% if not post.published %}
                        <em>(未发布)</em>
                    {% endif %}
                </p>
            </div>
        {% endfor %}
    
        <!-- 4. 检查字典键是否存在 -->
        {% if "赵六" not in user_info %}
            <p style="color: #888;">注:赵六的信息未收录。</p>
        {% endif %}
    
        <!-- 5. 使用 loop.index 显示循环序号 -->
        <h2>带序号的用户列表</h2>
        <ol>
            {% for user in users %}
                <li>第{{ loop.index }}位:{{ user }}</li>
            {% endfor %}
        </ol>
    </body>
    </html>
    

注意: 渲染的时候一定要小心{% for post in posts %}{%之间不要有空格,{%之间同理,其他语句亦是如此

  1. 效果说明
    在这里插入图片描述

  2. 关键语法总结

功能Jinja2 语法示例场景
遍历列表{% for item in list %}渲染用户列表
遍历字典键值{% for key, value in dict.items() %}渲染用户详情表
嵌套循环多层 {% for %}渲染用户的技能标签
条件判断{% if condition %}检查文章是否发布
检查键是否存在{% if key in dict %}判断用户“赵六”是否存在
循环序号{{ loop.index }}显示“第1位:张三”

若是代码中没有传入对应渲染的值,那么HTML页面则什么都不会显示


5. a标签

在HTML中,<a> 标签(锚标签,Anchor Tag)用于创建超链接,允许用户跳转到其他页面、文件、电子邮件地址或同一页面的特定位置。它是网页中实现导航和交互的核心元素之一。

  • 基本语法
    <a href="目标地址" 属性>链接文本或内容</a>
    

  • 主要属性
    1. href(必需)

      • 定义链接的目标地址,可以是:
        • 绝对URL:<a href="https://www.example.com">示例</a>
        • 相对路径:<a href="/about.html">关于我们</a>
        • 同一页面的锚点:<a href="#section1">跳转到第一节</a>
        • 电子邮件:<a href="mailto:email@example.com">发送邮件</a>
        • 电话:<a href="tel:+123456789">拨打电话</a>
    2. target

      • 指定链接的打开方式:
        • _blank:在新标签页打开。
        • _self(默认):在当前标签页打开。
        • _parent / _top:在父框架或顶层窗口打开。
      <a href="https://example.com" target="_blank">在新标签打开</a>
      
    3. rel

      • 定义链接与当前页面的关系,常用于SEO和安全:
        • nofollow:告诉搜索引擎不要追踪此链接。
        • noopener noreferrer:防止新页面通过window.opener访问原页面(安全防护)。
      <a href="https://external.com" rel="nofollow noopener noreferrer">外部链接</a>
      
    4. download

      • 提示浏览器下载链接的资源(而非打开):
      <a href="/files/document.pdf" download>下载PDF</a>
      
    5. title

      • 鼠标悬停时显示的提示文本(辅助功能优化):
      <a href="#faq" title="常见问题解答">FAQ</a>
      

  • 常见用法示例
    1. 跳转到页面锚点
      需在目标位置设置id

      <a href="#section2">跳转到第二节</a>
      <!-- 页面中的目标位置 -->
      <h2 id="section2">第二节标题</h2>
      
    2. 发送邮件

      <a href="mailto:contact@example.com?subject=反馈&body=您好...">联系我们</a>
      
    3. 触发JavaScript

      <a href="javascript:void(0);" onclick="alert('点击!')">点我</a>
      

  • 注意事项
    • 如果省略href<a> 标签会变成普通的占位符(无链接功能)。
    • 为提升可访问性,建议链接文本要有明确描述(避免“点击这里”)。
    • 使用target="_blank"时,建议加上rel="noopener noreferrer"以防止安全风险。

完整示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <div>
        <a href="https://www.baidu.com/" >访问baidu(不创建新的页面标签)</a>
    </div>

    <div>
        <a href="https://www.baidu.com/" target="_blank" rel="noopener">访问baidu(打开新的页面)</a>
    </div>

    <div>
        <a href="/news" target="_blank" rel="noopener">跳转至本地页面(简写)</a>
        <a href="http://127.0.0.1:9000/news" target="_blank" rel="noopener">跳转至本地页面(完整)</a>
    </div>

    <div>
        <!--  跳转至 id="contact" 的目标出 -->
        <!--  title="联系信息" 表示鼠标悬停在这里产生的提示信息 -->
        <a href="#contact" title="联系信息">跳转到联系方式</a>
    </div>
    <div>
        <a href="mailto:942898202@qq.com">发送邮件</a>
    </div>
    <div>
        <a href="/files/document.pdf" download>下载PDF</a>
    </div>

    <div style="height: 5000px;"></div> <!-- 模拟长页面 -->
    <h2 id="contact">17366020308</h2>
    <p>邮箱:942898202@qq.com</p>

</body>
</html>

在这里插入图片描述

6. 插入图像

在HTML中,可以使用 <img> 标签 插入图片。这是一个 自闭合标签(不需要闭合标签),通过 src 属性指定图片路径,并可以设置宽度、高度、替代文本等属性。


  • 基本语法
    <img src="图片路径" alt="替代文本">
    

  • 主要属性
属性说明示例
src图片的URL或文件路径(必需)src="images/photo.jpg"
alt图片无法显示时的替代文本(SEO优化和可访问性)alt="一只猫"
width设置图片宽度(单位:像素或百分比)width="300"width="50%"
height设置图片高度(单位:像素或百分比)height="200"
title鼠标悬停时显示的提示文本title="点击查看大图"
loading控制图片懒加载(lazy 延迟加载)loading="lazy"
style内联CSS样式(如边框、边距等)style="border: 1px solid #ccc;"

示例代码

  1. 插入本地图片

    <img src="images/cat.jpg" alt="一只橘猫" width="300" height="200">
    
    • 图片路径可以是:
      • 相对路径(相对于当前HTML文件):src="images/cat.jpg"
      • 绝对路径(完整URL):src="https://example.com/images/cat.jpg"
  2. 插入网络图片

    <img src="https://example.com/pic.jpg" alt="网络图片" width="400">
    
  3. 带链接的图片
    <a> 标签包裹 <img>,使图片可点击跳转:

    <a href="https://example.com" target="_blank">
        <img src="logo.png" alt="公司Logo">
    </a>
    
  4. 响应式图片(自适应宽度)

    <img src="photo.jpg" alt="风景照" style="max-width: 100%; height: auto;">
    
    • max-width: 100% 确保图片不超过容器宽度
    • height: auto 保持比例不变
  5. 懒加载(Lazy Loading)
    延迟加载图片,提升页面性能:

    <img src="large-image.jpg" alt="大图" loading="lazy">
    

完整HTML示例

<!DOCTYPE html>
<html>
<head>
    <title>插入图片示例</title>
</head>
<body>
    <h1>我的相册</h1>
    
    <!-- 本地图片 -->
    <img src="images/sunset.jpg" alt="日落" width="500">
    
    <!-- 网络图片 -->
    <img src="https://picsum.photos/600/400" alt="随机图片" loading="lazy">
    
    <!-- 可点击的图片 -->
    <a href="https://example.com">
        <img src="logo.png" alt="网站Logo" title="点击访问">
    </a>
    
    <a href="https://portal.irayple.com/Home" title="跳转至主页" target="_blank">
    	<img src="static/1.jpeg" alt="风景照" style="max-width: 30%; height: auto;">
	</a>

</body>
</html>

通过 <img> 标签,你可以轻松地在网页中嵌入图片,并控制其显示方式!

7. 列表

在HTML中,列表主要有三种类型:无序列表有序列表定义列表。以下是它们的语法和示例:

  • 关于这里的便签记忆:
    • 无序列表:<ul> 标签表示(ulunordered list 的缩写),元素标签用 <li>,代表 list
    • 有序列表: <ol> 标签表示(olordered list 的缩写),元素标签用 <li>,代表 list
    • 定义列表:<dl>标签表示(dldefine list 的缩写)

  1. 无序列表<ul>
    用于展示没有特定顺序的项目,默认用实心圆点()标记。
    <ul>
      <li>项目一</li>
      <li>项目二</li>
      <li>项目三</li>
    </ul>
    

效果:
在这里插入图片描述
属性:

  • 通过CSS的 list-style-type 可以修改标记样式(如 circlesquarenone)。

  1. 有序列表<ol>
    用于需要顺序的项目,默认用数字标记。
    <ol>
      <li>第一步</li>
      <li>第二步</li>
      <li>第三步</li>
    </ol>
    

效果:
在这里插入图片描述

属性:

  • type:可指定标记类型(如 1AaIi)。
  • start:设置起始编号(如 start="3" 从3开始)。
  • reversed:倒序排列(HTML5新增)。

示例:

<ol type="A" start="2">
  <li>项目B</li>
  <li>项目C</li>
</ol>

在这里插入图片描述


  1. 定义列表<dl>
    用于术语及其定义的组合,如字典。
    <dl>
      <dt>HTML</dt>
      <dd>超文本标记语言,用于网页结构。</dd>
      <dt>CSS</dt>
      <dd>层叠样式表,用于网页样式设计。</dd>
    </dl>
    

效果:
在这里插入图片描述


  1. 嵌套列表
    列表可以多层嵌套,例如:
    <ul>
      <li>水果
        <ul>
          <li>苹果</li>
          <li>香蕉</li>
        </ul>
      </li>
      <li>蔬菜
        <ol>
          <li>番茄</li>
          <li>豌豆</li>
        </ol>
      </li>
    </ul>
    

效果:
在这里插入图片描述


8. 表格

在 HTML 中,表格使用 <table> 标签定义,由行(<tr>table row)、表头(<th>table head)和单元格(<td>Table Data Cell)组成。以下是详细语法和示例:


  1. 基本表格结构
    <table>
      <tr>
        <th>表头1</th>
        <th>表头2</th>
      </tr>
      <tr>
        <td>数据1</td>
        <td>数据2</td>
      </tr>
    </table>
    

效果:
在这里插入图片描述


  1. 表格关键标签
标签说明
<table>定义整个表格
<tr>定义一行(table row)
<th>定义表头单元格(加粗居中)
<td>定义普通单元格(table data)
<caption>表格标题(显示在表格上方)

  1. 合并单元格
  • 跨列合并(colspan
    合并同一行中的多个单元格:

    <td colspan="2">合并两列</td>
    
  • 跨行合并(rowspan
    合并同一列中的多个单元格:

    <td rowspan="2">合并两行</td>
    

示例:

<table border="1">
  <tr>
    <th>姓名</th>
    <th colspan="2">联系方式</th>
  </tr>
  <tr>
    <td></td>
    <td>电话</td>
    <td>邮箱</td>
  </tr>
  <tr>
    <td>张三</td>
    <td>3698</td>
    <td>c@example.com</td>
  </tr>
  <tr>
    <td rowspan="2">李四</td>
    <td>123</td>
    <td>a@example.com</td>
  </tr>
  <tr>
    <td>456</td>
    <td>b@example.com</td>
  </tr>
</table>

效果:
在这里插入图片描述


  1. 表格分组(语义化结构)
标签说明
<thead>表头区域(可选)
<tbody>表格主体(必须)
<tfoot>表尾区域(可选)

示例:

<table border="1">
  <thead>
    <tr><th>月份</th><th>收入</th></tr>
  </thead>
  <tbody>
    <tr><td>1月</td><td>1000</td></tr>
    <tr><td>2月</td><td>1500</td></tr>
  </tbody>
  <tfoot>
    <tr><td>总计</td><td>2500</td></tr>
  </tfoot>
</table>

在这里插入图片描述


  1. 常用属性(已废弃,建议用CSS替代)
属性说明替代CSS
border边框粗细border: 1px solid;
cellspacing单元格间距border-spacing: 5px;
cellpadding单元格内边距padding: 10px;
width表格宽度width: 100%;

示例:

<table style="border: 1px solid; width: 100%;">
  <tr><td>用CSS控制样式</td></tr>
</table>

  1. 响应式表格
    为小屏幕设备添加横向滚动:
<div style="overflow-x: auto;">
  <table>
    <!-- 宽表格内容 -->
  </table>
</div>

示例程序1:

<table border="1">
  
  
  <thead>
    <tr>
      <th>ID</th>
      <th>图片</th>
      <th>标题</th>
      <th>价格</th>
      <th>链接</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td><img src="static/icon_1.jpg" style="width:80px"></td>
      <td>选择正确</td>
      <td>1999</td>
      <td><a href="https://portal.irayple.com/Home" target="_blank">跳转</a></td>
    </tr>
    <tr>
      <td>2</td>
      <td><img src="static/1.jpeg" style="width:80px"></td>
      <td>选择正确</td>
      <td>4999</td>
      <td><a href="https://portal.irayple.com/Home" target="_blank">跳转</a></td>
    </tr>
  </tbody>
  <tfoot>
      <td>小节</td>
      <td><img src="static/1.jpeg" style="width:80px"></td>
      <td>choice</td>
      <td>618活动</td>
      <td><a href="https://portal.irayple.com/Home" target="_blank">跳转</a></td>
  </tfoot>


</table>

在这里插入图片描述

示例程序2:结合模板渲染

Python代码:

# http://127.0.0.1:9000/goods
@app.route("/goods")
def goods():
    data_list=[
        {"id":1,"img_url":"static/mobile/15sp.png","title":"小米15spro","price":5499,
         "url":"https://www.mi.com/shop/buy/detail?product_id=21305/"},
        {"id": 2, "img_url": "static/mobile/civ5pro.png", "title": "小米civ5pro", "price": 2799,
         "url": "https://www.mi.com/shop/buy/detail?product_id=21298/"},
        {"id": 2, "img_url": "static/mobile/15u.jpg", "title": "小米15Ultra", "price": 6499,
         "url": "https://www.mi.com/shop/buy/detail?product_id=20982/"},
    ]

    return render_template(
        "goods.html",
        data_list = data_list
    )

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=9000)

在这里插入图片描述

<table border="1">
  <thead>
    <tr>
      <th>ID</th>
      <th>图片</th>
      <th>标题</th>
      <th>价格</th>
      <th>链接</th>
    </tr>
  </thead>
  
  <tbody>
    {% for item in data_list %}
    <tr>
      <td>{{item.id}}</td>
      <td><img src="{{item.img_url}}" style="width:80px"></td>
      <td>{{item.title}}</td>
      <td>{{item.price}}</td>
      <td><a href="{{item.url}}" target="_blank">点击跳转</a></td>
    </tr>
    {% endfor %}
  </tbody>
</table>

在这里插入图片描述


三、HTML— 用户输入

1. input 系列

HTML的<input>元素用于创建交互式控件,以便用户输入数据。以下是<input>元素的基本语法和常见属性:

基本语法

<input type="input_type" name="field_name" id="field_id" value="default_value">

主要属性

  1. type - 指定输入类型(必需):

    • text - 单行文本输入框(默认值)
    • password - 密码输入框(内容显示为圆点)
    • email - 电子邮件输入框
    • number - 数字输入框
    • date - 日期选择器
    • checkbox - 复选框
    • radio - 单选按钮
    • file - 文件上传
    • submit - 提交按钮
    • reset - 重置按钮
    • button - 普通按钮
    • hidden - 隐藏字段
    • 等等(共有20多种类型)
  2. name - 字段名称(表单提交时使用)

    • 表单提交时的参数名

      • 当表单提交时,浏览器会以 name=value 的形式将数据发送到服务器
        • 例如:<input type="text" name="username" value="John"> 提交后会生成 username=John
    • 表单分组

      • 对于单选按钮(radio),相同 name 的按钮属于同一组,只能选择其中一个,最后也是以 name=value 的形式将数据发送到服务器,但是这个 name=value中的value就是选项标签中的value属性的值。(如:male或者female
        <input type="radio" name="gender" value="male"><input type="radio" name="gender" value="female">
  3. id - 唯一标识符(用于CSS和JavaScript)

  4. value - 默认值

  5. placeholder - 提示文本(当输入框为空时显示)

  6. required - 必填字段(布尔属性):在 HTML 表单中,required 属性用于指定某个表单字段(如 <input><select><textarea>)必须在提交表单之前填写或选择。它是一个布尔属性,添加后表示该字段是必填项。

    示例

    • 文本输入框必填

      <input type="text" name="username" required>
      
      • 如果用户未填写,提交时会提示“请填写此字段”。
    • 单选按钮必选

      <input type="radio" name="gender" value="male" required><input type="radio" name="gender" value="female">
      • 必须选择其中一个选项,否则无法提交。
    • 下拉选择框必选

      <select name="country" required>
        <option value="">请选择国家</option>
        <option value="cn">中国</option>
        <option value="us">美国</option>
      </select>
      
      • 必须选择一个非空值(value="" 的选项会被视为未选择)。
    • 复选框必选(至少选一个)

      <input type="checkbox" name="hobby" value="sports" required> 运动
      <input type="checkbox" name="hobby" value="music"> 音乐
      
      • 如果 required 放在单个复选框上,表示必须勾选它:
        <input type="checkbox" name="agree" required> 我同意协议
        
  7. disabled - 禁用输入字段(布尔属性)

  8. readonly - 只读(布尔属性)

  9. maxlength - 最大字符数

  10. min/max - 数值/日期的最小/最大值(适用于number/date类型)

  11. step - 数值的增量(适用于number类型)

  12. checked - 默认选中(适用于checkbox和radio)

  13. multiple - 允许多个值(适用于file和email类型)

示例代码

<!-- 文本输入框 -->
<input type="text" name="username" id="username" placeholder="请输入用户名">

<!-- 密码输入框 -->
<input type="password" name="password" id="password">

<!-- 单选按钮 -->
<input type="radio" name="gender" id="male" value="male" checked>
<input type="radio" name="gender" id="female" value="female">

<!-- 复选框 -->
<input type="checkbox" name="hobby" id="reading" value="reading">
<input type="checkbox" name="hobby" id="sports" value="sports">

<!-- 数字输入 -->
<input type="number" name="age" id="age" min="18" max="99">

<!-- 日期选择 -->
<input type="date" name="birthday" id="birthday">

<!-- 文件上传 -->
<input type="file" name="avatar" id="avatar" multiple>

<!-- 提交按钮 -->
<input type="submit" value="提交表单">

<input>元素通常嵌套在<form>元素中使用,但也可以单独使用。

完整示例

    <h2>用户登录</h2>
    <div>
        <!-- 文本输入 -->
        <span>用户名:</span>
        <input type = "text" name = "user_name" placeholder="用户名"/>
    </div>
    <div>
        <!-- 密码输入隐藏输入 -->
        <span>密   码:</span>
        <input type="password" name="password" id="password"/>
    </div>
    <div>
        <!-- 按钮——登录为vlue -->
       <input type="button" value="登录"/>
    </div>



    <div>
        <!-- 单选框 -->
        <span>性别:</span>
        <input type="radio" name="gender" id="male" value="male" checked></input>
        <input type="radio" name="gender" id="female" value="female"></input>
        <input type="radio" name="gender" id="unknown" value="unknown">未知</input>
    </div>

    <div>
        <!-- 复选框 -->
        <span>爱好:</span>
        <input type="checkbox" name="hobby" id="reading" value="reading">阅读</input>
        <input type="checkbox" name="hobby" id="sports" value="sports">运动</input>
        <input type="checkbox" name="hobby" id="music" value="music">音乐</input>
    </div>

    <div>
        <!-- 数字输入 -->
        <span>数字输入:</span>
        <input type="number" name="age" id="age" min="18" max="99">
    </div>

    <div>
        <!-- 日期选择 -->
        <span>日期选择:</span>
        <input type="date" name="birthday" id="birthday">
    </div>

    <div>
        <!-- 文件上传 -->
        <span>文件上传:</span>
        <input type="file" name="avatar" id="avatar" multiple>
    </div>

在这里插入图片描述


2. 下拉框

  1. 基本结构

    <select name="下拉框名称" id="唯一标识符">
      <option value="选项值">显示文本</option>
      <option value="option2">选项2</option>
    </select>
    
  2. <select> 核心属性

    属性说明示例
    name表单提交时的字段名name="country"
    id唯一标识符id="country-select"
    multiple允许多选<select multiple>
    size可见选项行数size="4"
    disabled禁用下拉框<select disabled>
    required必填字段<select required>
    form关联的表单IDform="form1"
    autofocus自动获取焦点<select autofocus>
  3. <option> 核心属性

    属性说明示例
    value表单提交的值value="us"
    selected默认选中<option selected>
    disabled禁用选项<option disabled>
    label替代显示文本label="United States"
  4. <optgroup> 分组属性

    属性说明示例
    label分组标题label="亚洲国家"
    disabled禁用整个分组<optgroup disabled>
  5. 完整示例

     <form id="user-form">
            <!-- 基本下拉框 -->
            <!--br表示换行标签-->
            <label for="gender">性别:</label><br>
            <select id="gender" name="gender" required>
                <option value="">-- 请选择 --</option>
                <option value="male"></option>
                <option value="female"></option>
            </select>
    
    		<!--br表示换行标签-->
            <br><br><br><br><br><br>
    
    
            <!-- 分组下拉框 -->
            <label for="country">国家/地区:</label><br>
            <select id="country" name="country" style="width: 200px;height:50px">
                <optgroup label="亚洲">
                    <option value="cn">中国</option>
                    <option value="jp">日本</option>
                </optgroup>
                <optgroup label="欧洲">
                    <option value="uk">英国</option>
                    <option value="fr">法国</option>
                </optgroup>
            </select>
            
            <!--br表示换行标签-->
            <br><br><br><br><br><br><br><br><br>
    
    
            <!-- 多选下拉框 -->
            <label for="hobbies">兴趣爱好:</label><br>
            <select id="hobbies" name="hobbies" multiple size="4" style="width: 200px">
                <option value="sports">运动</option>
                <option value="music">音乐</option>
                <option value="reading" selected>阅读</option>
                <option value="travel">旅行</option>
            </select><br>
            <input type="submit" value="提交">
        </form>
    
    

    在这里插入图片描述

  6. 使用注意

    • 默认选项:建议第一个选项作为提示项,设置value=""required属性
    • 多选操作
      • Windows: Ctrl + 点击
      • Mac: Command + 点击
      • 连续选择: Shift + 点击
    • 样式限制:原生下拉框样式有限,复杂需求建议使用JavaScript库
    • 表单关联:当<select>不在<form>内时,使用form="form-id"属性关联
  7. 注意事项

    • value属性是表单提交时发送到服务器的值
    • 未设置value属性时,提交的是选项的文本内容
    • multiplesize属性通常配合使用
    • 移动设备上下拉框的表现可能与桌面端不同

3. 多行文本

<!-- 基本结构 -->
<textarea 
  id="myTextarea"          <!-- 元素ID -->
  name="userContent"       <!-- 表单字段名 -->
  rows="5"                 <!-- 可见行数 -->
  cols="40"                <!-- 可见宽度(字符数) -->
  maxlength="500"          <!-- 最大字符数 -->
  placeholder="请输入..."   <!-- 提示文本 -->
  required                 <!-- 必填字段 -->
  readonly                 <!-- 只读(可选) -->
  disabled                 <!-- 禁用(可选) -->
  autofocus                <!-- 自动聚焦(可选) -->
  wrap="hard"              <!-- 换行方式(soft/hard/off) -->
  style="width:300px; height:150px; resize:none;"> <!-- CSS样式 -->
默认文本内容
</textarea>

完整示例:

<!-- 实际应用示例 -->
<form>
  <label for="comment">评论:</label><br>
  <textarea id="comment" name="comment" rows="4"
            placeholder="请留下您的评论..." required
            maxlength="500"></textarea><br>
  <button type="submit">提交</button>
</form>

<br><br><br><br>
<form>
  <label for="comment">批注</label><br>
  <textarea id="remark" name="remark" style="width:400px;height:100px"
            placeholder="请留下您的批注..." required
            maxlength="500"></textarea><br>
  <button type="submit">提交</button>
</form>

在这里插入图片描述

关键点说明:

  1. 内容写在开始和结束标签之间,不是通过value属性
  2. 现代开发推荐用CSS的width/height替代rows/cols
  3. resize:none可禁止用户调整大小
  4. 通过maxlength限制输入长度
  5. required属性确保表单提交前必须填写

4. label标签

<label>是HTML中用于关联表单控件(如<input><select><textarea>等)的重要标签,在CSS中可以通过多种方式对其进行样式设置。以下是关于<label>标签的详细说明:

基本功能

  1. 关联表单控件

    • 通过for属性与表单控件的id关联
    <label for="username">用户名:</label>
    <input type="text" id="username">
    
  2. 提升可用性

    • 点击<label>会自动聚焦关联的表单控件
    • 对屏幕阅读器等辅助技术更友好

5. Form 标签

Form标签是前面标签的上级 + submit就能提交数据

<form action="要提交的地址" method="get/post">
    <input type="text" />
    <input type="password" />
    <input type="submit" value="提交" />
</form>
<form>
    <input type="text" />
    <input type="password" />
    <input type="submit" value="提交" />
</form>

。。。。

四、get和post请求

案例1:用户登录—get请求

python代码

from flask import Flask,render_template,request
app = Flask(__name__)

# http://127.0.0.1:9000/login
@app.route('/login')
def login():
    #....

    return render_template("login.html")

# 登录信息的表单提交之后跳转的网址以及内部函数
# http://127.0.0.1:9000/goin
@app.route('/goin')
def goin():
    #....
    print(request.args)
    # 获取浏览器发送过来的数据参数,通过字典的方式获取
    username = request.args.get("username")
    password = request.args.get("password")
    print("uesrname:{} — password:{}".format(username,password))
    return "ok"



if __name__ == '__main__':
    app.run(host='127.0.0.1', port=9000)
	<!--表单提交后跳转的网址http://127.0.0.1:9000/goin -->
    <form action="http://127.0.0.1:9000/goin" method="get">
        <h2>用户登录</h2>
            <div>
                <!-- 文本输入 -->
                <span>用户名:</span>
                <input type = "text" name = "username" placeholder="用户名"/>
            </div>
            <div>
                <!-- 密码输入隐藏输入 -->
                <span>密   码:</span>
                <input type="password" name="password" id="password"/>
            </div>
            <div>
                <!-- 按钮——登录为vlue -->
               <input type="submit" value="登录"/>
            </div>
    </form>

在这里插入图片描述
在这里插入图片描述
默认是get请求,所以url中显示了输入的用户名和密码
在这里插入图片描述
在这里插入图片描述


案例2:用户登录—post请求

from flask import Flask,render_template,request
app = Flask(__name__)

# http://127.0.0.1:9000/login
@app.route('/login')
def login():
    #....

    return render_template("login.html")



# 登录信息的表单提交之后跳转的网址以及内部函数
# 这里设置post请求
# http://127.0.0.1:9000/goin
@app.route('/goin',methods=["post"])
def goin():
    #....
    print(request.args)
    # 获取浏览器发送过来的数据参数,通过字典的方式获取
    username = request.form.get("username")
    password = request.form.get("password")
    print("uesrname:{} — password:{}".format(username,password))
    return "ok"


if __name__ == '__main__':
    app.run(host='127.0.0.1', port=9000)
	<!--表单提交后跳转的网址http://127.0.0.1:9000/goin -->
	<!--这里设置post请求 -->
    <form action="http://127.0.0.1:9000/goin" method="post">
        <h2>用户登录</h2>
            <div>
                <!-- 文本输入 -->
                <span>用户名:</span>
                <input type = "text" name = "username" placeholder="用户名"/>
            </div>
            <div>
                <!-- 密码输入隐藏输入 -->
                <span>密   码:</span>
                <input type="password" name="password" id="password"/>
            </div>
            <div>
                <!-- 按钮——登录为vlue -->
               <input type="submit" value="登录"/>
            </div>
    </form>

在这里插入图片描述
由于是post请求,点击登录之后的url中就不显示刚刚填写的登录信息
在这里插入图片描述
在这里插入图片描述


post请求和get请求的区别

当然!我们用更直白的语言和比喻来解释 GETPOST 的区别,结合生活中的例子,保证你一听就懂。


(1). 核心区别一句话总结

  • GET:像查字典——你告诉服务器“我要什么”,服务器返回数据(只读操作)。
  • POST:像填表格——你提交数据给服务器,让它去处理(写入操作)。

(2). 具体对比(用快递举例)

对比项GET(查快递)POST(寄快递)
用途从服务器“拿”数据(比如查订单、搜商品)向服务器“发”数据(比如登录、下单)
数据位置数据挂在URL上(像快递单号暴露在快递盒外面)数据藏在包裹里(像快递内容在盒子内部)
安全性不安全(URL能被看到、被缓存)相对安全(数据不直接暴露,但也要加密)
数据量限制大(URL长度有限,比如最多2048字符)无限制(能发大文件、长文本)
浏览器行为能收藏、能刷新、能分享链接不能直接收藏或刷新(可能重复提交)

(3). 举个实际例子

场景:用户登录
  • 如果用GET(错误示范❌):

    • URL长这样:https://example.com/login?username=admin&password=123456
    • 问题:密码直接暴露在地址栏!别人看浏览器历史就能盗号。
  • 如果用POST(正确做法✅):

    • URL不变:https://example.com/login
    • 密码藏在请求体里,肉眼不可见,相对安全。

(4). Flask代码对比

from flask import Flask, request

app = Flask(__name__)

# GET请求:通过URL传参(比如搜索)
@app.route('/search', methods=['GET'])
def search():
    keyword = request.args.get('q')  # 从URL获取参数,如 /search?q=apple
    return f"你搜索了: {keyword}"

# POST请求:通过表单提交数据(比如登录)
@app.route('/login', methods=['POST'])
def login():
    username = request.form.get('username')  # 从表单获取数据
    password = request.form.get('password')
    return f"用户名: {username}, 密码已隐藏"

(5). 什么时候用哪个?

  • 用GET

    • 不修改服务器数据,只是“看看”(比如:加载网页、搜索、查看详情)。
    • 记住:GET请求可以被用户手动刷新、分享链接,不会出问题。
  • 用POST

    • 要修改服务器数据(比如:登录、注册、付款、删除内容)。
    • 记住:POST请求如果刷新浏览器,可能会弹窗提示“是否重新提交表单”。

说明:关于get/post请求

  1. GET请求
网址输入+回车访问        							——> GET
连接点过去                                            	——> GET
点击按钮+URL中 ?n1=123&n2=xxx        ——> GET
  1. POST
<form action="????" method = "post">
	...
</form>
提交后,再URL中没有看到参数   ——> post

如果它的请求都是在干同一件事,一般会选择用 一个url+多个请求的方式进行区分。
例如:登录/注册

  • 第一步:访问页面,看到输入页面 GET
    http://127.0.0.1:9000/login
    
    @app.route('/login',methods=['GET','POST'])
    def login():
        if request.method == "GET":
            return render_template("login.html")
    
  • 第二步:用户看到页面+用户输入+点击按钮提交 —— HTML
    <form action="http://127.0.0.1:9000/login" method="post">
        <h2>用户登录</h2>
            <div>
                <!-- 文本输入 -->
                <span>用户名:</span>
                <input type = "text" name = "username" placeholder="用户名"/>
            </div>
            <div>
                <!-- 密码输入隐藏输入 -->
                <span>密   码:</span>
                <input type="password" name="password" id="password"/>
            </div>
            <div>
                <!-- 按钮——登录为vlue -->
               <input type="submit" value="登录"/>
            </div>
    </form>
    
  • 第三步:接受POST提交的数据
    # http://127.0.0.1:9000/login
    @app.route('/login',methods=['GET','POST'])
    def login():
        if request.method == "GET":
            return render_template("login.html")
    
        username = request.form.get("username")
        password = request.form.get("password")
        print("uesrname:{} — password:{}".format(username,password))
        return "ok"
    

案例3:用户登录 get+post

from flask import Flask,render_template,request,redirect

app = Flask(__name__)



# http://127.0.0.1:9000/login
# 即接受post请求,也接受get请求
@app.route('/login',methods=['GET','POST'])
def login():
	
	# 若是get请求(输入网址+回车),那么返回登陆的html页面
    if request.method == "GET":
        return render_template("login.html")

    username = request.form.get("username")
    password = request.form.get("password")
    print("uesrname:{} — password:{}".format(username,password))

    if username == "root" and password == "123":
        #登录成功,跳转到另外一个页面
        return redirect("http://www.baidu.com")
    else:
        return render_template("login.html",message="登录失败")



if __name__ == '__main__':
    app.run(host='127.0.0.1', port=9000)
<form action="http://127.0.0.1:9000/login" method="post">
    <h2>用户登录</h2>
        <div>
            <!-- 文本输入 -->
            <span>用户名:</span>
            <input type = "text" name = "username" placeholder="用户名"/>
        </div>
        <div>
            <!-- 密码输入隐藏输入 -->
            <span>密   码:</span>
            <input type="password" name="password" id="password"/>
        </div>
        <div>
            <!-- 按钮——登录为vlue -->
           <input type="submit" value="登录"/>
            <span style="color: #ff5722">{{message}}</span>
        </div>
</form>

在这里插入图片描述

  • 若登录成功,直接跳转到新的页面

注意事项:

  • 若是密码输入成功则会进行跳转,失败则返回登录界面,但是会有提示信息"登录失败"

        if username == "root" and password == "123":
            #登录成功,跳转到另外一个页面
            return redirect("http://www.baidu.com")
        else:
            return render_template("login.html",message="登录失败")
    
    • 这里登录成功界面跳转,用到了 redirect 方法;
    • 登录失败还是返回login.html模板,但是此时有文字渲染。(当返回输入参数message的时候,模板进行渲染替换文字,但是若不传入message参数,就部进行替换,显示为空的
  • HTML中的关于网址,之前有几个标签会进行链接如:

    <a href= "???">百度</a>
    <img src = "???"/>
    <form action="????"></form>
    
    • 若是跳转到外部的其他网站,则要写出全名
      <a href= "https://www.baidu.com">百度</a>
      <img src = "https://www.baidu.com"/>
      <form action="https://www.baidu.com"></form>
      
    • 若是跳转到自己的内部网站,可以省略前面的 http://127.0.0.1:9000
      <a href= "http://127.0.0.1:9000/admin">百度</a>
      <img src = "http://127.0.0.1:9000/static/mobile/15sp.png"/>
      <form action="http://127.0.0.1:9000/login"></form>
      
      可以简写成
      <a href= "/admin">百度</a>
      <img src = "/static/mobile/15sp.png"/>
      <form action="/login"></form>
      

五、综合案例(登录+注册)

  • 输入登录网址,进入登录界面

  • 若有账号,则进行登录操作

    • 登录成功——显示已经注册的用户信息,并以列表的形式呈现
    • 登录失败——则依旧停留在登录界面,只不过界面显示登录失败
  • 若不存在账号,则进行注册操作,点击注册按钮,跳转至注册界面
    在这里插入图片描述

  • Python代码

    from flask import Flask,render_template,request,redirect
    
    app = Flask(__name__)
    
    # 注册函数
    # 登录,设置请求时post+get
    @app.route('/register',methods=['GET','POST'])
    def register():
    
        if request.method == 'GET':
            return render_template("register.html")
    
        print(request.form)
        username = request.form['username']
        password = request.form['password']
        gender = request.form['gender']
        hobby = request.form.getlist('hobby')
        city = request.form.get('city')
        more = request.form.get('more')
        print( username, password, gender, hobby, city,more)
    
    	#将用户信息写入txt文件
        with open("db.txt",mode="a",encoding="utf-8") as f:
            f.write(f"{username},{password},{gender},{'_'.join(hobby)},{city},{more}\n")
    
        #注册成功返回至登录界面
        return redirect("/login")
        # return render_template("register.html",message = "注册成功")
    
    
    
    # 登录成功之后,显示的界面(以表格的形式显示用户信息)
    # 这里设置为get请求,因为这里实际上是点击按钮,或者网址输入+回车过去,这个就是get请求
    @app.route('/usr/list',methods=['GET'])
    def usr_list():
    
    	#通过字典,创建映射关系,因为按钮、下拉框的值直观呈现的效果不好,这里进行二次处理
        gender_map = {
            "male":"男",
            "female":"女",
        }
        city_map = {
            "bj":"北京",
            "sh":"上海",
            "nj":"南京",
            "hz":"杭州",
        }
        hobby_map = {
            "20":"篮球",
            "30":"足球",
            "40":"乒乓球",
        }
        data_list = []
        # 打开文件,逐行读取内容
        with open("db.txt",mode="r",encoding="utf-8") as f:
            for line in f:
    	
    			# 去除字符串 line 首尾的空白字符
                line = line.strip()
                if not line:
                    continue
    			
    			# 一行的信息是以","区分的,所以通过,将信息分割开,并赋值给对应的变量
                user,pwd,gender,hobby,city,more = line.split(',')
                
                # gender、city变量获取的值是缩写,这里通过前面字典的映射关系变成中文
                gender_text= gender_map[gender]
                city_text= city_map[city]
                
                # hobby是一些以"_"分割开的字符串,这里分割开,并且以列表的形式赋值给hobby_list 
                hobby_list = hobby.split('_')
                hobby_text_list = []
                # hobby_list 里的值过前面字典的映射关系变成中文,并且添加到新的列表hobby_text_list 中
                for item in hobby_list:
                    hobby_text_list.append(hobby_map[item])
                hobby_string = "、".join(hobby_text_list)
                
                data_list.append({
                    "user":user,
                    "pwd":pwd,
                    "gender":gender_text,
                    "hobby":hobby_string,
                    "city":city_text,
                    "more":more,
                })
    
                print(user,pwd,gender_text,hobby_string,city_text,more)
    
    	# 返回HTML模板,并且进行渲染
        return render_template("user_list.html",data_list=data_list)
    
    
    # 登录,设置请求时post+get
    @app.route("/login",methods=['GET','POST'])
    def login():
        if request.method == 'GET':
            return render_template("login.html")
    
        username = request.form['username']
        password = request.form['password']
    
        is_success = False
        with open("db.txt",mode="r",encoding="utf-8") as f:
            for line in f:
                line = line.strip()
                if not line:
                    continue
                db_user,db_pwd,*v3 = line.split(',')
                if db_user == username and db_pwd == password:
                    is_success = True
                    break
    
        if is_success:
            #登录成功,返回用户列表
            return redirect("/usr/list")
        else:
            #登录失败
            return render_template("login.html",message = "用户名或密码错误")
    
    if __name__ == '__main__':
        app.run(host='127.0.0.1', port=5000)
    
    
  • 登录的HTML界面

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>用户登录</title>
    </head>
    <body>
        <h2>用户登录</h2>
        <form action="/login" method="post">
            <input type="text" name = "username" placeholder="用户名" required>
            <input type="password" name="password" placeholder="密码" required>
            <input type="submit" value="登录">
            <span style="color: greenyellow">{{ message }}</span>
            <br>
            <a href="/register">注册</a>
        </form>
    
    
    </body>
    </html>
    
  • 登陆成功后,跳转的用户信息表格显示

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>用户信息</title>
    </head>
    <body>
        <h1>用户信息列表</h1>
        <table border="1">
            <thead>
                <tr>
                    <th>用户名</th>
                    <th>密码</th>
                    <th>性别</th>
                    <th>爱好</th>
                    <th>城市</th>
                    <th>其他</th>
                </tr>
            </thead>
    
            <tbody>
                {% for row in data_list %}
                    <tr>
                        <td>{{ row.user }}</td>
                        <td>{{ row.pwd }}</td>
                        <td>{{ row.gender }}</td>
                        <td>{{ row.hobby }}</td>
                        <td>{{ row.city }}</td>
                        <td>{{ row.more }}</td>
                    </tr>
                {% endfor %}
            </tbody>
        </table>
    </body>
    </html>
    
  • 用户注册界面

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>用户注册</title>
    </head>
    <body>
    <h2>用户注册</h2>
    
    <form action="/register" method="post">
        <div>
            <!-- label 标签 点击后,可以选中对应的 id 所在的 input ,属性for后面跟的是input中的id内容 -->
            <label for="username">用户名</label>
            <input id="username" type="text" placeholder="请输入用户名:" name="username" required>
        </div>
    
        <div>
            <!-- label 标签 点击后,可以选中对应的 id 所在的 input ,属性for后面跟的是input中的id内容 -->
            <label for="password">密码</label>
            <input id="password"  type="password" placeholder="请输入密码" name="password" required>
        </div>
    
        <div>
            <label>性别</label>
            <!--对于这种选择框,提交后台后,是将value的值传递给后台的 -->
            <input  type="radio" name="gender" value="male"><input  type="radio" name="gender" value="female"></div>
    
        <div>
            <label>爱好</label>
            <!--对于这种选择框,提交后台后,是将value的值传递给后台的 -->
            <input  type="checkbox" name="hobby" value="20"> 篮球
            <input  type="checkbox" name="hobby" value="30"> 足球
            <input  type="checkbox" name="hobby" value="40"> 乒乓球
        </div>
    
        <div>
            <label>城市</label>
            <select name = "city">
                <option value="bj">北京</option>
                <option value="sh">上海</option>
                <option value="nj">南京</option>
                <option value="hz">杭州</option>
            </select>
        </div>
    
        <div>
            <label>备注信息</label>
            <textarea  name = "more" style="width: 500px;height: 100px"></textarea>
        </div>
    
        <input type="submit" value="注册">
        <span style="color: red">{{ message }}</span>
    </form>
    
    </body>
    </html>
    

在这里插入图片描述
注册完之后就会返回登录界面重新输入用户民和密码
在这里插入图片描述
登录成功显示用户信息表格
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值