当前位置:   article > 正文

PythonWeb开发——Django(博客系统实例)_python web django 博客 教程

python web django 博客 教程


Django:用 Python语言编写的 开源Web框架,可以轻松地完成一个功能齐全的 Web开发

1.设计模式

1.MVC模式

MVC是一种使用MVC(Model View Controller 模型-视图-控制器)设计创建Web应用程序的模式:

  • Model(模型)表示应用程序核心(比如数据库记录列表)。
  • View(视图)显示数据(数据库记录)。
  • Controller(控制器)处理输入(写入数据库记录)。
    MVC模式
2.Django MTV 模式

对于Django,它有另一套差不多的模式:MTV模式

  • Model 模型:用来构建和操作Web应用中的数据。
  • View 视图:负责接受用户请求,进行业务处理,并返回响应。
  • Template 模板:负责封装响应结果,生成并返回想要的界面。

MTV模式

2.Django项目

1.Django常用命令

Django项目流程
在命令提示符(cmd)中输入命令行django-admin可查看常用命令。

  • 创建Django项目:startproject
  • 创建Django应用:startapp
  • 运行Django项目:runserver
  • 进入shell项目环境:shell
  • 创建迁移文件:makemigrations
  • 执行迁移文件:migrate
2.创建Django项目

在命令提示符输入命令行:django-admin startproject xxxxxx是你想要创建的项目名。例如:
在这里插入图片描述

3.Django项目目录结构

创建完成之后的Django项目目录结构应该如下图所示:
Django项目目录

目录与文件说明
init.py空文件,表示当前目录是一个包
setting.py整个项目的配置文件
urls.py项目的URL配置文件(路由配置),用于配置用户请求的URL与View模块中函数的对应关系
wsgi.py项目与支持WSGI协议的Web服务器对接的入口文件
manage.py项目的入口文件
4.启动开发服务器

进入项目文件夹,输入命令:python manage.py runserver,然后在浏览器的地址栏输入http://127.0.0.1:8000/,如果看到下面这个页面说明Django项目运行成功
Django项目启动

3.Django应用

1.创建应用

每一个项目可划分为若干个子模块,一个子模块可视为一个应用app。创建Django应用的命令:python manage.py startapp xxx,其中xxx就是你想要创建的应用名,例如:
创建Django应用
创建blog应用之后,项目目录变为:
创建blog应用之后的项目目录

其中,db.sqlite3是在项目测试运行(runserver)时生成的一个默认的后台连接的数据库,目录下的blog文件夹就是刚生成的新的应用。注意,用命令提示符cmd生成项目及应用的时候Template模板文件需要自己创建,用Pycharm中的终端进行创建时会自动生成。

下面对生成的应用blog进行某些目录分析:

目录与文件说明
models.pyModel模型,用来构建和操作Web应用中的数据
Views.pyView视图,负责接受用户请求,进行业务处理,并返回响应
admin.pyDjango自带的后台管理工具
2.添加应用blog

创建应用完成之后要在settings.py中添加应用,如下图位置:
在settings.py中添加应用
需要注意的是在'bolg'后面别忘了加,以便下次新增应用。

3.Django显示HelloWorld

要想输出HelloWorld需要在views.py中自定义一个函数用来输出。
views.py

from django.shortcuts import render
from django.http import HttpResponse

def Hello(request):
    return HttpResponse('Hello World')
  • 1
  • 2
  • 3
  • 4
  • 5

接着需要配置URL(即打开浏览器在地址栏输入什么URL才会调用HelloWorld函数):
urls.py:

from django.contrib import admin
from django.urls import path,include
from blog import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/hello/',views.hello),
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

配置好之后,在终端输入命令:python manage.py runserver开启服务器,然后到浏览器地址输入http://127.0.0.1:8000/blog/hello/,成功的页面如下所示:
输出helloworld

这里需要考虑另一个很重要的问题就是:当URL出现过多或者app中出现同名函数造成路由混乱了怎么办?为了解决这个问题,可以将路由分解为项目路由,应用路由。改进如下:

blog_yyz下的urls.py(项目路由):

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls')),
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

