Python Web框架Django

Django是一个开放源代码的Web应用框架,由Python写成。采用了MVT的框架模式,即模型M,视图V和模版T。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是CMS(内容管理系统)软件。

python 3 DjanGo 教程
更多:Django

第 11 章 Web 框架:Django

Python 是唯一一种 Web 框架比语言关键字多的语言。

—Harald Armin Massa, 2005 年 12 月

本章内容:

  • 简介;
  • Web 框架;
  • Django 简介;
  • 项目和应用;
  • “Hello World”应用(一个博客);
  • 创建模型来添加数据库服务;
  • Python 应用 shell;
  • Django 管理应用;
  • 创建博客的用户界面;
  • 改进输出;
  • 处理用户输入;
  • 表单和模型表单;
  • 视图进阶;
  • *改善外观;
  • *单元测试;
  • 中级Django 应用:TweetApprover;
  • 资源。
11.1 简介

本章不再介绍 Python 标准库,而介绍一个著名的 Web 框架:Django。首先简要介绍什么是 Web 框架,接着介绍使用 Django 开发应用。从基础开始介绍 Django,并开发一个“Hello World”应用。接着逐步深入,介绍开发实际应用时所要了解的内容。这个路线图也组成了本章的架构: 首先夯实基础;然后介绍中级应用,这个应用会涉及Twitter、电子邮件和 OAuth(OAuth 是一个开放的授权协议,用于通过应用编程接口[API]访问数据)。

本章旨在介绍一款工具,Python 开发者每天都会用这款工具解决实际问题。通过本章, 读者会学到一些技能和足够的知识,来通过 Django 构建更复杂的工具。读者可以带着这些技能去学习任何其他Python Web 框架。首先,了解什么是 Web 框架。

11.2 Web 框架

这里希望读者通过第 10 章的学习,对 Web 开发有了足够的了解。Web 开发除了像上一章那样全部从头写起,还可以在其他人已有的基础上进行开发,简化开发流程。这些 Web 开发环境统称为 Web 框架,其目标是帮助开发者简化工作,如提供一些功能来完成一些通用任务,或提供一些资源来用于降低创建、更新、执行或扩展应用的工作量。

前面还提到,由于 CGI 在可扩展性方面有缺陷,因此不建议使用它。所以 Python 社区的人们寻求一种更强大的 Web 服务器解决方案,如 Apache、ligHTTPD(发音为“lighty”),或 nginx。有些服务器,如 Pylons 和 CherryPy,拥有自己的框架生态系统。但服务方面的内容只是创建 Web 应用的一个方面。还需要关注一些辅助工具,如 JavaScript 框架、对象关系映射器(ORM)或底层数据库适配器。还有与 Web 不相关但其他类型的开发需要的工具, 如单元测试和持续集成框架。Python Web 框架既可以是单个或多个子组件,也可以是一个完整的全栈系统。

术语“全栈”表示可以开发 Web 应用所有阶段和层次的代码。框架可以提供所有相关的服务,如 Web 服务器、数据库 ORM、模板和所有需要的中间件 hook。有些还提供了 JavaScript 库。Django 就是这当中一个广为人知的 Web 框架。许多人认为 Django 对于 Python,就相当于 Ruby on Rails 对 Ruby 一样。Django 包含了前面提到的所有服务,可作为全能解决方案(除了没有内置的 JavaScript 库,这样可以自由选择相应的库)。在第 12 章将看到 Google App Engine 也提供了这些组件,但更适合于由 Google 托管并且侧重于可扩展性和快速请求/响应的 Web 和非 Web 应用。

Django 是由一个开发团队作为单个突出创建的,但并不是所有框架都遵循这种哲学。以TurboGears 为例,这是一个非常优秀的全栈系统,由分散在全世界的开发者开发,其作为胶水代码,将栈中其他独立的组件组合起来,如ToscaWidgets(高级 Web 部件,它可利用多种JavaScript 框架,如 Ex1tJs、jQuery 等)、SQLAlchemy(ORM)、Pylons(Web 服务器),还有Genshi(模板化)。遵循这种架构样式的框架能提供很好的灵活性,用户可以选择不同的模板系统、JS 库、生成原始 SQL 语句的工具,以及不同的 Web 服务器。只须牺牲一点一致性和放弃单一工具的追求。但对框架的使用也许与之前的方式没什么区别。

