软件开发的流程
– 需求分析→设计说明→代码编写→程序测试→软件交付→客户验收→后期维护
软件需求分析需要解决什么问题?
当我们了解整个项目的开发设计之后,下一步是根据设计内容编写相应的功能代码。开始搭建网站之前,还需要确认使用哪种开发技术完成项目开发,比如网站的前后端是否分离,前后端分别采用哪些框架实现等。本项目采用前后端不分离模式开发,后端使用Django 3.0+MySQL 8.0实现,前端使用layui框架+jQuery实现网页设计。
前后端不分离模式要求前端开发人员提供静态的HTML模板,并且HTML模板实现简单的JavaScript脚本功能,如果涉及Ajax异步数据传输,则需要在开发阶段中与后端人员相互调试API接口的数据结构。
在终端窗口下执行命令
python manage.py startapp index
点击terminal(终端)输入指令后回车
部分情况下会出现错误,报错信息是
name 'os' is not defind
这种情况需要在主应用的配置文件(settings.py)中导入(import)相关包(os)
导入后再执行之前的命令:python manage.py startapp index
就可看到新多出了一个目录:index
依照之前的方法,在终端输入相关指令:
python manage.py startapp commodity
终端输入指令:
python manage.py startapp shopper
此处为我后期的项目,所以除开新建的应用之外还有多余的目录,之后会一一介绍。
整个项目共有7个文件夹和1个文件,每个文件夹和文件的功能说明如下:
babies文件夹与项目名相同,该文件夹下含有文件init .py、asgi.py、settings.py、urls.py和 wsgi.py
commodity是Django创建的项目应用(App),文件夹里含有init.py、 admin.py、apps.py、models.py、tests.py和views.py文件,它主要实现网站的商品列表页和商品详细页。
index是Django创建的项目应用(App),文件夹含有的文件与项目应用(App)commodity相同,它主要实现网站首页。
media是网站的媒体资源,用于存放商品的主图和详细介绍图。
pstatic是网站的静态资源,用于存放网站的静态资源文件,如css、JavaScript和网站界面图片。
shopper也是Django创建的项目应用(App),它主要实现网站的购物车页面、个人中心页面、用户登录注册页面、在线支付功能等。
templates用于存放HTML模板文件,即网站的网页文件。
manage.py是项目的命令行工具,内置多种方法与项目进行交互。在命令提示符窗口下,将路径切换到项目babys并输入python manage.py help,可以查看该工具的指令信息。
由于文件夹media,pstatic和templates是我们自行创建的,因此还需要在这些文件夹中添加前端提供的HTML静态模板,详细的添加说明如下:
由于文件夹media、pstatic和templates是我们自行创建的,Django在运行中无法识别这些文件夹的具体作用,因此,我们还需要在Django的配置文件settings.py中添加这些文件夹,使Django在运行中能识别这些文件夹的作用。
"""
Django settings for babies project.
Generated by 'django-admin startproject' using Django 3.2.7.
For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
import os
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/3.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-+k_skf&$q5j4=n!+oe-4&^hc7c5=9topc*d=vsi-xe3qz0eeca'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'index',
'commodity',
'shopper',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware', # 添加中间件LocaleMiddleware
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'babies.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'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_APPLICATION = 'babies.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'babies',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '127.0.0.1',
'PORT':'3306'
}
}
# Password validation
# https://docs.djangoproject.com/en/3.2/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/3.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
#静态资源配置
STATIC_URL = '/static/'
# 添加并设置配置属性STATICFILES_DIRS
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'pstatic'),)
#媒体资源配置
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
上述代码列出了13个配置信息,每个配置信息的说明如下:
用户密码:Django内置一套Auth认证系统,该系统具有用户认证和存储用户信息等功能,在创建用户的时候,将用户密码通过密钥进行加密处理,保证用户的安全性。
CSRF机制:该机制主要用于表单提交,防止窃取网站的用户信息来制造恶意请求。
会话Session:Session的信息存放在Cookie中,以一串随机的字符串表示,用于标识当前访问网站的用户身份,记录相关用户信息。
admin:内置的后台管理系统。
auth:内置的用户认证系统。
contenttypes:记录项目中所有model元数据(Django的ORM框架)。
sessions:Session会话功能,用于标识当前访问网站的用户身份,记录相关用户信息。
messages:消息提示功能。
staticfiles:查找静态资源路径。
在网站开发阶段中,我们经常对配置文件settings.py的INSTALLED_APPS、MIDDLEWARE、TEMPLATES、DATABASES和STATIC_URL进行配置,从而完成网站的开发过程,而配置属性DEBUG和ALLOWED_HOSTS则用于网站上线阶段。
上述配置属性是Django默认的功能配置,在实际开发中,可根据实际情况适当添加或删除相应的功能配置。
我们在项目babies添加了项目应用(App)index、commodity和shopper,但Django在运行过程中依然无法识别新增的项目应用(App),因此还需在Django的配置文件settings.py添加我们新增的项目应用(App)。在App列表INSTALLED_APPS分别添加index、commodity和shopper,添加信息如下:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'index',
'commodity',
'shopper',
]
在Web开发中,模板是一种较为特殊的HTML文档。这个HTML文档嵌入了一些能够让Django识别的变量和指令,然后由Django的模板引擎解析这些变量和指令,生成完整的HTML网页并返回给用户浏览。模板是Django里面的MTV框架模式的T部分,配置模板路径是为了告诉Django在解析模板时,如何找到模板所在的位置。
一般情况下,项目的根目录文件夹templates通常存放共用的模板文件,能为各个App的模板文件调用,这个模式符合代码重复使用的原则。我们已在项目babies创建了文件夹templates,它是用来存放Django模板文件的,在配置文件settings.py的配置属性TEMPLATES添加文件夹templates,配置信息如下:
如果是命令行创建的项目,由于没有templates文件夹,该配置文件中也无相关配置,需要做以下红框部分的配置,如果是使用PyCharm向导生成的项目,该配置已经完成,不用再手动配置。
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'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',
],
},
},
]
模板配置以列表格式表示,每个元素具有不同的含义,其含义说明如下:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware', # 添加中间件LocaleMiddleware
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
配置属性MIDDLEWARE的数据格式为列表类型,每个中间件的设置顺序是固定的,如果随意变更中间件很容易导致程序异常。每个中间件的说明如下:
SecurityMiddleware:内置的安全机制,保护用户与网站的通信安全。
SessionMiddleware:会话Session功能。
LocaleMiddleware:国际化和本地化功能。
CommonMiddleware:处理请求信息,规范化请求内容。
CsrfViewMiddleware:开启CSRF防护功能。
AuthenticationMiddleware:开启内置的用户认证系统。
MessageMiddleware:开启内置的信息提示功能。
XFrameOptionsMiddleware:防止恶意程序单击劫持。
默认情况下,Django支持使用PostgreSQL、MySQL、Sqlite3和Oracle数据库,如果要使用其他的数据库,如MSSQL或Redis等,需要自行安装第三方插件。配置属性DATABASES是设置项目所使用的数据库信息,不同的数据库需要设置不同的数据库引擎,数据库引擎用于实现项目与数据库的连接,Django提供了4种数据库引擎:
数据库引擎用于实现项目与数据库的连接,Django提供了4种数据库引擎:
‘django.db.backends.postgresql’
‘django.db.backends.mysql’
‘django.db.backends.sqlite3’
‘django.db.backends.oracle’
在创建项目的时候,Django已默认使用Sqlite3数据库,配置文件settings.py的配置信息如下所示
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
项目创建之后,如果没有修改配置属性DATABASES,当启动并运行Django时,Django会自动在项目的目录下创建数据库文件db.sqlite3,如下图所示:
由于项目babies需要使用MySQL数据库,因此在配置属性DATABASES中设置MySQL的连接信息。在配置数据库信息之前,首先确保本地计算机已安装MySQL数据库系统,然后再安装MySQL的连接模块,Django可以使用mysqlclient和pymysql模块实现MySQL连接。
mysqlclient模块可以使用pip指令安装,打开命令提示符窗口并输入安装指令
pip install mysqlclient
然后等待模板安装完成即可。
如果使用pip在线安装mysqlclient的过程中出现错误,还可以选择whl文件安装。在浏览器中访问
https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient
并下载与Python版本相匹配的mysqlclient文件。
完成mysqlclient模块的安装后,在项目的配置文件settings.py中配置MySQL数据库连接信息,代码如下:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'babies',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '127.0.0.1',
'PORT':'3306'
}
}
为了验证数据库连接信息是否正确,我们使用数据库可视化工具Navicat Premium打开本地的MySQL数据库。在本地的MySQL数据库创建数据库babies,如下图所示:
刚创建的数据库babies是一个空白的数据库,接着在PyCharm的Terminal界面下输入Django操作指令
python manage.pymigrate
来创建Django内置功能的数据表。因为Django自带了内置功能,如Admin后台系统、Auth用户系统和会话机制等功能,这些功能都需要借助数据表实现,所以该操作指令可以将内置的迁移文件生成数据表,如下图所示:
最后在数据库可视化工具Navicat Premium里查看数据库babies是否生成相应的10个数据表,如下图所示:
(我这里用的是后来的项目,所以就多了一些。)
使用mysqlclient连接MySQL数据库时,Django对mysqlclient版本有要求,打开Django的源码查看mysqlclient的版本要求,如下图所示:
一般情况下,使用pip安装mysqlclient模块都能符合Django的使用要求。如果在开发过程中发现Django提示mysqlclient过低,那么可以对Django的源码进行修改,将上图的if条件判断注释即可。
pymysql模块的安装使用pip在线安装即可,在命令提示符窗口下输入
pip install pymysql
指令并等待安装完成即可。
或者也可以通过Pycharm下载安装
import pymysql
pymysql.install_as_MySQLdb()
若要验证pymysql模块连接MySQL数据库的功能,建议读者先将mysqlclient模块卸载,这样能排除干扰因素,而验证方式与mysqlclient模块连接MySQL的验证方式一致。记得在验证之前,务必将数据库babies的数据表删除。
卸载mysqlclient模块指令:
pip uninstall pysqlclient
删除babies数据库里迁移生成的数据表
执行迁移命令,生成相应数据表
python manage.py migrate
查看表的回归
值得注意的是,如果读者使用的MySQL是8.0以上版本,在Django连接MySQL数据库时会提示django.db.utils.OperationalError的错误信息,这是因为MySQL 8.0版本的密码加密方式发生了改变,8.0版本的用户密码采用的是CHA2加密方式。
为了解决这个问题,我们通过SQL语句将8.0版本的加密方式改回原来的加密方式,这样可以解决Django连接MySQL数据库的错误问题。在MySQL的可视化工具中运行以下SQL语句:
# newpassword是已设置的用户密码
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'newpassword';
FLUSH PRIVILEGES;
Django除了支持PostgreSQL、SQLite3、MySQL和Oracle之外,还支持SQL Server和MongoDB的连接。由于不同的数据库有不同的连接方式,因此此处不过多介绍,本案例主要以MySQL连接为例,若需了解其他数据库的连接方式,可自行搜索相关资料。
静态资源的配置分别由配置属性STATIC_URL、STATICFILES_DIRS和STATIC_ROOT完成,默认情况下,Django只配置了配置属性STATIC_URL。一个项目在开发过程中肯定需要使用CSS和JavaScript文件,这些静态文件的存放路径主要在配置文件settings.py设置,Django默认的配置信息如下:
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
STATIC_URL = '/static/'
Django在调试模式(DEBUG=True)下只能识别项目应用(App)的static文件夹里面的静态资源,并且项目应用(App)的static文件夹在创建项目应用的时候不会自动生成,开发者还需要自行在项目应用(App)里面创建static文件夹,如果该文件夹改为其他名字,Django将无法识别;若将static文件夹放在babies的项目目录下,则Django也是无法识别的。
由于STATIC_URL的特殊性,在开发中会造成诸多不便,比如将静态文件夹存放在项目的根目录或者定义多个静态文件夹等。以项目babies为例,若想在网页上正常访问静态资源文件,可以将文件夹pstatic写入资源集合STATICFILES_DIRS,在配置文件settings.py添加并设置配置属性STATICFILES_DIRS,该属性以列表或元组的形式表示,设置方式如下:
# 添加并设置配置属性STATICFILES_DIRS
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'pstatic'),)
如果项目中有多个静态资源文件夹,并且这些文件夹不是在项目应用(App)里面;或者项目应用(App)的静态文件夹名称不是static,那么我们只需在配置属性STATICFILES_DIRS添加对应的文件夹即可。
静态资源配置还有STATIC_ROOT,其作用是在服务器上部署项目,实现服务器和项目之间的映射。STATIC_ROOT主要收集整个项目的静态资源并存放在一个新的文件夹,然后由该文件夹与服务器之间构建映射关系。STATIC_ROOT的配置如下:
STATIC_ROOT = os.path.join(BASE_DIR, 'AllStatic')
当项目的配置属性DEBUG设为True的时候,Django会自动提供静态文件代理服务,此时整个项目处于开发阶段,因此无须使用STATIC_ROOT。当配置属性DEBUG设为False的时候,意味着项目进入生产环境,Django不再提供静态文件代理服务,此时需要在项目的配置文件中设置STATIC_ROOT。
设置STATIC_ROOT需要使用Django操作指令collectstatic来收集所有的静态资源,这些静态资源会保存在STATIC_ROOT所设置的文件夹里。
一般情况下,STATIC_URL是设置静态文件的路由地址,如CSS样式文件、JavaScript文件以及常用图片等。对于一些经常变动的资源,通常将其存放在媒体资源文件夹,如用户头像、商品主图、商品详细介绍图等。
媒体资源和静态资源是可以同时存在的,而且两者可以独立运行,互不影响,而媒体资源只有配置属性MEDIA_URL和MEDIA_ROOT。以项目babies为例,新建的文件夹media是用来存放媒体资源文件的,在配置文件settings.py分别设置MEDIA_URL和MEDIA_ROOT,使Django在运行的时候能够自动识别媒体资源文件夹media,详细的设置方式如下:
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
配置属性设置后,还需要将media文件夹注册到Django里,让Django知道如何找到媒体文件,否则无法在浏览器中访问该文件夹的文件信息。打开babies文件夹的urls.py文件,为媒体文件夹media添加相应的路由地址,代码如下:
from django.contrib import admin
from django.urls import path, re_path
from django.views.static import serve
from django.conf import settings
urlpatterns = [
path('admin/', admin.site.urls),
# 配置媒体资源路由信息
re_path('media/(?P.*)' , serve,{'document_root':settings.MEDIA_ROOT}, name='media'),]
Django在配置url路由时,使用两种方式,一种是path,一种是re_path,唯一区别是re_path的第1个参数可以使用正则表达式,表达非常复杂的匹配逻辑。此处使用了正则表达式,大家大致理解即可,不必深究。
path(route
, view
, kwargs , name)
re_path(regex
, view
, kwargs , name)
标红的是必选参数,后2个是可选参数。
简单说明path()参数:
route: 是一个匹配URL的准则(类似正则表达式)。当Django响应一个请求时,它会从urlpatterns的第一项开始,按顺序依次匹配列表中的项,直到找到匹配的项。这些准则不会匹配GET和POST参数或域名。例如,URLconf在处理请求https://www.example.com/myapp/时,它会尝试匹配myapp/。处理请求https://www.example.com/myapp/?page=3 时,也只会尝试匹配myapp/。
view: 当 Django 找到了一个匹配的准则,就会调用这个特定的视图函数,并传入一个HttpRequest对象作为第一个参数,被“捕获”的参数以关键字参数的形式传入。
kwargs: 任意个关键字参数可以作为一个字典传递给目标视图函数。
name: 为你的URL取名能使你在 Django 的任意地方唯一地引用它,尤其是在模板中。这个有用的特性允许你只改一个文件就能全局地修改某个URL模式。
访问http://127.0.0.1:8000/static/css/main.css
访问http://127.0.0.1:8000/media/imgs/p1.jpg
我们已掌握了Django的项目创建、项目开发调试和基本的功能配置,本节讲述Django内置指令的详细作用,只有了解各个操作指令的功能,才能为我们的项目开发提供巨大的便利和帮助。
在PyCharm的Terminal或者Windows的CMD窗口(CMD窗口路径必须在项目路径下,如项目babies的路径)中输入指令python manage.py help并按回车键,即可看到相关的指令信息,以PyCharm的Terminal为例,如下图所示:
Django的操作指令共有30条,每条指令的说明这里以图片形式展示,如下图所示:
相关django知识:菜鸟教程