blog下的urls.py(需要自己新建,应用路由):

from django.urls import path,include
from blog import views

urlpatterns={
    path('hello/',views.hello)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

实际的地址http://127.0.0.1:8000/blog/hello/由上面两部分路由共同组成。

4.模板系统

在上面HelloWorld的例子中,返回的仅仅是一个字符串,但是在实际项目中返回的应该是一个页面,也就是模板T,里面可以对数据进行动态的渲染。Django模板语言DTL带有特殊语法的HTML文件,可以传递View视图中的参数,实现数据动态化。
渲染模板(传递参数):

from django.shortcuts import render

def index(request):
    return render('request','xxx.html',{字典传递参数})
  • 1
  • 2
  • 3
  • 4
1.配置views.py
from django.shortcuts import render
from django.http import HttpResponse

def hello(request):
    return HttpResponse('Hello World')
def index(request):
    return render(request,'index.html')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
2.配置路由

blog下的urls.py

from django.urls import path,include
from blog import views

urlpatterns={
    path('hello/',views.hello),
    path('index/',views.index)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
3.实现效果

在浏览器地址栏中输入地址http://127.0.0.1:8000/blog/index/即可访问到以下页面:
模板系统实现效果

5.模型层

Django中的一个模型类就对应着数据库中的一张数据表,对模型类的操作就是对数据库表的操作。引入模型层的原因就是:因为数据库存在多样性,因此如果同一个程序要连接管理不同的数据库,语法会有差异,引入模型类就能实现统一的管理,大大方便了我们对数据库的操作。
Django模型层

1.数据库配置settings.py

settings.py中的DATABASES字段配置了项目所用到的数据库,如下图:
DATABASES
在本次的实验项目中,可以看到用的数据库是db.sqlite3(本地的轻量级数据库),也就是默认的后台数据库,一开始运行项目时所生成的那个文件。

2.博客文章格式分析

博客文章大概可分为四部分文章标题,文章摘要,文章内容,文章ID
博客文章格式分析

3.编写models.py

models.py中的一个就对应数据库中的一张表,类中的一个对象就对应数据库表中的一个字段

from django.db import models

class Article(models.Model):
    article_id=models.AutoField(primary_key=True)
    title=models.TextField()
    abstract=models.TextField()
    content=models.TextField()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
4.生成并执行迁移文件

生成迁移文件
编写完models.py之后,要想在数据库db.sqlite3中生成对象的表和字段,需要生成迁移文件并执行,迁移的目的是通过Django的ORM系统将定义在模型类中的字段转换成对应的SQL语句。执行命令为:python manage.py makemigrations,执行完之后会在migrations目录下增加0001_initial.py文件。
执行命令生成迁移文件
执行迁移文件
执行迁移文件数据库生成相应数据库表与字段,执行命令为:python manage.py migrate
执行迁移文件
执行完之后,接下去就是验证是否生成了对应的数据库的表及各字段,需要用到软件:Navicat Premium
Navicat Premium
在软件内建立与sqlite的连接,选择本地文件(就是Django博客项目下的db.sqlite3文件),用户名为root不需要输入密码,打开数据库查找到blog_article这张表即可看到对应的四个字段已经生成。如下图:
建立与sqlite的连接
检验是否成功生成

6.Django Shell

交互式的编程方式,类似与python shell。继承Django环境,可临时性操作和小范围的Debug。不需要运行整个项目来测试。
命令:python manage.py shell
实例:使用Django shell创建博客文章。

7.关于数据库sqlite的一些操作

1.插入操作
  1. 实例化对象
  2. 字段赋值
  3. 对象.save()方法保存

首先在命令行输入python manage.py shell
进入Django shell 模式
接着依次输入以下几条命令创建一个实例化对象

from blog.models import Article
a=Article()
a.title='随笔'
a.abstract='笔记'
a.content='......'
a.save()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

如下图:
创建实例化对象
接着去Navicat Premium中对blog_article这张表进行刷新可以看到数据已经添加成功了:
插入数据成功

2.查询操作
  1. get方法:查询一条记录(有多条或没有记录会出错)
  2. all方法:获取所有数据
    例如,在上述例子中,在命令行输入articles=Article.objects.all(),接着利用for循环打印输出信息,如下图(这里我只存了一条信息,如果表中存了多条数据打印出来的就是全部文章的标题title):
    all方法获取所有数据
  3. filter方法:根据条件查询
3.更新操作
  1. get方法找到对象
  2. 给字段更新数据
  3. 对象.save()方法保存
4.删除操作

对象.delete()

8.动态数据页面

能够将数据库sqlite中的数据打印输出了之后,现在就需要将数据渲染到一个动态的数据页面index.html上去,达到最终目的。
静态页面index.html来自于Bootstrap,部分代码如下图:
静态页面index.html
Django模板语法

{% for ... in ...%}
...
{% endfor %}
  • 1
  • 2
  • 3
{% if %}
...
{% elif %}
...
{% else %}
  • 1
  • 2
  • 3
  • 4
  • 5
{% 变量 %}
  • 1

采用Django模板语言(DTL)改写之后:
index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>我的第一个Django Web项目</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body>
<div class="container page-header">
    <h1>第一个Django项目-极简博客
    <small>--by yyz</small>
    </h1>
</div>
<div class="container page-body">
    <div class="col-md-9" role="main">
        <div class="body-main">
            <div>
                {% for article in articles %}
                    <h2>{{article.title}}</h2>
                    <p>
                    {{article.content}}
                    </p>
                {% endfor %}
            </div>
        </div>

    </div>
    <div class="col-md -3" role="complementary">
        <div>
            <h2>最新文章</h2>
            {% for article in articles %}
                <h4><a href="#">{{article.title}}</a></h4>
            {% endfor %}
        </div>
    </div>
</div>

</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

views.py也需要改写(将index.html中的循环变量articles做为参数传过去):

from django.shortcuts import render
from django.http import HttpResponse
from blog.models import Article

def hello(request):
    return HttpResponse('Hello World')
def index(request):
    articles=Article.objects.all()
    return render(request,'index.html',{'articles':articles})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

最终实现效果(这里因为数据库只有一篇文章显得很不美观):
最终实现效果

9.博客详情页面detail.html

用Django模板语法先对detail.html进行改写:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>我的第一个Django Web项目</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body>
<div class="container page-header">
    <h1>{{ curr_article.title }}
    </h1>
</div>
<div class="container body-main">
            <div>
                <p>
                    {{ curr_article.content }}
                </p>
            </div>
            <div>
                <nav aria-label="...">
                  <ul class="pager">
                    <li><a href="/blog/detail/{{ p_article.article_id}}">上一篇:{{ p_article.title }}</a></li>
                    <li><a href="/blog/detail/{{ n_article.article_id}}">下一篇:{{ n_article.title }}</a></li>
                  </ul>
                </nav>
            </div>
</div>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

接着编写视图函数views.py中的对应detail方法:

def get_detail_page(request):
	curr_article=Article.objects.all()[0] #[0]表示拿到第一篇文章
	return render(request,'detail.html',{
	'curr_article':curr_article #curr_article就是你想要查看详细内容的那篇文章
})
  • 1
  • 2
  • 3
  • 4
  • 5

当然还需要配置URL:
应用路由blog下的urls.py添加一条路由(项目路由不需要配置):

path('detail/',views.get_detail_page),
  • 1

接着在浏览器地址栏中输入:http://127.0.0.1:8000/blog/detail就能访问到第一篇文章的详情页面了。
当然,这种做法每次需要在代码输入指定的文章下标[]才能去进行访问,显然是不科学的,最好的方法就是在浏览器地址栏中直接输入对应文章的id就能访问到指定文章的详情页面,就比如输入http://127.0.0.1:8000/blog/detail/1,就能访问到第二篇文章。
所以就需要更改一下路由配置urls.py

path('detail/<int:article_id>',views.get_detail_page),
  • 1

对应的视图函数views.py

def get_detail_page(request,article_id):
	all_article=Article.objects.all()
	for article in all_article:
		if article.article_id==article_id:
            curr_article=article
            break
	return render(request,'detail.html',{
	'curr_article':curr_article #curr_article就是你想要查看详细内容的那篇文章
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这样就实现了在地址栏可以输入http://127.0.0.1:8000/blog/detail/下标来访问对应下标的文章详情页面。

10.文章列表页index.html与详情页detail.html相关联

想要实现在文章列表中点击对应的文章超链接或标题可以跳转到指定文章的详情页面。
index.html

<div>
    {% for article in articles %}
        <h2><a href="/blog/detail/{{ article.article_id }}" >{{article.title}}</a></h2>
        <p>
        {{article.content}}
        </p>
    {% endfor %}
</div>
...
<div>
   <h2>最新文章</h2>
   {% for article in articles %}
   	   <h4><a href="/blog/detail/{{ article.article_id }}">{{article.title}}</a></h4>
   {% endfor %}
</div>
...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

但是详情页面又显得非常单调,除了标题和内容就没其他元素了。可以在详情页面加上一组按钮,用来实现跳转上一篇或者下一篇的功能。
Bootstrap 翻页功能组件
翻页功能代码
detail.html
当然这里另外需要增加显示的是在上一篇下一篇按钮处显示对应上一篇或者下一篇文章的题目

<div>
    <p>
        {{ curr_article.content }}
    </p>
</div>
<div>
    <nav aria-label="...">
      <ul class="pager">
        <li><a href="/blog/detail/{{ p_article.article_id}}">上一篇:{{ p_article.title }}</a></li>
        <li><a href="/blog/detail/{{ n_article.article_id}}">下一篇:{{ n_article.title }}</a></li>
      </ul>
    </nav>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

接着就需要在views.py中找到上一篇和下一篇文章并传过来,具体思路就是先要找到当前这篇文章的下标索引值index,那么它的上一篇文章的下标就是index-1,下一篇文章的下标就是index+1,当然当当前文章是第一篇时,它是没有上一篇的;当前文章是最后一篇时,它是没有下一篇的。

def get_detail_page(request,article_id):
    all_article=Article.objects.all()
    p_index=0 #前一篇文章的下标
    n_index=0 #后一篇文章的下标
    for index,article in enumerate(all_article): #enumerate函数的作用是为迭代对象添加索引,索引下标从0开始
        if index==0: #当前文章是第一篇
            p_index = 0
            n_index = index+1
        elif index==len(all_article)-1: #当前文章是最后一篇
            p_index = index-1
            n_index = index
        else:
            p_index = index-1
            n_index = index + 1
        if article.article_id==article_id:
            curr_article=article
            p_article=all_article[p_index]
            n_article = all_article[n_index]
            break
    return render(request,'detail.html',{'curr_article':curr_article,'p_article':p_article,'n_article':n_article})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

完成之后的效果如下图:
详情页面可以进行翻页操作

11.对详情页面进行分页

还是一样去刚才的Bootstrap复制分页的html代码,并把它放到index.html中。
Bootstrap上的默认分页的代码

<div>
    <nav aria-label="Page navigation">
      <ul class="pagination">
        <li>
          <a href="/blog/index?page={{previous_page}}" aria-label="Previous">
            <span aria-hidden="true">&laquo;</span>
          </a>
        </li>
          <% for num in page_num%>
        <li><a href="/blog/index?page={{num}}">{{num}}</a></li>
          {% endfor %}
        <li>
          <a href="/blog/index?page={{next_page}}" aria-label="Next">
            <span aria-hidden="true">&raquo;</span>
          </a>
        </li>
      </ul>
    </nav>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

目前在网页上常见的浏览不同页面的方法就是在地址栏中输入http://127.0.0.1:8000/blog/index?page=1,通过获取到地址栏的中page参数的值来显示对应的页面。语句为:

page=int(request.GET.get('page')) #获取到的page是字符串类型的,需要进行转换。
  • 1

具体的分页需要用到Django的一个模块:Paginator。具体代码及函数如下:

from django.core.paginator import Paginator as pr

def index(request):
    page=request.GET.get('page')
    if page: #这里代码的目的是为了防止第一次输入时地址出错就默认跳转到第一页
        page=int(page)
    else:
        page=page
    all_articles = Article.objects.all()
    paginator=pr(all_articles,3) #每一页三篇文章
    page_num=paginator.num_pages #总页数
    page_article_list=paginator.page(page)
    if page_article_list.has_next(): #has_next():是否有下一页
        next_page = page + 1
    else:
        next_page = page + 1
    if page_article_list.has_previous(): #has_previous():是否有上一页
        previous_page = page - 1
    else:
        previous_page = page
    return render(request,'index.html',{
        'articles':page_article_list,
        'curr_page':page, #当前页
        'previous_page':previous_page, #上一页
        'next_page':next_page, #下一页
        'page_num':range(1,page_num+1), #各个页码的列表
    })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

最终实现的效果如下图:
添加分页之后的导航页面

12.Django Admin 模块

Django Admin 模块是Django自带的的后台管理工具,可读取模型数据,提供强大的管理使用页面。
创建admin用户:python manage.py createsuperuser,然后输入我们的用户名和密码:
创建admin用户
后台管理的URL是http://127.0.0.1:8000/admin,不需要我们手动配置,直接可以访问。

在访问时,如果出现TypeError: 'set' object is not reversible的报错,报错的原因是“设置”对象不可逆。只需要将urls.py中的urlpatterns改为[]而不是{}即可。

访问成功的页面如下:
admin后台管理系统页面
输入自己刚才设置的用户名和密码进行登录:
登录成功页面
注册模型之后的管理页面
第一次登录是是看不到BLOG下的Articles的,这时候需要在admin.py中注册模型

from blog.models import Article
admin.site.register(Article)
  • 1
  • 2

如果想要设置语言为中文,可以在settings.py中修改:
settings.py设置语言及时区
LANGUAGE_CODE是设置语言环境TIME_ZONE设置时区

LANGUAGE_CODE = 'zh-Hans' #修改语言为中文
TIME_ZONE = 'Asia/Shanghai' #修改时区
# Python和Django的版本问题,可能会导致退出服务
  • 1
  • 2
  • 3

13.Django运用MySql数据库

Django的MTV模式中的的模型model采用的是ORM模型的方式:对象关系映射,通过类的方法操作数据库,不再写原生的SQL语句,把表映射成类,把行作实例,把字段作属性。(Django在操作数据库时可以忽视数据库的类型,仅仅是操作某个类就可以实现对数据库中表,字段的操作)。这种模式的优点就是:性能损耗小,设计灵活,可移植性(轻松切换数据库)

1.创建数据库

可以在MySql中直接创建,也可以用Navicat连接到MySql并创建。
在连接上右键选择新建数据库:
新建数据库

2.配置数据库连接

创建好了之后就需要在seetings.py配置数据库连接
seetings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME':'blogdb',
        'USER':'root',
        'PASSWORD':'182584',
        'HOST':'127.0.0.1',
        'PORT':'3306'
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

即便是这样配置好了,项目还是无法执行,因为对应的迁移文件还没有创建。并且,Django操作Mysql数据库需要一个驱动程序—pymysql库,首先先下载pymysql第三方库。然后,在整个项目的_init_.py中添加如下代码:

import pymysql

pymysql.version_info = (1, 3, 13, "final", 0) //这句话是为了解决Django3与pymysql不兼容的问题
pymysql.install_as_MySQLdb()
  • 1
  • 2
  • 3
  • 4
3.创建迁移文件并执行

创建迁移文件之前,需要将之前sqlite的迁移文件删除掉,即下图中的0001_initial.py
在这里插入图片描述
然后执行命令python manage.py makemigrations来创建迁移文件:
创建迁移文件
执行python manage.py migrate来执行迁移文件(看到一连串的OK就说明执行成功了):
执行迁移文件
可以看到Mysql中的blogdb数据库中已经多了一张表blog_article
生成表blog_article
这个时候再去启动项目服务可以看到在地址http://127.0.0.1:8000/blog/index/?page=1中已经出现页面,但是还没有数据显示,因为我们压根没有往表中添加数据:
项目启动成功

4.给空数据表中添加数据

可以选择执行sql文件或者手动添加数据,数据添加完了之后刷新页面就有文章可见了:
添加数据之后的blog页面

5.模板路径的设置

在视图函数views.py中,每个函数都有一句返回语句:

from django.shortcuts import render
...
def index(request):
...
return render(request,'index.html',{字典传递参数})
  • 1
  • 2
  • 3
  • 4
  • 5

像上图中的index.html,写的时候并没有指定具体的路径,仅仅是写了文件名,并且index.html这些html文件都放在blog/templates(应用/模板)下。其中的原因就是在seetings.py文件中:
seetings.py中的TEMPLATES模板设置
'DIRS':[]:(如果你想执行html文件)到指定路径下查找。
APP_DIRS:True:到app(视图函数对应的app)的templates目录下查找。
先按DIRS找,然后找已安装的app的templates目录,再找其他app(选择有先后次序)。当然在seetings.py中已经添加了应用blog
在settings.py中已经添加了应用blog
所以在render的参数中,index.html不需要再加什么路径,它会自己找到所在app下的templates中去寻找。当然,如果index.html并不是直接放在templates目录下,而是放在templates/aa文件夹下,那么在render中的路径就要改为aa/index.html,否则就会报错了。

如果有多个应用同时使用到模板文件,比如index.html,那么这些模板文件都可以放到整个项目的templates文件夹(自己新建)下,在所有的应用中的视图函数views.py都可以方便使用。如果templates放到了整个项目文件夹下,需要进行配置才可以使用。配置方法如下:
settings.py中配置:

'DIRS': [os.path.join(BASE_DIR,'templates')]
  • 1

BASE_DIR在项目中原本就有配置,就是整个项目的路径:

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  • 1

14.静态文件

1.定义

一个网页中,除了html骨架外,还有css样式文件,js执行文件,以及图片等文件。

2.加载方法
  • 确保django.contrib.staticfiles已经添加到应用。
    django.contrib.staticfiles添加到应用
  • 确保settings.py中设置了STATIC_URL。
    settings.py中设置了STATIC_URL
  • 把静态文件放在static文件夹下(应用,项目)。具体文件夹建立在哪里就看静态文件用在某个应用下还是多个应用都会用到。
    应用:blog/static/blog
    项目:STATICFILES_DIRS=[os.path.join(BASE_DIR,'static')]
3.具体实现

如下图在应用blog文件夹下新建一个文件夹static,将静态文件(图片等)放到里面。
在应用下面新建一个static文件夹
为了避免与原index.html混淆,新建一个index2.html,然后写入以下代码:

{% load static %} #load标签加载静态文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
        <img src="{% static '20190309160339403.gif' %}" alt=""> #这里只需要写文件名,因为在settings.py中已经设置了应用静态文件的路径为blog/static
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

因为有了一个新的页面,因此还需要配置视图函数,在之前的hello视图函数的基础上改写:

def hello(request):
    return render(request,'index2.html')
  • 1
  • 2

在地址栏中输入:http://127.0.0.1:8000/blog/hello/就可以访问到添加了静态页面之后的页面:
添加了静态文件的页面

当有多个应用在使用静态文件的时候,假如两张图片重名了,那么为了避免寻找出错,我们需要在每个应用的static文件夹下再新建一个和应用同名的文件夹static文件夹下再新建一个和应用同名的文件夹
然后在页面index2.html中将文件名改成地址+文件名:<img src="{% static 'blog/20190309160339403.gif' %}" alt="">,这样就可以避免应用静态文件重名的问题。

同样的,如果静态文件是多个应用会用到的,那么就在整个项目文件夹下新建一个static文件夹,然后放入静态文件,在settings.py中写入语句:STATICFILES_DIRS=[os.path.join(BASE_DIR,'static')]index2.html中img的src只需要写一个文件名就可以了。

Django(博客系统实例)到此结束!!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/73807
推荐阅读
相关标签
  

闽ICP备14008679号