本章通过一个博客项目用户模块的开发,可以先熟悉下django各个组件和数据对象的简单处理方式,以及URL地址和访问资源的对应关系,对django项目有个宏观的了解。
本项目需求:
项目技术选型:
本章只是基于用户模块讲解下开发的基本流程,大部分功能后续讲解。
根据需求分析,项目各个模块划分如下:
|-- 项目主目录
|-- 根管理项目(自动创建)
|-- 用户模块
|-- 文章模块
|-- 评论模块
|-- 相册模块
|-- 留言板|私信模块
执行如下命令:
django-admin startproject personal_blog
进入项目主目录,我是使用的conda环境,需要先切换使用自己创建虚拟环境。
然后分别执行以下命令,创建各个模块:
django-admin startapp author
django-admin startapp article
django-admin startapp comment
django-admin startapp album
django-admin startapp message
这里创建的应用程序,是Django项目中实际业务执行处理模块,以用户模块为例,文件结构如下:
|-- personal_blog/
|-- personal_blog/
|-- author/
|-- migrations
|-- __init__.py
|-- __init__.py
|-- admin.py
|-- app.py
|-- models.py
|-- tests.py
|-- views.py
在Django项目中是通过根管理项目来管理所有接入的每个独立的业务模块的,在根管理项目中会配置访问资源的路由对象,来访问各个业务模块中的实际资源数据。
在创建好业务模块后,需要将业务模块注册给根管理项目,Django才能管理这些业务模块中包含的数据。
打开根管理项目(personal_blog)中的配置文件setting.py
,添加后面5行配置:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'author',
'article',
'comment',
'album',
'message',
]
参考上一章,执行下面命令
python manage.py createsuperuser
按照提示填写用户名密码等信息。
以用户模块为例,现在开始在用户模块定义Author类型。
打开author目录下的models.py
,代码如下:
from django.db import models
class Author(models.Model):
"""用户类型:博客作者"""
# 作者编号
id = models.AutoField(primary_key=True, verbose_name='作者编号')
# 登录账号
username = models.CharField(max_length=50, verbose_name='登录账号')
# 登录密码
password = models.CharField(max_length=50, verbose_name='登录密码')
# 真实姓名
realname = models.CharField(max_length=20, verbose_name='作者姓名')
class Meta:
# 后台管理系统中的名称
verbose_name_plural = '作者'
def __str__(self):
return self.realname
定义好Author模型后,把模型随影的表结构同步到数据库,生成表结构。
在Django中对数据模型和数据库表结构的映射关系进行来了封装,可通过执行命令完成数据库同步。
执行如下命令,会创建用户模块中Author模型的DDL SQL语句:
python manage.py makemigrations author
执行结果如下,说明DDL语句已经创建完成:
Migrations for 'author':
author/migrations/0001_initial.py
- Create model Author
执行如下命令,才会将数据同步至数据库:
python manage.py migrate
执行结果如下,说明模型已同步数据库,数据库中会有对应的表结构。
Operations to perform:
Apply all migrations: admin, auth, author, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying author.0001_initial... OK
Applying sessions.0001_initial... OK
Django对系统的用户模块进行自动封装,并提供了后台数据管理操作流程,可供开发测试使用。
打开用户模块,进入author目录中的admin.py
模块,将Author模型注册给后台管理模块,代码如下:
from django.contrib import admin
from .models import Author
admin.site.register(Author)
运行项目,打开后台管理系统,就可以看到Author模型已经在后台管理功能中,我们就可以直接在管理界面对Author模型对应的表进行增删改查操作。
如下图:
点击Author会进入Author表的数据管理界面,如下:
点击Add可以增加数据,如下:
右下角还有三个按钮,分别可以继续添加用户、并存继续编辑,保存并返回。添加两个后,回到管理界面,可以看到添加的数据,如下:
点击某个作者,可以修改或删除信息,如下:
还有其他基本增删改查按钮可自行学习。
下面来看下项目的配置文件setting.py
有哪些内容,分别代表什么意思。
"""
Django settings for personal_blog project.
Generated by 'django-admin startproject' using Django 4.1.
For more information on this file, see
https://docs.djangoproject.com/en/4.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.1/ref/settings/
"""
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
# 项目在当前计算机中路径,在其他配置可直接使用,开发过程不需要更改
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
# 安全密钥,作为内置认证模块中的混淆码使用,在开发过程中不需要更改
SECRET_KEY = 'django-insecure-q1kvncfzd!+9!u6-pt1^!!49*97a7nv)zt+^78--)h#yst4x6_'
# SECURITY WARNING: don't run with debug turned on in production!
# 调试模式,在开发过程不需要更改,部署到生产环境,则需要改为false
DEBUG = True
# 允许主机访问的列表,在开发过程不需要更改,如果需要更改IP地址段
ALLOWED_HOSTS = []
# Application definition
# Django框架管理的所有模块,通过startapp创建的应用模块需要被添加到这个配置中
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'author',
'article',
'comment',
'album',
'message',
]
# 中间件配置,如果需要在处理流程中添加额外的功能,则在这里添加
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# 根路由定义,在项目部署之后接受的URL路径,它首先会被ROOT_URLCONF定义的模块处理
ROOT_URLCONF = 'personal_blog.urls'
# 上下文模板路径配置,对公共静态页面进行处理,需要改动这里的配置
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
# WSGI协议配置,开发过程不需要修改
WSGI_APPLICATION = 'personal_blog.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
# 数据库连接配置,默认连接内置SQLite3数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
# 身份认证配置,开发过程不需要修改
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.1/topics/i18n/
# 语言环境配置,中文课改为zh-Hans
LANGUAGE_CODE = 'en-us'
# 时区配置,中国时间可改为Asia/Shanghai
TIME_ZONE = 'UTC'
USE_I18N = True # 国际化配置
USE_TZ = True # 默认启用时区配置
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.1/howto/static-files/
# 静态资源默认文件夹配置
STATIC_URL = 'static/'
# Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
# 定义一个没有指定主键的model时,Django将自动为您创建一个主键。主键设置为BigAutoField类型。
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
可以看到配置还是很多的,具体每个意思也注释了。同时也贴了噢诶之链接,如果想看完整的配置列表有哪些,可以访问网站https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/。查看具体的配置可以具体去网站查看。
网页模板是把数据展示到到页面上。
首先在用户模板创建templates
文件夹,并创建一个子文件夹,名称和模块名一致,主要用于隔离网页路径。然后再文件夹中创建HTML网页文件。最终项目文件结构如下:
|-- personal_blog/
|-- personal_blog/
|-- author/
|-- migrations
|-- __init__.py
|-- templates
|-- author
|-- index.html
|-- login.html
|-- register.html
|-- __init__.py
|-- admin.py
|-- app.py
|-- ...
首页index.html
代码如下:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户首页title>
head>
<body>
<h2>用户信息展示h2>
<div>
<h3>当前登录用户账号:{{request.session.author.username}}h3>
<h3>当前登录用户姓名:{{request.session.author.realname}}h3>
div>
body>
html>
注册页register.html
代码如下:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户注册title>
head>
<body>
<h2>新用户注册h2>
<h3 class="error_msg">
{{msg_info}}
h3>
<form action="#" method="POST">
{% csrf_token %}
<label for="username">账号:label>
<input type="text" name="username" id="username"><br/>
<label for="password">密码:label>
<input type="password" name="password" id="password"><br/>
<label for="realname">姓名:label>
<input type="text" name="realname" id="realname"><br/>
<input type="submit" value="立即注册">
form>
body>
html>
登录页login.html
代码如下:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录title>
head>
<body>
<h2>用户登录h2>
<h3 class="error_msg">
{{msg_info}}
h3>
<form action="#" method="POST">
{% csrf_token %}
<label for="username">账号:label>
<input type="text" name="username" id="username"><br />
<label for="password">密码:label>
<input type="password" name="password" id="password"><br />
<input type="submit" value="登录">
form>
body>
html>
也就是后端处理业务的逻辑,下面分别简单写下登录和注册功能。
打开视图处理模块personal_blog/author/views.py,添加注册和登录视图处理函数,代码如下:
from django.core.handlers.wsgi import WSGIRequest
from django.http import HttpResponse
from django.shortcuts import render
from .models import Author
def author_register(request: WSGIRequest) -> HttpResponse:
"""作者注册"""
if request.method == "GET":
return render(request, 'author/register.html', {})
elif request.method == "POST":
# 获取前端传递的数据
username = request.POST.get('username')
password = request.POST.get('password')
realname = request.POST.get('realname')
# 判断账号是否注册过
authors = Author.objects.filter(username=username)
if len(authors) > 0:
return render(request, 'author/register.html',
{'msg_code': 0, 'msg_info': '账号已经存在,请使用其他账号注册'})
# 创建作者对象
author = Author(username=username, password=password, realname=realname)
author.save()
# 返回登录页
return render(request, 'author/login.html',
{'msg_code': 0, 'msg_info': '账号注册成功'})
def author_login(request: WSGIRequest) -> HttpResponse:
"""作者登录"""
if request.method == "GET":
return render(request, 'author/register.html', {})
else:
username = request.POST.get('username')
password = request.POST.get('password')
# 查询是否存在该用户
try:
author = Author.objects.filter(username=username, password=password)
# 登录成功,记录登录状态
request.session['author'] = author
# 跳首页
print("----", request.session)
return render(request, 'author/index.html',
{'msg_code': 0, 'msg_info': '登录成功'})
except:
# 登录失败
return render(request, 'author/login.html',
{'msg_code': -1, 'msg_info': '账号或密码错误,请重新登录'})
因为在处理登录业务的时候基于Session的状态保持技术,所以需要在配置文件添加SESSION_SERIALIZER
配置,这样才可以在Session中添加对象数据。
打开项目的setting.py
文件,末尾添加:
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.BasePickleSerializer'
上面把所有资源都添加好后,下面就是添加网页和视图处理函数之间的映射关系。
在Django中,为了方便协同开发和维护大量的请求映射,将URL请求和视图处理函数之间的映射封装成路由,并按照上下级的方式进行路径匹配管理。
下面开始添加登录和注册的映射关系。
打开根管理项目的路由模块personal_blog/personal_blog/urls.py
,添加如下配置:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('author/', include('author.urls')), # 添加用户模块的主路由映射关联信息
]
然后再用户模块创建一个路由模块urls.py
,编辑代码如下:
__author__ = 'Ethan'
__version__ = 'v1.0.0'
from django.urls import path, include
from . import views
# 路由模块名称
app_name = 'author'
# 添加路由配置
urlpatterns = [
# 第一参数是路由,第二个参数是路由对应的视图函数
path('register/', views.author_register, name='register'),
path('login/', views.author_login, name='login'),
]
这样URL请求地址和对应的视图处理函数之间的映射关系就配置完成了。
接下来把配置的路由信息添加到网页视图的表单,就全部完成代码编写,可以测试了。
打开author/templates/author/login.html
,完善代码表单action如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
</head>
<body>
<h2>用户登录</h2>
<h3 class="error_msg">
<!-- 展示注册错误信息[模板语法] -->
{{msg_info}}
</h3>
<form action="{% url 'author:login' %}" method="POST">
<!-- 用户令牌认证[模板标签] -->
{% csrf_token %}
<label for="username">账号:</label>
<input type="text" name="username" id="username"><br />
<label for="password">密码:</label>
<input type="password" name="password" id="password"><br />
<input type="submit" value="登录">
</form>
</body>
</html>
打开author/templates/author/register.html
,完善代码表单action如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户注册</title>
</head>
<body>
<h2>新用户注册</h2>
<h3 class="error_msg">
<!-- 展示注册错误信息[模板语法] -->
{{msg_info}}
</h3>
<form action="{% url 'author:register' %}" method="POST">
<!-- 用户令牌认证[模板标签] -->
{% csrf_token %}
<label for="username">账号:</label>
<input type="text" name="username" id="username"><br/>
<label for="password">密码:</label>
<input type="password" name="password" id="password"><br/>
<label for="realname">姓名:</label>
<input type="text" name="realname" id="realname"><br/>
<input type="submit" value="立即注册">
</form>
</body>
</html>
进入项目主目录,执行命令:
python manage.py runserver
补充:
如果在pycharm里运行项目,想启用debug模式,需要点击右上角的项目名,点击edit configration按钮,添加additional options:--noreload
打开浏览器,访问注册页面http://127.0.0.1:8000/author/register/
,打开页面住下,填写用户信息,点击立即注册: