django + layui + sqlite3 配置
1 工作目录(环境配置)
配置环境(conda + vscode)
# 1 创建虚拟环境
conda create -n web_blog
# 2 进入虚拟环境
conda activate web_blog
# 3 安装 django
pip install Django
# 4 创建工程,文件名为 web_blog
django-admin startproject web_blog
使用vscode打开web_blog文件夹,使用虚拟环境web_blog
使用命令python manage.py runserver, 然后打开网站127.0.0.1:8000, 可以打开,环境配置成功。
2创建第一个页面
需要创建一个应用(app),承担一些单独的功能。在虚拟环境中执行,python manage.py startapp app_name
相关的文件功能如下:
admin.py文件跟网站的后台管理站点配置相关。apps.py文件用于配置当前子应用的相关信息。migrations目录用于存放数据库迁移历史文件。models.py文件用户保存数据库模型类。tests.py文件用于开发测试用例,编写单元测试。views.py文件用于编写Web应用视图。
同时在settings.py文件下修改
.....
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'web_resume' # startapp web_resume app名字
]
......
3使用layui组件
在layUi官网下载并且解压至static文件夹。已知项目文件夹如下:
├─static
│ ├─layui-v2.11.6 # layui 文件夹 放在此处
│ │ └─layui
│ │ ├─css
│ │ └─font
├─templates
│ └─resume # 前端页面 html 放在这个
├─web_blog # startproject web_blog 工程名字
│ └─__pycache__
└─web_resume # startapp web_resume app名字
├─migrations
│ └─__pycache__
└─__pycache__
为了确保django能够识别到layui文件夹同时修改web_blog中的settings.py,增加以下信息:
import os
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR), 'templates'],
'APP_DIRS': True,
'OPTIONS': {
.........
},
},
]
STATIC_URL = '/static/' # app下面的 static
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'), # 项目根目录下面的 static
]
配置完以上内容,再通过以下三个步骤可以创建第一个页面
3.1创建index.html页面
在index.html中要引入layui的格式,添加以下内容
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>测试 - Layui</title>
<link rel="stylesheet" href="{% static 'layui-v2.11.6/layui/css/layui.css' %}">
</head>
....
<script src="{% static 'layui-v2.11.6/layui/layui.js' %}"></script>
....
关键代码{% load static %}表示使用静态文件标签,必须放在html页面开头部分。load是Django模板系统的关键字(保留指令),static 只是一个模板库名字(app 名),不是关键字,属于 django.contrib.staticfiles这个官方contrib应用
{% static 'A/B/C' %} 会把“A/B/C”拼成 settings.STATIC_URL + A/B/C” 的完整URL。
3.2创建视图函数
在app文件夹下编写views.py视图函数
from django.shortcuts import render
def index(request):
articles = Article.objects.all() # Article 是models.py 里面定义的 数据库表 articles 为返回的queryset
return render(request, 'resume/index.html', {'articles': articles})
render函数,根据参数request参数找到resume/index.html,其中,存放前端页面的完整路径如下,参数{'articles': articles}键名'articles'将成为模板里能用的变量名;articles是刚才查到的 QuerySet。
├─templates
│ └─resume
│ └─index.html
介绍一个常用函数get_object_or_404
from django.shortcuts import get_object_or_404
def article_detail(request, pk):
article = get_object_or_404(Article, pk=pk) # 主键找不到直接 404
return render(request, 'resume/detail.html', {'article': article})
# 等价于如下写法
try:
article = Article.objects.get(pk=pk)
except Article.DoesNotExist:
raise Http404('No Article matches the given query.')
- 首先去数据库调用Model.objects.get(args, *kwargs)
- 如果记录存在,返回该对象
- 如果记录不存在,自动抛出Http404异常,Django会捕获并返回404页面,无需你手写
try/except
3.3配置路由
首先在app文件下的urls.py
from django.urls import path
app_name = 'resume' # django 保留关键字 方便前端页面引用
urlpatterns = [
path('', views.index, name='index'), # name 参数是该路由的全名
path('article/<int:pk>/', views.article_detail, name='article_detail'),
path('category/<slug:category_slug>/', views.article_list, name='category'), # slug 用以匹配字母、数字,-,_
]
主项目下的urls.py
urlpatterns = [
path('admin/', admin.site.urls), # 默认 管理超级管理员的路由
path("resume/", include("app_name.urls")), # 增加的app下的路由
]
4初始化数据库
创建数据库文件,在app下的models.py
class Article(models.Model):
title = models.CharField('title', max_length=120) # 标题
summary = models.CharField('abstract', max_length=255, blank=True) # 摘要
content_md = models.TextField('content') # 正文
content_html = models.TextField('con_HTML', editable=False, blank=True) # 渲染后html
cover = models.ImageField('img', upload_to='covers/', blank=True) # 题图 实际目录上传至 settings.MEDIA_ROOT + upload_to 目录
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='articles', null=True) # 文章类别
created_at = models.DateTimeField('create_time', auto_now_add=True, null=True) # 创建时间
updated_at = models.DateTimeField('update', auto_now=True) # 更新时间
views = models.PositiveIntegerField('num_views', default=0) # 浏览次数
class Meta:
ordering = ['-created_at'] # 查询的结果 按时间排序,
def save(self, *args, **kwargs):
# 只要有 md 就重新渲染,空 md 则留空 html
import markdown
if self.content_md:
self.content_html = markdown.markdown(
self.content_md,
extensions=['fenced_code', 'codehilite', 'toc'],
safe_mode=False,
enable_attributes=False
)
else:
self.content_html = ''
super().save(*args, **kwargs)
# 父类方法 只要执行 model.save() 或者 model.objects.create() save()方法就会执行
def __str__(self):
return self.title
写好数据库表以后,在终端执行以下命令
python manage.py makemigrations
python manage.py migrate
数据库相关字段说明
| 字段 | 作用 | 样例/选项 | 备注 |
|---|---|---|---|
| CharField | 短字符串(≤255) | max_length=120 |
必需给长度;对应库 varchar |
| TextField | 长文本 | 无长度限制 | 对应库 text/longtext |
| DateTimeField | 日期+时间 | auto_now=True 每次保存自动刷新 |
自动列别设为 datetime |
| IntegerField / PositiveIntegerField | 整数/正整数 | default=0 |
可配 validators 限制范围 |
| ImageField | 图片文件上传 | upload_to='covers/%Y/%m/' |
依赖 Pillow;存路径字符串 |
| FileField | 任意文件上传 | 同上 | 与 ImageField 唯一区别是不做图片验证 |
| ForeignKey | 多对一 | on_delete=models.CASCADE 级联删除 |
会自动产生 _id 后缀列 |
| BooleanField | 布尔 | default=False |
对应 tinyint(1) |
| EmailField / URLField | 带格式校验 | 也是 CharField 子类 | 自动正则验证 |
| SlugField | 带格式校验 | unique=True |
URL安全短标签 |