Pyramid 是另外一个非常著名的 Web 框架,这是 repoze.bfg(或简称 BFG)和 Pylons 的继承者。Pyramid 的方式更加简单,它只提供一些基础功能,如URL 分派、模板化、安全和一些资源。如果需要其他功能,必须手动添加。这种极简的方式带来的好处就是 Pyramid 拥有完整的测试和文档,以及从Pylons 和BFG 社区继承的用户,让Pyramid 成为今日Python Web 框架中有力的竞争者。

如果读者刚接触到 Python,可能会了解 Rails 或 PHP,这两者原先只想将语言嵌入到HTML 中,后来扩展成一个庞大框架。Python 的好处就是不必局限于“一种语言,一种框架” 的形式。从 Python 中可以选择许多框架,就如同本章起始处的引用所说的那样。Web 服务器网关接口(WSGI)标准的建立加速了 Web 框架的发展。Python WSGI 由PEP 333 定义,参见:http://python.org/dev/peps/pep-0333

如果读者还不了解 WSGI,这里有必要简要说明一下。WSGI 不是实际的代码或 API,而定义了一系列接口,让 Web 框架的开发者无须为框架创建自定义 Web 服务器,也让应用程序开发者可以自行选择 Web 服务器。有了WSGI,应用开发者就可以方便地切换(或开发新的)WSGI 兼容的服务器,而无须担心需要改变应用代码。关于 WSGI 的更多内容,可阅读上一章。

有一点不知道是否应该在这里提及(特别是在书中),当热情的 Python 开发者不满足已有的框架时,他们就会创建一个新框架。Python 中 Web 框架的数目比关键字的数目还多。其他框架还包括 web2py、web.py、Tornado、Diesel 和 Zope。可以在 Python 官网的维基页面http://wiki.python.org/moin/WebFrameworks 来了解这些框架。

回到正文,现在在这些 Web 开发的相关知识的基础上来学习Django。

11.3 Django 简介

Django 自称是“能够很好地应对应用上线期限的 Web 框架”。其最初在 21 世纪初发布, 由 Lawrence Journal-Wor ld 报业的在线业务的 Web 开发者创建。2005 年正式发布,引入了以“新闻业的时间观开发应用”的方式。本章中我们会使用   Django  开发一个简单的博客应用, 下一章会用 Google App Engine 开发相同的应用,比较两者来看 Django 的开发速度(这里的博客比较简单,读者需要自行完善)。尽管会直接给出这个例子,但在介绍的过程中仍然会详细解释示例。如果读者想深入了解,可以阅读 Python Web Development with Django
(Addison-Wesley, 2009)第 2 章,该书由我和我尊敬的同事 Jeff Forcier (Fabric 主要开发者) 和Paul Bissex(dpaste 创建者)编写。

核心提示:对Python 3的支持
在撰写本书时,Django 2 已经并仅支持Python 3,因此本章的所有示例都以 Python 2.x 编写。不过本书的网站中含有所有的Python 3 版本的示例。

11.3.1 安装

在介绍 Django 开发之前,首先安装必需的组件,这包括依赖组件和 Django 本身。

预备条件

在安装 Django 之前,必须先安装 Python。由于读者已经读到本书第 10 章了,因此假设已经安装了 Python。大多数兼容POSIX 的系统(Mac  OS X、Linux、*BSD)都已经安装了Python。只有微软 Windows 需要自行下载并安装 Python。

Apache 是 Web 服务器中的王者,因此大多数部署都会使用这款服务器。Django 团队建议使用 mod_wdgi 这个Apache 模块,并提供了安装指南:http://docs.djangoproject.com/en/dev/ topics/install/#install-apache-and-mod-wsgi,同时也提供了完整的开发文档,参见  http://docs.djangoproject.com/en/dev/howto/deployment/modwsgi/。还有一份更好的文档,其中介绍了使用一个   Apache  实例来持有多个   Django  Web  站点(项目),参见   http://forum.webfaction.com/viewtopic.php?id=3646 。如果想了解  mod_python,只能在老的  Django  安装包或在mod_wsgi 成为标准之前的一些操作系统的发行版中寻找。官方已经不支持 mod_python(实际上,从Django 1.5 开始,就移除了 mod_python)。

