Django基本使用以及博客搭建的准备工作,请参考Django入门与实践
博客主页面编写
编写思路
- 取出数据库中所有文章对象
- 将文章对象打包成列表发送到前端
- 前端页面以超链接的形式逐个列出
流程
- 后端
view.py
中传递对象列表
def index(request):
articles = models.Article.objects.all()
return render(request, 'blog/index.html', {'articles':articles})
- 前端
通过模板for循环显示
{% for xx in xxs %}
html语句
{%endfor%}
注意这里不是{{ }}
而是{% %}
index.html
中
<html>
<head>
<title>my first html!</title>
</head>
<body>---
<h1>
<a href="">新文章</a>
</h1>
{%for article in articles %}
<a href="">{{article.title}}</a>
<br>
{% endfor %}
</body>---
</html>
浏览器打开地址http://localhost:8000/blog/index/
即可。
博客主页面点击链接进入文章
当点击主页面的文章标题后,跳转到该文章页面
流程
- 参数写在响应函数
request
后,可以有默认值
views.py
中
def article_page(request, article_id):
article = models.Article.objects.get(pk=article_id)
return render(request, 'blog/article.html', {'article':article})
- url正则表达式匹配
url.py
中
urlpatterns = [
url(r'^article/(?P<article_id>[0-9]+)$', views.article_page),
]
注意这里的组名:article_id>
必须和article_page()
中的形参article_id
一致
- 写对应的
article.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Article Page</title>
</head>
<body>
<h1>{{article.title}}</h1>
<br/>
<h3>{{article.content}}</h3>
<br/><br/>
<a herf="">修改文章</a>
</body>
</html>
浏览器输入http://localhost:8000/blog/article/1
可以打开索引为1的文章页面。
但是index
主页面的超链接点击没有反应,需要额外的配置。
url链接配置
-
根url
,写在include()
的第二个参数位置,namespace = 'xxx'
myblog.urls.py
中
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^blog/', include('blog.urls', namespace='blog')),
]
- app的
urls.py
中url()
第3个位置,name =xxx
blog.urls.py
中
urlpatterns = [
url(r'^index/$', views.index),
url(r'^article/(?P<article_id>[0-9]+)$', views.article_page, name='article_page'),
]
- html修改
index.html
中的href
配置
<html>
<head>
<title>my first html!</title>
</head>
<body>---
<h1>
<a href="">新文章</a>
下</h1>
{%for article in articles %}
<a href="{% url 'blog:article_page' article.id %}">{{article.title}}</a>
<br>
{% endfor %}
</body>---
</html>
博客新建文章撰写页面
页面内容
- 标题编辑栏
- 文章内容编辑区域
- 提交按钮
- 后端获取前端数据
- 存入数据库
流程
- 编写页面
(1) view.py
def edit_page(request):
return render(request, 'blog/edit_page.html')
(2) 新建edit_page.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Edit Page</title>
</head>
<body>
<form action="" method="post">
<label>
文章标题
<input type="text" name="title"/>
</label>
<br/>
<label>
文章内容
<input type="text" name="content"/>
</label>
<br/>
<br/>
<input type="submit" />
</form>
</body>
</html>
注意这里<input type="text" name="content"/>
的name
和后面post
获取该前端数据的key值
必须相同。
(3) urls.py
urlpatterns = [
url(r'^edit/$', views.edit_page),
]
浏览器输入http://localhost:8000/blog/edit/
即可。
- 点击
提交按钮
后,将前端页面内容返回给后端
(1) 使用request.POST['参数名']
来获取前端的表单数据
blog.views.py
中编写提交按钮
的响应函数
def submit_action(request):
title = request.POST.get('title', 'TITLE')
content = request.POST.get('content', 'CONTENT')
models.Article.objects.create(title=title, content=content)
# 新文章提交后,默认返回主页面
articles = models.Article.objects.all()
return render(request, 'blog/index.html', {'articles':articles})
注意这里post
获取该前端数据的key值title
和content
必须和html中的输入框的name
相同,比如<input type="text" name="content"/>
。
(2) 存入数据库
models.Article.objects.create(title,content)
创建对象
(3) 配置url
blog.urls.py
urlpatterns = [
url(r'^submit_action/$', views.submit_action, name='submit_action'),
]
(4)提交按钮
绑定url
edit_page.html
中为表单添加url
<form action="{% url 'blog:submit_action'%}" method="post">
</form>
(5) 浏览器中点击提交按钮
访问页面会发现报错:
禁止访问 (403)
CSRF验证失败. 请求被中断.
Django中通过POST提交表单的时候需要添加
{% csrf_token %}
即:
<form action="{% url 'blog:submit_action'%}" method="post">
{% csrf_token %}
博客已提交的文章重新编辑界面
重新编辑文章页面有文章内容,而新建文章编辑页面没有文章内容。
重新编辑的文章有文章对象,对象id是数据库存入自动生成的键值,从1开始的整形数据。
而新建文章的页面,id可以传入默认值0进行区分。
- 修改html
index.html
中
- 点击新建文章返回
0
, 进入编辑页面。 - 点击已有文章,返回文章
id
,进入文章页面。
<h1>
<a href="{% url 'blog:edit_page' 0 %}">新文章</a>
</h1>
{%for article in articles %}
<a href="{% url 'blog:article_page' article.id %}">{{article.title}}</a>
<br>
{% endfor %}
article.html
中
- 文章页面的
编辑文章
按钮,返回当前文章id,进入编辑页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Article Page</title>
</head>
<body>
<h1>{{article.title}}</h1>
<br/>
<h3>{{article.content}}</h3>
<br/><br/>
<a href="{% url 'blog:edit_page' article.id %}">编辑文章</a>
</body>
</html>
edit_page.html
中
- 如果编辑已有的文章,后端会传入
article
对象,更新前端的数据。 - 通过新增
hidden
的article_id
来标识提交的是新文章还是已有文章。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Edit Page</title>
</head>
<body>
<form action="{% url 'blog:submit_action'%}" method="post">
{% csrf_token %}
{% if article %}
<input type="hidden" name="article_id" value="{{article.id}}" >
<label>
文章标题
<input type="text" name="title" value={{article.title}} />
</label>
<br/>
<label>
文章内容
<input type="text" name="content" value={{article.content}} />
</label>
<br/>
<br/>
{% else %}
<input type="hidden" name="article_id" value="0" >
<label>
文章标题
<input type="text" name="title"/>
</label>
<br/>
<label>
文章内容
<input type="text" name="content"/>
</label>
<br/>
<br/>
{% endif %}
<input type="submit", name="提交" />
</form>
</body>
</html>
- 修改
view.py
(1) edit_page
函数
- 编辑已有文章,传入
article
对象。 - 编辑新建文章,不传
article
对象。
def edit_page(request, article_id):
# 编辑文章的页面
if str(article_id) == '0':
# 如果是新建文章,则直接编辑空文章
return render(request, 'blog/edit_page.html')
else:
# 如果编辑之前的文章,则传入对象,进行显示
article = models.Article.objects.get(pk=article_id)
return render(request, 'blog/edit_page.html', {'article':article})
(2) submit_action
函数
-
article.html
进入的编辑页面,传入的article_id
不为0,则更新数据库的数据 -
index.html
主页面进入的新建文章的编辑页面,传入的article_id
为0,创建新的数据库对象。
def submit_action(request):
# 编辑文章页面的提交按钮的处理行为
title = request.POST.get('title', 'TITLE')
content = request.POST.get('content', 'CONTENT')
article_id = request.POST.get('article_id', '0')
if article_id == '0':
models.Article.objects.create(title=title, content=content)
# 新文章提交后,默认返回主页面
articles = models.Article.objects.all()
return render(request, 'blog/index.html', {'articles':articles})
else:
article = models.Article.objects.get(pk=article_id)
article.title = title
article.content = content
article.save()
# 之前文章编辑后,返回文章页面
return render(request, 'blog/article.html', {'article': article})
(3)修改urls.py
views.edit_page
的url
需要修改正则表达式
urlpatterns = [
url(r'^index/$', views.index),
url(r'^article/(?P<article_id>[0-9]+)$', views.article_page, name='article_page'),
url(r'^edit/(?P<article_id>[0-9]+)$', views.edit_page, name='edit_page'),
url(r'^submit_action/$', views.submit_action, name='submit_action'),
]
最后可以浏览器输入地址http://localhost:8000/blog/index/
进行测试了。
Templates 过滤器
这里用过滤器将代码进行优化
过滤器使用方法:
{{value|filter}}
过滤器可叠加
{{value|filter1|filter2}}
比如
{{list_nums|length}}
edit_page.html
中可以使用过滤器来简化if else
<form action="{% url 'blog:submit_action'%}" method="post">
{% csrf_token %}
{% if article %}
<input type="hidden" name="article_id" value="{{article.id}}" >
<label>
文章标题
<input type="text" name="title" value={{article.title}} />
</label>
<br/>
<label>
文章内容
<input type="text" name="content" value={{article.content}} />
</label>
<br/>
<br/>
{% else %}
<input type="hidden" name="article_id" value="0" >
<label>
文章标题
<input type="text" name="title"/>
</label>
<br/>
<label>
文章内容
<input type="text" name="content"/>
</label>
<br/>
<br/>
{% endif %}
<input type="submit", name="提交" />
</form>
改为
<form action="{% url 'blog:submit_action'%}" method="post">
{% csrf_token %}
<input type="hidden" name="article_id" value="{{article.id|default:'0'}}" >
<label>
文章标题
<input type="text" name="title" value="{{article.title}} "/>
</label>
<br/>
<label>
文章内容
<input type="text" name="content" value="{{article.content}}" />
</label>
<br/>
<br/>
<input type="submit", name="提交" />
</form>