需求分析原因:
需求分析方式:
需求分析内容:
提示:
为了方便项目管理及多人协同开发,我们根据需求将功能划分为不同的模块。
将来在项目中,每个模块都会对应一个子应用进行管理和解耦。
说明
• 前后端不分离的开发模式,是为了提高搜索引擎排名,即SEO。特别是首页,详情页和列表页。
• 页面需要局部刷新:我们会选择使用Vue.js来实现。
准备工作
创建商城虚拟环境
pipenv shell
安装Django框架
pip install django==2.2
创建商城Django工程
django-admin startproject shop
项目的环境分为开发环境和生产环境。
• 开发环境:用于编写和调试项目代码。
• 生产环境:用于项目线上部署运行。
• 准备配置文件目录
• 准备开发环境配置内容
配置数据库
# 此时需要先装 mysqlclient 库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 数据库引擎
'HOST': '127.0.0.1', # 数据库主机
'PORT': 3306, # 数据库端口
'USER': 'root', # 数据库用户名
'PASSWORD': 'root', # 数据库用户密码
'NAME': 'shop' # 数据库名字
},
}
商城数据缓存服务采用Redis数据库
安装django-redis扩展包
pip install django-redis
文档地址:https://django-redis-chs.readthedocs.io/zh_CN/latest/
配置Redis数据库
# Redis数据库配置
CACHES = {
"default": { # 默认
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/0", # 最后一个0是第0个数据库,redis共有16个数据库 0-15
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
},
"session": { # session session可以放在redis中,例如验证码,图形验证等等
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1", # session保存在第1个数据库中
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
},
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache" # engine保存在cache数据库中
SESSION_CACHE_ALIAS = "session"
default
:
session
:
SESSION_ENGINE
:
SESSION_CACHE_ALIAS
:
配置日志
# 日志配置 日志用于记录用户的访问记录
LOGGING = {
'version': 1,
'disable_existing_loggers': False, # 是否禁用已经存在的日志器
'formatters': { # 日志信息显示的格式
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'
},
'simple': {
'format': '%(levelname)s %(module)s %(lineno)d %(message)s'
},
},
'filters': { # 对日志进行过滤
'require_debug_true': { # django在debug模式下才输出日志
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': { # 日志处理方法
'console': { # 向终端中输出日志
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'file': { # 向文件中输出日志
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.join(BASE_DIR, 'logs/lgshop.log'), # 日志文件的位置
'maxBytes': 300 * 1024 * 1024, # 最大保存每个日志大小为300M
'backupCount': 10, # 总共保存10个日志文件 10*300M=3000M
'formatter': 'verbose'
},
},
'loggers': { # 日志器
'django': { # 定义了一个名为django的日志器
'handlers': ['console', 'file'], # 可以同时向终端与文件中输出日志
'propagate': True, # 是否继续传递日志信息
'level': 'INFO', # 日志器接收的最低日志级别
},
}
}
日志记录器的使用
import logging
# 创建日志记录器
logger = logging.getLogger('django')
# 输出日志
logger.debug('测试logging模块debug')
logger.info('测试logging模块info')
logger.error('测试logging模块error')
商城项目中需要使用静态文件,比如css,images,js等等
准备静态文件
在项目目录下新建一个static
目录
指定静态文件加载路径: dev.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static")
]
配置完成后,测试URL:http://127.0.0.1:8000/static/images/adv01.jpg
还有模板文件路径配置:
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',
],
},
},
]
• 准备apps包,用于管理所有应用(新建一个apps的python page文件)
• 在apps包下创建应用users(新的app模块在同一个python page文件下,方便管理)
python ../../manage.py startapp users
dev.py
配置
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'apps.users', # 在apps文件夹下的users模块进行app注册
]
或者可以改为
是否可以将注册users应用做的更加简便?
# Application definition
import sys
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 'apps.users', # 在apps文件夹下的users模块进行app注册
'users',
]
准备用户注册模板文件
{% load static %}
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>美多商城-注册title>
<link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}">
from django.shortcuts import render
from django.http import HttpResponse
from django.views import View
class RegisterView(View):
"""用户注册"""
def get(self, request):
return render(request, "register.html")
def post(self, request):
pass
总路由 shop/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('users/', include('users.urls')), # 如果当时注册users模块时候没有使用sys.path.insert导入路径,这里就需要改为 'apps.users.urls'
]
子路由apps/users/urls.py
# -*- encoding: utf-8 -*-
"""
@File : urls.py
@Time : 2020/7/26 20:34
@Author : chen
apps/users/urls.py 子路由,users模块的路由
"""
from django.urls import path, include
from . import views
urlpatterns = [
path('register/', views.RegisterView.as_view(), name='register'),
]
前端界面渲染:register.html
{% load static %}
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>LG商城-注册title>
<link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}">
head>
<body>
<div class="register_con">
<div class="l_con fl">
<a href="index.html" class="reg_logo"><img src="{% static 'images/1.png' %}">a>
<div class="reg_slogan">商品美 · 种类多 · 欢迎光临div>
<div class="reg_banner">div>
div>
<div class="r_con fr">
<div class="reg_title clearfix">
<h1>用户注册h1>
<a href="login.html">登录a>
div>
<div class="reg_form clearfix">
<form method="post" class="register_form">
<ul>
<li>
<label>用户名:label>
<input type="text" name="username" id="user_name">
<span class="error_tip">请输入5-20个字符的用户span>
li>
<li>
<label>密码:label>
<input type="password" name="password" id="pwd">
<span class="error_tip">请输入8-20位的密码span>
li>
<li>
<label>确认密码:label>
<input type="password" name="password2" id="cpwd">
<span class="error_tip">两次输入的密码不一致span>
li>
<li>
<label>手机号:label>
<input type="text" name="mobile" id="phone">
<span class="error_tip">请输入正确的手机号码span>
li>
<li>
<label>图形验证码:label>
<input type="text" name="image_code" id="pic_code" class="msg_input">
<img src="{% static 'images/pic_code.jpg'%}" alt="图形验证码" class="pic_code">
<span class="error_tip">请填写图形验证码span>
li>
<li>
<label>短信验证码:label>
<input type="text" name="sms_code" id="msg_code" class="msg_input">
<a href="javascript:;" class="get_msg_code">获取短信验证码a>
<span class="error_tip">请填写短信验证码span>
li>
<li class="agreement">
<input type="checkbox" name="allow" id="allow">
<label>同意”LG商城用户使用协议“label>
<span class="error_tip">请勾选用户协议span>
li>
<li class="reg_sub">
<input type="submit" value="注 册">
li>
ul>
form>
div>
div>
div>
<div class="footer no-mp">
<div class="foot_link">
<a href="#">关于我们a>
<span>|span>
<a href="#">联系我们a>
<span>|span>
<a href="#">招聘人才a>
<span>|span>
<a href="#">友情链接a>
div>
<p>CopyRight © 2016 北京LG商业股份有限公司 All Rights Reservedp>
<p>电话:010-****888 京ICP备*******8号p>
div>
body>
html>
修改时区:dev.py 开发版本配置文件
LANGUAGE_CODE = 'en-us'
# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
# USE_TZ = True
USE_TZ = False
注意 :此时运行项目可能会出现‘gbk’编码错误的提示,只需要修改debug.py
文件中332行的open(encoding='utf-8')
代码就行.
def get_traceback_html(self):
"""Return HTML version of debug 500 HTTP error page."""
with Path(CURRENT_DIR, 'templates', 'technical_500.html').open(encoding='utf-8') as fh:
t = DEBUG_ENGINE.from_string(fh.read())
c = Context(self.get_traceback_data(), use_l10n=False)
return t.render(c)
Django默认用户认证系统
django.contrib.auth
包含认证框架的核心和默认的模型。django.contrib.contenttypes
是Django内容类型系统,它允许权限与你创建的模型关联。Django认证系统中提供了用户模型类User保存用户的数据
from django.contrib.auth.models import AbstractUser # (源码)
django.contrib.auth.models.User
class User(AbstractUser):
"""
Users within the Django authentication system are represented by this
model.
Username and password are required. Other fields are optional.
"""
class Meta(AbstractUser.Meta):
swappable = 'AUTH_USER_MODEL'
User对象基本属性
– 创建用户(注册用户)必选: username、password
– 创建用户(注册用户)可选:email、first_name、last_name、last_login、date_joined、is_active 、is_staff、is_superuse
– 判断用户是否通过认证(是否登录):is_authenticated
创建用户(注册用户)的方法
user = User.objects.create_user(username, email, password, **extra_fields)
from django.contrib.auth import authenticate
user = authenticate(username=username, password=password, **kwargs)
users/models.py
定义User模型,继承自AbstractUser
from django.db import models
from django.contrib.auth.models import AbstractUser
# objects = models.Manager()
class User(AbstractUser):
"""自定义用户模型类"""
mobile = models.CharField(max_length=11, unique=True, verbose_name="手机号") # 父类中没有的字段
class Meta:
db_table = 'tb_users'
verbose_name = '用户'
verbose_name_plural = verbose_name
def __str__(self):
return self.username
注意:添加更改dev.py
开发版本配置文件再进行数据库映射
# Django.conf.global_settings.py中的源码第498行复制到dev.py配置文件进行修改映射到数据库中的表名
# AUTH_USER_MODEL = 'auth.User'
AUTH_USER_MODEL = 'users.User' # users是app模块