在结束对Web服务器的讨论之前 ①,还需要提醒读者,在生产环境的服务器中并不是一定要使用Apache,还可以有其他选择,其中有些内存占用量更少,速度更快。也许其中一个就更适合你的应用。可以在http://code. djangoproject.com/wiki/ServerArrangements中查找符合要求的Web服务器。

Django 需要用到数据库。当前的标准版 Django 只可运行基于 SQL 的关系数据库管理系统(RDBMS)。用户主要使用 4 种数据库,分别是 PostgreSQL、MySQL、Oracle 和 SQLite。其中最容易设置的是 SQLite。另外,SQLite 是这 4 个当中唯一一个无须部署数据库服务器的,所以使用起来也是最简单的。当然,简单并不代表无能,SQLite  功能和另外三个一样强大。

① 除非到了开发阶段,否则无需 Web 服务器,因此可以在后面安装。Django 自带了开发服务器(刚刚已经看到),可以用于创建和测试应用。

为什么 SQLite 很容易设置?SQLite 数据库适配器是所有 Python 版本中自带的(从 2.5 开始)。注意,这里说的是适配器。有些 Python 发行版自带了 SQLite 本身,有些会使用系统上安装的 SQLite。而其他东西则需要手动下载和安装。

Django 支持众多关系数据库,SQLite 只是其中一种,所以如果不喜欢 SQLite,可以使用其 他数据库,特别是如果公司已经使用了某一款基于服务器的数据库。关于 Django 和数据库安装的更多内容,可以参考 http://docs.djangoproject.com/en/dev/topics/install/#data- base-installation.。

最近还有快速发展的非关系数据库(NoSQL)。大概这是因为这种类型的系统提供了额外的可扩展性,能面对不断增长的数据量。如果处理像 Facebook、Twitter 或类似服务那样的海量数据,关系数据库需要手动分区(切分)。如果需要使用 NoSQL 数据库,如 MongoDB 或 Google App Engine 的原生Datastore,可以尝试 Django-nonrel,这样用户就可以选择使用关系或非关系数据库。(需要说明一下,Goolge App Engine 也有一个关系数据库(兼容MySQL),即   Google Cloud SQL)。

可以从 http://www.allbuttonspressed.com/projects/ django-nonrel 下载Django-nonrel,以及其适配器,参见 https:// github.com/FlaPer87/django-mongodb-engine(Django 和MongoDB),或者 http://www.allbuttonspressed.com/projects/djangoappengine(Django 和Google App Engine 的 Datastore)。在本书编写时,由于 Django-nonrel 是Django 的分支,因此只能安装其中一个。主要原因是因为需要在开发环境和生产环境中使用相同的版本。如同在 http://www. allbuttonspressed.com/projects/django-nonrel 上说的那样,“(Django-nonrel)只对 Django 进行了一丁点修改(可能少于 100 行)”。Django-nonrel 可作为压缩文件下载,所以直接解压它, 在对应的目录中执行下面的命令。

$ sudo python setup.py install

如果下载Django 压缩包,其安装方法完全相同(如下所示),所以完全可以跳过下一节, 直接开始学习教程。

安装 Django

有多种方法可以安装 Django,下面对这些安装方法按难易程度排序,越靠前的越简单。

  • Python 包管理器
  • 操作系统包管理器
  • 官方发布的压缩包
  • 源码库

最简单的下载和安装方式是使用 Python 包管理工具,如 Setuptools 中的 easy_install

