一、添加模板
现在我们进入博客的首页 127.0.0.1:8000
, 发现还是欢迎页面,因为我们还没有给博客添加任何模板,也就是前端HTML页面
博客前端模板托管在GitHub:HTML
将项目下载到本地后,内含两个文件夹,static
、templates
,将 static 文件夹整个拷贝到博客项目根目录下,然后在将 templates 文件夹下的 html 文件全部拷贝到到 templates 目录下。里边的 index.html 就是我们博客的首页。
二、创建视图
Django 中后端的控制都是在视图函数中进行的,也就是 view.py
,每创建一个 app,该 app 目录下都会有一个view.py
,我们主要就是在这里进行后端代码的书写的。
# ------------------------
__author__ = 'fswy'
__date__ = '2020/4/28 11:26'
# ------------------------
from django.shortcuts import render
from django.shortcuts import get_object_or_404, get_list_or_404
from .models import Article, BigCategory, Category, Tag
from django.views.generic import ListView
# Create your views here.
class IndexView(ListView):
'''
首页视图,继承自ListView,用于展示从数据库中获取的文章列表
'''
# 获取数据库中的文章列表
model = Article
# temlate_name 属性用于指定使用哪个模板进行渲染
template_name = 'index.html'
# context_object_name 属性用于给上下文变量取名(在模板中使用该名字)
context_object_name = 'articles'
三、配置首页路由
通过 url 将视图函数与模板关联起来
现在我们有了 index.html
页面,也有了视图函数 IndexView
,但是怎么才能通过 127.0.0.1:8000
访问到这个页面呢?django中是通过 path
将这个页面与视图函数关联起来,也就是前后端的API接口。
添加 urls.py 文件 blog -> fswy
配置页面路由 blog -> fswy -> urls.py
from django.urls import path
from .views import IndexView
urlpatterns = [
path('', IndexView.as_view(template_name='index.html'), name='index')
]
注意
template_name
是指定使用的模板文件,传递给视图,进行数据渲染,后边会详讲路由。
四、配置博客应用路由
blog -> blog -> urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
# 后台管理应用,django自带
path('admin/', admin.site.urls),
# fswy 应用
path('', include(('fswy.urls', "fswy"), namespace="blog")),
]
注意
这里include()
函数,在新版本有所改变
path('', include('fswy.urls', namespace='blog')),
会报错:
django.core.exceptions.ImproperlyConfigured: Specifying a namespace in include() without providing an app_name is not supported. Set the app_name attribute in the included module, or pass a 2-tuple containing the list of patterns and app_name instead.
查找错误出处,为conf.py
文件
def include(arg, namespace=None):
app_name = None
if isinstance(arg, tuple):
# Callable returning a namespace hint.
try:
urlconf_module, app_name = arg
except ValueError:
if namespace:
raise ImproperlyConfigured(
'Cannot override the namespace for a dynamic module that '
'provides a namespace.'
)
raise ImproperlyConfigured(
'Passing a %d-tuple to include() is not supported. Pass a '
'2-tuple containing the list of patterns and app_name, and '
'provide the namespace argument to include() instead.' % len(arg)
)
else:
# No namespace hint - use manually provided namespace.
urlconf_module = arg
if isinstance(urlconf_module, str):
urlconf_module = import_module(urlconf_module)
patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module)
app_name = getattr(urlconf_module, 'app_name', app_name)
if namespace and not app_name:
raise ImproperlyConfigured(
'Specifying a namespace in include() without providing an app_name '
'is not supported. Set the app_name attribute in the included '
'module, or pass a 2-tuple containing the list of patterns and '
'app_name instead.',
)
namespace = namespace or app_name
# Make sure the patterns can be iterated through (without this, some
# testcases will break).
if isinstance(patterns, (list, tuple)):
for url_pattern in patterns:
pattern = getattr(url_pattern, 'pattern', None)
if isinstance(pattern, LocalePrefixPattern):
raise ImproperlyConfigured(
'Using i18n_patterns in an included URLconf is not allowed.'
)
return (urlconf_module, app_name, namespace)
从include()
函数可以看出来,这个函数有两个参数,一个arg
,一个namespace
,我在代码中也是两个参数,但是异常中提示了,没有提供app_name
,还提示需要传入一个两元元组,从第六行代码
urlconf_module, app_name = arg
可以看出来,arg
就是那个元组,且给app_name
赋值了,所以我们这里修改代码为:
urlpatterns = [
# 后台管理应用,django自带
path('admin/', admin.site.urls),
# fswy 应用
path('', include(('fswy.urls', "fswy"), namespace="blog")),
]
目前项目结构
.
|-- blog
| |-- fswy # 博客应用
| | |-- migrations # 数据库映射文件
| | |-- __init__.py # 声明模块,内容默认为空
| | |-- admin.py # 该应用的后台管理系统
| | |-- apps.py # 应用配置,Django-1.9以后自动生成
| | |-- models.py # 数据模块,使用ORM框架
| | |-- tests.py # 自动化测试的模块
| | |-- urls.py # 应用路由
| | |-- views.py # 执行响应的代码所在模块,是代码逻辑处理的主要地点,项目中大部分代码在这里编写
| |-- blog # 项目的容器
| | |-- __init__.py # 声明模块,内容默认为空
| | |-- settings.py # 该 Django 项目的设置/配置。
| | |-- urls.py # 该 Django 项目的 URL 声明; 一份由 Django 驱动的网站"目录"。
| `-- wsgi.py # 一个 WSGI 兼容的 Web 服务器的入口,以便运行你的项目
| |-- static # 静态文件
| | |-- css
| | |-- fonts
| | |-- images
| | |-- js
| |-- templates # 模板文件
| | |-- about.html
| | |-- donate.html
| | |-- exchange.html
| | |-- index.html
| | |-- message.html
| | |-- project.html
| | |-- question.html
| | |-- resources.html
| | |-- technique.html
| | |-- wp-login.html
`-- manage.py
五、修改静态文件路径
访问 127.0.0.1:8000
这个页面时,Django 会通过正则表达式解析这个 url,从而判断出该 url 连接到哪个视图函数,我们这里对应的就是 IndexView
。然后在 IndexView
中, 将 index.html
传递给前端,并通过浏览器展示给用户,这样我们便配置好了首页。
首页样式的加载
但是在刷新首页时,我们发现并没有样式,样式文件我们放在 static 文件夹中了,而index.html并没有定位到该目录
配置静态路径
这里静态文件 static 需要在 settings.py 中配置一下路径,templates 已经在 Django3.0+Python3.8+MySQL8.0 个人博客搭建四|创建第一个APP中设置过了.
blog -> blog -> settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
index.html 中,修改静态文件路径
前端H5源码:
<link rel='stylesheet' id='crayon-css' href='/static/css/crayon.min.css' type='text/css' media='all' />
<link rel='stylesheet' id='crayon-theme-github-css' href='/static/css/github.css' type='text/css' media='all' />
<link rel='stylesheet' id='crayon-font-monaco-css' href='/static/css/monaco.css' type='text/css' media='all' />
修改静态文件路径为绝对路径
<link rel='stylesheet' id='crayon-css' href='/static/css/crayon.min.css' type='text/css' media='all' />
<link rel='stylesheet' id='crayon-theme-github-css' href='/static/css/github.css' type='text/css' media='all' />
<link rel='stylesheet' id='crayon-font-monaco-css' href='/static/css/monaco.css' type='text/css' media='all' />
以上只是部分示列,要把 index.html
文件中的 ../
按上边的方式全改掉
六、查看运行效果
配置好静态路径后,重启项目,查看运行效果
最后再刷新下页面, 发现我们的博客首页已经出现,接下来就是首页渲染数据了。不要感觉这么多步骤很难,对 Django 项目结构进一步了解后也就那么回事,就可以驾轻就熟的搞出自己喜欢的站点了,不要急躁,首页整好后接下来每干一点,都会在前台看到自己的成果,坚持一下,美好即将来临。
现在我们展示的还只是静态页面,首页中博客的内容仍然是崔庆才的内容,为了将我们自己的文章从后台添加的文章展示到前端,我们还需要对视图函数进行进一步完善。下节继续~~~
参考文章:
Django2.0异常:Specifying a namespace in include() without providing an app_name is not supported.