摘要:一些表单界面元素文本框或复选框非常简单并内置在中,而其他会复杂些像弹出日期选择等操作控件。和标签中的属性指定了当前文本框提交的数据的名称,它必须与表单类中的字段名称对应,否则服务器无法将字段和数据正确的对应起来。
前面我们已经学会如何用Markdown语法书写文章了。
但是还有问题呀。之前写文章都是在后台中进行的,万一有别的普通用户也要发表文章怎么办?万一我想拓展些后台中没有的提交验证功能又怎么办?
本章即讲述如何在前台中提交新的文章,以便满足开发者各种各样的特殊需求。
Forms表单类在HTML中,表单是在 中的一些元素,它允许访客做类似输入文本、选择选项、操作对象或空间等动作,然后发送这些信息到服务端。一些表单界面元素(文本框或复选框)非常简单并内置在HTML中,而其他会复杂些:像弹出日期选择等操作控件。
处理表单是一件挺复杂的事情。想想看Django的admin,许多不同类型的数据可能需要在一张表单中准备显示,渲染成HTML,使用方便的界面进行编辑,传到服务器,验证和清理数据,然后保存或跳过进行下一步处理。
Django的表单功能可以简化上述工作的大部分内容,并且也能比大多数程序员自己编写代码去实现来的更安全。
Django表单系统的核心组件是 Form类,它能够描述一张表单并决定它如何工作及呈现。
要使用Form类也很简单,需要在article/中创建forms.py文件,并写入如下代码:
article/forms.py # 引入表单类 from django import forms # 引入文章模型 from .models import ArticlePost # 写文章的表单类 class ArticlePostForm(forms.ModelForm): class Meta: # 指明数据模型来源 model = ArticlePost # 定义表单包含的字段 fields = ("title", "body")
代码中ArticlePostForm类继承了Django的表单类forms.ModelForm,并在类中定义了内部类class Meta(之前提到过,还记得吗),指明了数据模型的来源,以及表单中应该包含数据模型的哪些字段。
在ArticlePost模型中,created和updated字段为自动生成,不需要填入;author字段暂时固定为id=1的管理员用户,也不用填入;剩下的title和body就是表单需要填入的内容了。
接下来,改写article/views.py,添加一个视图函数以处理写文章的请求:
article/views.py ... # 引入redirect重定向模块 from django.shortcuts import render, redirect # 引入HttpResponse from django.http import HttpResponse # 引入刚才定义的ArticlePostForm表单类 from .forms import ArticlePostForm # 引入User模型 from django.contrib.auth.models import User ... # 写文章的视图 def article_create(request): # 判断用户是否提交数据 if request.method == "POST": # 将提交的数据赋值到表单实例中 article_post_form = ArticlePostForm(data=request.POST) # 判断提交的数据是否满足模型的要求 if article_post_form.is_valid(): # 保存数据,但暂时不提交到数据库中 new_article = article_post_form.save(commit=False) # 指定数据库中 id=1 的用户为作者 new_article.author = User.objects.get(id=1) # 将新文章保存到数据库中 new_article.save() # 完成后返回到文章列表 return redirect("article:article_list") # 如果数据不合法,返回错误信息 else: return HttpResponse("表单内容有误,请重新填写。") # 如果用户请求获取数据 else: # 创建表单类实例 article_post_form = ArticlePostForm() # 赋值上下文 context = { "article_post_form": article_post_form } # 返回模板 return render(request, "article/create.html", context)
分析一下上面的代码。当视图函数接收到一个客户端的request请求时,首先根据request.method判断用户是要提交数据(POST)、还是要获取数据(GET):
如果用户是提交数据,将POST给服务器的表单数据赋于article_post_form实例。
然后使用Django内置的方法.is_valid()判断提交的数据是否满足模型的要求。
如果满足要求,保存表单中的数据(但是commit=False暂时不提交到数据库,因为author还未指定),并指定author为id=1的管理员用户。然后提交到数据库,并通过redirect返回文章列表。redirect可通过url地址的名字,反向解析到对应的url。
如果不满足要求,则返回一个字符串"表单内容有误,请重新填写。",告诉用户出现了什么问题。
如果用户是获取数据,则返回一个空的表单类对象,提供给用户填写。
其实逻辑并不复杂,不明白的读者请逐句理解。
这里特别提醒Django中的缩进不能够空格和tab键混用,否则会报错。由于不同的编辑器对tab的显示不尽相同,因此你应该坚持使用空格键缩进。
写好视图之后,就需要写模板文件了。在templates/article/中创建create.html:
templates/article/create.html {% extends "base.html" %} {% load staticfiles %} {% block title %} 写文章 {% endblock title %} {% block content %}{% endblock content %}
html文件还是一如既往的长。再重复一次,看不懂html文件语法也没有关系,先照着抄一遍,以后再慢慢理解,不影响目前Django的学习。
对其中的新内容进行审视:
标签中的内容就是需要提交的表单。method="post"指定了表单提交的方式为POST(与视图函数中的request.method相联系);action="."指定了表单提交的地址为默认的当前url。
关于{% csrf_token %},它是Django中一个与网络安全相关的中间件验证。目前我们暂时不去深究它的实现,只需要知道表单中必须包含它就可以了,否则将会得到一个403错误。
和标签中的name=""属性指定了当前文本框提交的数据的名称,它必须与表单类中的字段名称对应,否则服务器无法将字段和数据正确的对应起来。
最后老规矩,在article/urls.py中增加一个写文章的url地址:
article/urls.py urlpatterns = [ ... # 写文章 path("article-create/", views.article_create, name="article_create"), ]
大功告成了,不要着急,先喝口水,万一有bug又得忙活半天了。如果报错也不要慌张,开发过程一定是曲折的,耐心看看Django给出的错误提示,线索就在其中。
保存修改并运行服务器,地址栏中输入:http://127.0.0.1:8000/article/article-create/,看到如下界面:
很好,似乎正常工作起来了。接着随便输入些Markdown语法的文章,测试功能是否正常:
点击完成按钮后,页面会回到文章列表:
刚才提交的文章神奇的出现在列表中了。
点击阅读本文按钮,进入文章详情页面:
出现了具有Markdown语法的一篇优美的文章。
使用Django编写博客是不是非常有成就感呢?
别激动,还有一些收尾工作需要做。
优化写文章入口与之前类似,我们需要在导航栏中设置一个写文章的入口,优化使用体验。
将下列代码加入到templates/header.html中:
读者是否清楚,上面的代码应该放置在什么位置呢?
保存后刷新浏览器界面,导航栏有了如下变化:
点击写文章按钮,就可以进入写新文章的页面了,从此再也不用手动输入繁琐的url地址了。
世界是多么的美好。
总结本章学习了使用Django的表单类,完成了提交新文章的基本功能。当然目前暂时还没有真正将文章和登录的用户关联起来;等到学习了用户管理的知识,再回头来处理这部分的内容。
下一章继续学习如何删除一篇文章。
有疑问请在杜赛的个人网站留言,我会尽快回复。
或Email私信我:dusaiphoto@foxmail.com
项目完整代码:Django_blog_tutorial
转载请告知作者并注明出处。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/42531.html
摘要:最常见的用法就是存储用户的登录数据。如果用户未登录,则显示登录两个字提醒用户可以点击登录。创建文件用户登录配置根路由用户管理配置因为这个并没有改动,因此不用迁移数据。总结本章用到了表单类模板语句用户验证等知识完成了用户管理的登录和退出。 用户管理 用户数据可以说是大部分网站最重要的资产。用户管理就是对用户数据进行增删改查等操作的功能,自然也就非常的重要了。 本章开始学习用户管理的内容,...
摘要:确认创建成功后,记得在中注册因为我们想显示发表评论的时间,修改时区设置为上海的时区。处理错误请求发表评论仅接受请求。返回到一个适当的中即用户发送评论后,重新定向到文章详情页面。总结本章实现了发表评论展示评论的功能。 在没有互联网的年代,我们用日记来记录每天的心得体会。小的时候我有一个带锁的日记本,生怕被别人看见里面写了啥,钥匙藏得那叫一个绝。 现在时代变了,网络版的日记本:博客,却巴不...
摘要:下一步就是修改视图。判断语句的条件有两个博文的标题图不是必须的,剔除掉没有标题图的文章,这些文章不需要处理图片。总结本章学习了如何上传并处理文章的标题图,从此博客首页就有了漂亮的外观。 现在虽然博客的功能大都实现了,但是界面还是比较朴素,特别是首页的文章列表几乎全是文字,看多了难免疲劳。因此,给每个文章标题配一张标题图,不仅美观,用户也能通过图片快速了解文章内容。实际上大部分社交网站也...
摘要:既然有登录登出,那么用户的注册肯定也是少不了的。用户在注册成功后会自动登录并返回博客列表页面。总结本章用到了表单类对数据进行验证清洗等知识,完成了用户的注册功能。 既然有登录登出,那么用户的注册肯定也是少不了的。 注册表单类 用户注册时会用到表单来提交账号、密码等数据,所以需要写注册用的表单/userprofile/forms.py: /userprofile/forms.py .....
摘要:每一篇文章的标签可能都不一样,并且还可能拥有多个标签,这是与栏目功能不同的。列表中显示标签虽然保存标签的功能已经实现了,还得把它显示出来才行。更多的用法请阅读官方文档总结本章学习了使用来完成标签功能。 标签是作者从文章中提取的核心词汇,其他用户可以通过标签快速了解文章的关注点。每一篇文章的标签可能都不一样,并且还可能拥有多个标签,这是与栏目功能不同的。 好在标签功能也有优秀的三方库:D...
阅读 3452·2019-08-30 15:44
阅读 797·2019-08-30 13:46
阅读 2057·2019-08-30 11:05
阅读 3332·2019-08-29 18:32
阅读 2154·2019-08-29 13:56
阅读 1296·2019-08-29 12:57
阅读 756·2019-08-28 18:21
阅读 1733·2019-08-26 12:16