Django搭建博客页面

Django基本使用以及博客搭建的准备工作,请参考Django入门与实践

博客主页面编写

编写思路
  1. 取出数据库中所有文章对象
  2. 将文章对象打包成列表发送到前端
  3. 前端页面以超链接的形式逐个列出
流程
  1. 后端

view.py中传递对象列表

def index(request):
    articles = models.Article.objects.all()
    return render(request, 'blog/index.html', {'articles':articles})
  1. 前端

通过模板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/即可。

博客主页面点击链接进入文章

当点击主页面的文章标题后,跳转到该文章页面

流程
  1. 参数写在响应函数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})
  1. url正则表达式匹配

url.py

urlpatterns = [
    url(r'^article/(?P<article_id>[0-9]+)$', views.article_page),
]

注意这里的组名:article_id>必须和article_page()中的形参article_id一致

  1. 写对应的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链接配置
  1. 根url,写在include()的第二个参数位置,namespace = 'xxx'

myblog.urls.py

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^blog/', include('blog.urls', namespace='blog')),
]
  1. app的urls.pyurl() 第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'),
]
  1. 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. 编写页面

(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. 点击提交按钮后,将前端页面内容返回给后端

(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值titlecontent必须和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进行区分。

  1. 修改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对象,更新前端的数据。
  • 通过新增hiddenarticle_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>
  1. 修改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_pageurl需要修改正则表达式

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>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容

  • 去年的事情特别多,也没有什么时间充电学习。今年目测轻松一点,年初本来计划就好好休息一下,结果一晃2017就度过了一...
    灰豹儿阅读 618评论 0 2
  • 本博客是记录跟从慕课网课程所记下的笔记,更多内容请访问慕课网慕课网--项目源码 新建项目 打开命令行,进入到打算打...
    小白猿阅读 2,229评论 1 10
  • 通过写一个博客项目,来串联自己的知识点,并总结一些小的技巧 页面介绍 1.博客主页面 2.博客文章内容页面...
    be_keeper阅读 682评论 0 0
  • 更换数据表mysql 上文说到编写好了我们的 model 模块,映射生成数据表,之前我们用的是Django 默认的...
    sixkery阅读 705评论 0 12
  • 前面已经对DTL(Django Template Language)语言基础用法进行了讲解,现在我们开始做一个博客...
    E思无邪阅读 27,749评论 6 18