(http://packages.python.org/distribute/easy_install.html),或    pip(http://  pip.openplans.org),所有平台上都可使用这两个工具。对于 Windows 用户,使用 Setuptools 时需要将 easy_install.exe

文件放在Python 安装目录下的 Scripts 文件夹中。此时只须在 DOS 命令行窗口中使用一条命令就能安装 Django。

C:\WINDOWS\system32>easy_install django 
Searching for django
Reading http://pypi.python.org/simple/django/ 
Reading http://www.djangoproject.com/
Best match: Django 1.2.7
Downloading http://media.djangoproject.com/releases/1.2/Django- 1.2.7.tar.gz
Processing Django-1.2.7.tar.gz
. . .
Adding django 1.2.7 to easy-install.pth file
Installing django-admin.py script to c:\python27\Scripts

Installed c:\python27\lib\site-packages\django-1.2.7-py2.7.egg 
Processing dependencies for django
Finished processing dependencies for django

为了无须输入easy_install.exe的全路径,建议将C:\Python2x\Scipts添加到PATH环境变量 ① 中,其中 2.x根据Python的版本来决定。如果使用的是POSIX系统,easy_install会安装到众所周知的/usr/bin或/usr/local/bin中,所以无须再将其添加到PATH中,但可能需要使用sudo命令来将软件安装到一些典型的系统目录中,如/usr/local。命令如下所示。

$ sudo easy_install django

pip 的命令(不使用 virtuabanv)如下所示。

$ pip install django #sudo

只有在安装到需要超级用户权限的路径中时才会用到sudo;如果安装到用户目录中则不需要。这里还建议使用“容器”环境,如 virtualenv。使用 virtualenv 可以同时安装多个版本的Python、Django、数据库等。每个环境在独立的容器中运行,可以自由创建、管理、执行、销毁。关于 virtualenv 的更多内容可以参见 http://pypi.python.org/pypi/virtualenv。

另一种安装 Django 的方式是使用操作系统自带的包管理器(前提是系统有包管理器)。一般仅限于 POSIX 类的操作系统,如 Linux 和 Mac OS X。操作命令如下所示。

(Linux) $ sudo COMMAND install django 
(Mac OS X) $ sudo port install django

① Windows 系统用户可以修改PATH 环境变量。首先右击“我的电脑”,接着选择“属性”。在弹出的对话框中,选择“高级”标签,最后单击“环境变量”按钮。

对于 Linux 用户,COMMAND 是对应发行版的包管理器,如 apt-get、yum、aptitude 等。可以从 http://docs.djangoproject.com/en/dev/ misc/distributions 中找到不同发行版的安装指导。

除了上面提到的方法之外,还可以从 Django 网站直接下载并安装原始发布的压缩包。下载并解压后,就可以使用普通的命令进行安装。

$ sudo python setup.py install

在 http://docs.djangoproject.com/en/dev/topics/install/#installing-an-official-release 中可以找到更详细的安装指南。

专业开发者可能更喜欢从 Subversion 源码树中自行获取最新的源码。关于这种安装过程,可以参考 http://docs.djangoproject.com/en/dev/topics/install/#installing-the-development-version。

最后,http://docs.djangoproject.com/en/dev/topics/install/#install-the-django-code 包含了所有的安装指南。

下一步是设置服务器,确保所有组件安装完毕并能正常工作。但在此之前,先介绍一些基本的 Django 概念、项目(project)和应用(app)。

11.4 项目和应用

Django 中的项目和应用是什么?简单来说,可以认为项目是一系列文件,用来创建并运行一个完整的 Web 站点。在项目文件夹下,有一个或多个子文件夹,每个子文件夹有特定的功能,称为应用。应用并不一定要位于项目文件夹中。应用可以专注于项目某一方面的功能, 或可以作为通用组件,用于不同的项目。应用是一个具有特定功能的子模块,这些子模块组合起来就能完成 Web  站点的功能。如管理用户/读者反馈、更新实时信息、处理数据、从站点聚合数据等。

从Pinax 平台上能找到比较著名的可重用的 Django 应用。其中包括(但不限于)验证模块(OpenID 支持、密码管理等)、消息处理(E-mail 验证、通知、用户间联系、兴趣小组、主题讨论等),以及其他功能,如项目管理、博客、标签、导入联系人等。关于 Pinax 的更多内容可以访问其网站:http://pinaxproject.com。

项目和应用的概念简化了可插拔的使用方式,同时也强烈鼓励了敏捷设计和代码重用。现在知道了什么是项目和应用,下面开始创建一个项目。

11.4.1 在 Django 中创建项目

Django 带有一个名为 django-admin.py 的工具,它可以简化任务,如创建前面提到的项目目录。在 POSIX 平台上,它一般会安装到/usr/local/bin、/usr/bin 这样的目录中。如果使用的是 Windows 系统,它会安装到 Scripts 文件夹下,该文件夹位于 Python 安装目录下,如 C:\Python27\Scripts 。无论是 POSIX 还是 Windows 系统, 都应该确保django-admin.py 位于 PATH 环境变量中,这样它在可以在命令行中执行(否则需要使用全路径名调用解释器)。

对于 Windows 系统,需要手动将 C:\Python27 和 C:\Python27\Scripts(或自己设定的其他 Python 安装路径)添加到 PATH 变量中。首先打开控制面板,单击“系统”;或右击“我的电脑”,接着选择“属性”。在打开的窗口中选择“高级”标签,单击“环境变量”按钮。可以选择编辑单个用户的  PATH 项(上方的列表框),或者所有用户的  PATH(下方的列表框),接着在 Variable  Value 文本框中的末尾添加“;C:\Python27;C:\Python27\Scripts”,如图 11-1 所示。

在(任意一个平台上)设置好 PATH 以后,应该可以执行 Python 并获得一个交互式解释器,并查看 Django 的 django-admin.py 命令的使用方法。打开 UNIX shell 或 DOS 命令行,执行命令的名称。如果一切正常,就继续下面的内容。

下一步是到转到需要放置代码的文件夹或目录中。要在当前目录中创建项目,可以使用下面的命令(这里使用比较常见的项目名,如 mysite,读者也可以使用其他名称)。

$ django-admin.py startproject mysite

图 11-1 将Python 添加到 Windows PATH 变量中

注意,如果使用的是 Windows PC,首先必须打开 DOS 命令行窗口。在 DOS 中,命令行提示符类似C:\WINDOWS\system32,而不是 POSIX 系统中的美元符号($)或老式机器中的百分号(%),现在来看这些命令创建在该目录下创建了哪些内容。在  POSIX  系统上它应该类似下面这样。

$ cd mysite
$ ls -l
total 32
 
-rw-r–r–1 wesleyadmin0 Dec7 17:13 init .py
-rw-r–r–1 wesleyadmin546 Dec7 17:13 manage.py
-rw-r–r–1 wesleyadmin4778 Dec7 17:13 settings.py
-rw-r–r–1 wesleyadmin482 Dec7 17:13 urls.py

如果在 Windows 上开发,打开文件浏览器,找到这个文件夹,如图 11-2 所示,已经预先创建了名为 C:\py\django 的文件夹,用于放置项目。

图 11-2    Windows 系统上的 mysite 文件夹

在 Django 中,基本的项目含有 4 个文件,分别是 init .py、manage.py、setting.py、urls.py(后面会添加到应用中)。表 11-1 解释了这些文件的用途。

表 11-1 Django 项 目 文 件

文     件   名描述/用途
 __init__ .py告诉Python 这是一个软件包
urls.py全局 URL 配置(“URLconf”)
settings.py项目相关的配置
manage.py应用的命令行接口

读者会注意到,startproject 命令创建的每个文件都是纯Python 源码文件,没有.ini 文件、XML 数据,或其他配置语法。Django 尽力坚持“纯粹的 Python”这一信条。这样既可以在不向框架添加复杂东西的情况下拥有灵活性,同时也可以根据不同的情况从其他文件导入额外的配置,或动态计算数值,而不是硬编码。Django 中不适用其他内容,只有纯 Python。读者也可能注意到了 django-admin.py 也是 Python 脚本。其作为用户和项目之间的命令行接口。而 manage.py 同样可以用这种方式管理应用(这两条命令都有 Help 选项,可以从中了解到关于使用方面更多的信息)。

11.4.2 运行开发服务器

到目前为止,还没有创建一个应用。尽管如此,已经可以使用一些 Django 功能了。其中一个最方便的是 Django 内置的 Web 服务器。该服务器运行在本地,专门用于开发阶段。注意,这里强烈建议不要用这个服务器部署公开页面,因为其仅用于开发用途。

为什么会存在这个开发服务器?主要有以下几点原因。
1.使用开发服务器,可以直接运行与测试项目和应用,无需完整的生产环境。
2.当改动 Python 源码文件并重新载入模块时,开发服务器会自动检测。这样既能节省时间,也能方便地使用系统,无须每次编辑代码后手动重启。
3.开发服务器知道如何为 Django 管理应用程序寻找和显示静态媒体文件,所以无须立即了解管理方面的内容(后面会介绍相关内容,现在只是不要把它与django-admin.py 脚本弄混了)。

通过项目中的 manage.py 工具,可以使用下面这个简单的命令运行开发服务器。

(POSIX) $ python ./manage.py runserver
(PCs) C:\py\django\mysite> python manage.py runserver

如果使用POSIX 系统,并使用$ chmod 755 manage.py 来授予脚本执行许可,就无须显式调用 python,如$ ./manage.py runserver。在 DOS 命令行窗口中也同样可以做到,只需 Python 正确安装到 Windows 注册表中即可。

启动服务器后,应该能看到和下面例子相似的输出(Windows 使用不同的键组合来退出程序)。

Validating models...
0 errors found.

Django version 1.2, using settings 'mysite.settings' 
Development server is running at http://127.0.0.1:8000/ 
Quit the server with CONTROL-C.

在浏览器中打开链接(http://127.0.0.1:8000/或 http://localhost:8000/),就可以看到 Django的“It worked!”页面,如图 11-3 所示。

如果需要使用不同的端口运行服务器,可以在命令行中指定。例如,如果需要在端口 8080 运行它,可以使用这条命令:$ python ./manage.py runserver 8080。读者可以在下面这个链接中找到所有的 runserver 选项:http://docs.djangoproject.com/en/dev/ref/django-admin/#django-a dmin-runserver。

如果看到了图 11-3 中的“It worked!”页面,那么就表示一切正常。此时,如果查看命令行中的会话,可以看到开发服务器已经记录了GET 请求。

[11/Dec/2010 14:15:51] "GET / HTTP/1.1" 200 2051

图 11-3 Django 初始的“It worked!”页面

日志的每一行含有 4 个部分,从左到右,依次是时间戳、请求、HTTP 响应编码,以及字节数(读者可能有不同的字节数) 。“It worked!”页面很友好地告诉用户开发服务器正在工作,现在可以创建应用了。如果服务器没有正常工作,检查前面的步骤。此时甚至可以直接删除整个项目,从头开始,而不是在这里就开始调试。

当服务器成功运行时,就可以设置第一个Django 应用。

11.5 “Hello World”应用(一个博客)

既然拥有了一个项目,就可以在其中创建应用。为了创建一个博客应用,继续使用 manage.py:

$ ./manage.py startapp blog

如之前的项目一样,这里可以自行起名字,并不一定要使用 blog 这个名称。这一步与启动一个项目同样简单。现在在项目目录中有了一个 blog 目录。下面介绍了其中的内容,首先用POSIX 格式列出其中的内容,接着使用 Windows 的截图显示(见图 11-4)。

$ ls -l blog 
total 24
-rw-r--r-- 1 wesley admin 0 Dec 8 18:08 init .py
-rw-r--r-- 1 wesley admin 175 Dec 10 18:30 models.py
-rw-r--r-- 1 wesley admin 514 Dec 8 18:08 tests.py
-rw-r--r-- 1 wesley admin 26 Dec 8 18:08 views.py

图 11-4    Windows 系统中的 blog 文件夹

表 11-2 介绍了其中的应用文件。

表 11-2 Django 应 用 文 件

文  件   名描     述 / 目 的
    init   .py告诉Python 这是一个包
urls.py应用的 URL 配置文件(“URLconf”),这个文件并不像项目的 URLconf 那样自动创建(所以上面的截图中没有)
models.py数据模型
views.py视图函数(即 MVC 中的控制器)
tests.py单元测试

与项目类似,应用也是一个 Python 包。但在这里,models.py 和 views.py 文件中目前还没有真正的代码,需要开发者在今后添加代码。单元测试文件 tests.py 也是如此。同样,即使可以使用项目的 URLconf 来分派访问,也不会自动创建本地应用的 URLconf。这需要手动创建它,接着使用项目 URLconf 里的 include()指令将请求分配给应用的URLconf。

为了让Django 知道这个新的应用是项目的一部分,需要编辑settings.py(可以将其理解为配置文件)。使用编辑器打开这个文件,找到位于底部的 INSTALLED_APPS 这个元组。将应用名称(blog)添加到元组的末尾,如下所示。

INSTALLED_APPS = (
   . . .
   'blog',
)

虽然结尾的逗号不是必需的,但如果今后向该元组中添加其他项,就无须添加逗号。Django 使用INSTALLED_APPS 来配置系统的不同部分,包括自动管理应用程序和测试框架。

发表评论

电子邮件地址不会被公开。 必填项已用*标注