Django搭建个人博客--发表文章
原创
©著作权归作者所有:来自51CTO博客作者贝勒里恩的原创作品,请联系作者获取转载授权,否则将追究法律责任
一、Forms表单类
在HTML中,表单是在<form>...</form>
中的一些元素,它允许访客做类似输入文本、选择选项、操作对象或控件等动作,然后发送这些信息到服务端。一些表单界面元素(文本框或复选框)非常简单并内置在HTML中,而其他会复杂些:像弹出日期选择等操作控件。
Django的表单系统的核心组件是Form
类,它能够描述一张表单并决定它如何工作及呈现。
在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
,指明了数据模型的来源,以及表单中应该包含数据模型的哪些字段。
二、添加视图函数
改写article/views.py
,添加一个视图函数以处理写文章的请求:
...
# 发表文章
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 的用户为作者
# 如果你进行过删除数据表的操作,可能会找不到id=1的用户
# 此时请重新创建用户,并传入此用户的id
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。 - 如果不满足,则返回一个字符串“表单内容有误,请重新填写!”告诉用户出现了什么问题。
三、添加模板
在templates/article/
中创建create.html
:
<!-- extends表明此页面继承自 base.html 文件 -->
{% extends "base.html" %} {% load staticfiles %}
<!-- 写入base.html中定义的 title -->
{% block title %} 写文章 {% endblock title %}
<!-- 写入base.html中定义的 content -->
{% block content %}
<!-- 写文章表单 -->
<div class="container">
<div class="row">
<div class="col-12">
<br>
<!-- 提交文章的表单 -->
<form method="post" action=".">
<!--Django中需要POST数据的地方都必须有csrf_token -->
{% csrf_token %}
<!-- 文章标题 -->
<div class="form-group">
<!-- 标签 -->
<label for="title">文章标题</label>
<!-- 文本框 -->
<input type="text" class="form-control" id="title" name="title">
</div>
<!-- 文章正文 -->
<div class="form-group">
<label for="body">文章正文</label>
<!-- 文本区域 -->
<textarea type="text" class="form-control" name="body" id="body" rows="12"></textarea>
</div>
<!-- 提交按钮 -->
<button type="submit" class="btn btn-primary">完成</button>
</form>
</div>
</div>
</div>
-
<form>...</form>
标签中的内容就是要提交的表单。method="post"
指定了表单提交的方式为POST(与视图函数中的request.method
相联系);action="."
指定了表单提交的地址为默认的当前url。 -
{% csrf_token %}
是Django中一个与网络安全相关的中间件验证。表单中必须包含它,否则将会得到一个403错误。 -
<input>
和<teexarea>
标签中的name=''
属性指定了当前文本框提交的数据的名称,它必须与表单类中的字段名称对应,否则服务器无法将字段和数据正确的对应起来。
四、添加路由
在article/urls.py
中增加一个写文章的url地址:
...
urlpatterns = [
...
# 发表文章
path('article-create/', views.article_create, name='article_create'),
]
五、添加写文章入口
在导航栏中设置一个写文章的入口,通过url:http://127.0.0.1:8000/article/article-create/
访问,这样操作太不友好了。
打开templates/header.html
,加入写文章条目链接:
<!-- 定义导航栏 -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
...
<!-- 导航入口 -->
<div>
<ul class="navbar-nav">
<!-- 条目 -->
<li class="nav-item">
<a class="nav-link" href="{% url 'article:article_create' %}">写文章</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'article:article_list' %}">文章</a>
</li>
</ul>
</div>
</div>
</nav>
六、查看效果
启动服务器,打开网页: