首页 > 其他分享 >【Django开发】前后端分离美多商城项目第2篇:项目配置(附代码,文档已分享)

【Django开发】前后端分离美多商城项目第2篇:项目配置(附代码,文档已分享)

时间:2024-01-30 21:32:13浏览次数:32  
标签:meiduo 项目 redis 用户 django 文档 日志 Django

本系列文章md笔记(已分享)主要讨论django商城项目开发相关知识。本项目利用Django框架开发一套前后端不分离的商城项目(4.0版本)含代码和文档。功能包括前后端不分离,方便SEO。采用Django + Jinja2模板引擎 + Vue.js实现前后端逻辑,Nginx服务器(反向代理)Nginx服务器(静态首页、商品详情页、uwsgi服务器(美多商场业务场景),后端服务:MySQL、Redis、Celery、RabbitMQ、Docker、FastDFS、Elasticsearch、Crontab,外部接口:容联云、QQ互联、支付宝。

全套笔记和代码自取在个人博客: https://www.666mao.com/article?articleId=3

感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~


共 11 章,63 子模块

项目准备

配置

1. 修改settings/dev.py 文件中的路径信息

我们将Django的应用放到了 工程目录/meiduo_mall/apps目录下,如果创建一个应用,比如users,那么在配置文件的INSTALLED_APPS中注册应用应该如下:

INSTALLED_APPS = [
    ...
    'meiduo_mall.apps.users.apps.UsersConfig',
]

为了还能像如下方式简便的注册引用,我们需要向Python解释器的导包路径中添加apps应用目录的路径。

INSTALLED_APPS = [
    ...
    'users.apps.UsersConfig',
]

我们将配置文件改为放在settings子目录下,所以 配置文件中的BASE_DIR指向的变为了meiduo/meiduo_mall/meiduo_mall

使用sys.path添加<BASE_DIR>/apps目录,即可添加apps应用的导包路径。

  
  
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
  
  
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

  
  
# 添加导包路径
  
  
import sys
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))

2. INSTALLED_APPS

在INSTALLED_APPS中添加rest_framework

INSTALLED_APPS = [
    ...
    'rest_framework',
]

3. 数据库

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '127.0.0.1',  # 数据库主机
        'PORT': 3306,  # 数据库端口
        'USER': 'meiduo',  # 数据库用户名
        'PASSWORD': 'meiduo',  # 数据库用户密码
        'NAME': 'meiduo_mall'  # 数据库名字
    }
}

注意:

记得在meiduo/meiduo_mall/__init__.py文件中添加

import pymysql

pymysql.install_as_MySQLdb()

4. Redis

安装django-redis,并配置

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://10.211.55.5:6379/0",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },
    "session": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://10.211.55.5:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "session"

除了名为default的redis配置外,还补充了名为session的redis配置,分别使用两个不同的redis库。

同时修改了Django的Session机制使用redis保存,且使用名为'session'的redis配置。

此处修改Django的Session机制存储主要是为了给Admin站点使用。

关于django-redis 的使用,说明文档可见http://django-redis-chs.readthedocs.io/zh_CN/latest/

5. 本地化语言与时区

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

6. 日志

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': 'DEBUG',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
        'file': {  # 向文件中输出日志
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(os.path.dirname(BASE_DIR), "logs/meiduo.log"),  # 日志文件的位置
            'maxBytes': 300 * 1024 * 1024,
            'backupCount': 10,
            'formatter': 'verbose'
        },
    },
    'loggers': {  # 日志器
        'django': {  # 定义了一个名为django的日志器
            'handlers': ['console', 'file'],  # 可以同时向终端与文件中输出日志
            'propagate': True,  # 是否继续传递日志信息
            'level': 'DEBUG',  # 日志器接收的最低日志级别
        },
    }
}

7. 异常处理

修改Django REST framework的默认异常处理方法,补充处理数据库异常和Redis异常。

新建utils/exceptions.py

from rest_framework.views import exception_handler as drf_exception_handler
import logging
from django.db import DatabaseError
from redis.exceptions import RedisError
from rest_framework.response import Response
from rest_framework import status

  
  
# 获取在配置文件中定义的logger,用来记录日志
  
  
logger = logging.getLogger('django')

def exception_handler(exc, context):
    """
    自定义异常处理
    :param exc: 异常
    :param context: 抛出异常的上下文
    :return: Response响应对象
    """
    # 调用drf框架原生的异常处理方法
    response = drf_exception_handler(exc, context)

    if response is None:
        view = context['view']
        if isinstance(exc, DatabaseError) or isinstance(exc, RedisError):
            # 数据库异常
            logger.error('[%s] %s' % (view, exc))
            response = Response({'message': '服务器内部错误'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)

    return response

配置文件中添加

REST_FRAMEWORK = {
    # 异常处理
    'EXCEPTION_HANDLER': 'meiduo_mall.utils.exceptions.exception_handler',
}

用户部分

用户模型类

Django提供了认证系统

Django认证系统同时处理认证和授权。简单地讲,认证验证一个用户是否它们声称的那个人,授权决定一个通过了认证的用户被允许做什么。 这里的词语“认证”同时指代这两项任务,即Django的认证系统同时提供了认证机制和权限机制。

Django的认证系统包含:

  • 用户
  • 权限:二元(是/否)标志指示一个用户是否可以做一个特定的任务。
  • 组:对多个用户运用标签和权限的一种通用的方式。
  • 一个可配置的密码哈希系统
  • 用户登录或内容显示的表单和视图
  • 一个可插拔的后台系统

Django默认提供的认证系统中,用户的认证机制依赖Session机制,我们在本项目中将引入JWT认证机制,将用户的身份凭据存放在Token中,然后对接Django的认证系统,帮助我们来实现:

  • 用户的数据模型
  • 用户密码的加密与验证
  • 用户的权限系统

Django用户模型类

Django认证系统中提供了用户模型类User保存用户的数据,默认的User包含以下常见的基本字段:

  • username

必选。 150个字符以内。 用户名可能包含字母数字,_@+ .-个字符。在Django更改1.10:max_length从30个字符增加到150个字符。

  • first_name

可选(blank=True)。 少于等于30个字符。

  • last_name

可选(blank=True)。 少于等于30个字符。

  • email

可选(blank=True)。 邮箱地址。

  • password

必选。 密码的哈希及元数据。 (Django 不保存原始密码)。 原始密码可以无限长而且可以包含任意字符。

  • groups

Group 之间的多对多关系。

  • user_permissions

Permission 之间的多对多关系。

  • is_staff

布尔值。 指示用户是否可以访问Admin 站点。

  • is_active

布尔值。 指示用户的账号是否激活。 我们建议您将此标志设置为False而不是删除帐户;这样,如果您的应用程序对用户有任何外键,则外键不会中断。它不是用来控制用户是否能够登录。 在Django更改1.10:在旧版本中,默认is_active为False不能进行登录。

  • is_superuser

布尔值。 指定这个用户拥有所有的权限而不需要给他们分配明确的权限。

  • last_login

用户最后一次登录的时间。

  • date_joined

账户创建的时间。 当账号创建时,默认设置为当前的date/time。

常用方法:
  • set_password(raw_password)

设置用户的密码为给定的原始字符串,并负责密码的。 不会保存User 对象。当Noneraw_password 时,密码将设置为一个不可用的密码。

  • check_password(raw_password)

如果给定的raw_password是用户的真实密码,则返回True,可以在校验用户密码时使用。

管理器方法:

管理器方法即可以通过User.objects. 进行调用的方法。

  • create_user(username, email=None, password=None, **extra_fields)

创建、保存并返回一个User对象。

  • create_superuser(username, email, password, **extra_fields)

create_user() 相同,但是设置is_staffis_superuserTrue

创建自定义的用户模型类

Django认证系统中提供的用户模型类及方法很方便,我们可以使用这个模型类,但是字段有些无法满足项目需求,如本项目中需要保存用户的手机号,需要给模型类添加额外的字段。

Django提供了django.contrib.auth.models.AbstractUser用户抽象模型类允许我们继承,扩展字段来使用Django认证系统的用户模型类。

我们现在在meiduo/meiduo_mall/apps中创建Django应用users,并在配置文件中注册users应用。

在创建好的应用models.py中定义用户的用户模型类。

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

我们自定义的用户模型类还不能直接被Django的认证系统所识别,需要在配置文件中告知Django认证系统使用我们自定义的模型类。

在配置文件中进行设置

AUTH_USER_MODEL = 'users.User'

AUTH_USER_MODEL 参数的设置以点.来分隔,表示应用名.模型类名

注意:Django建议我们对于AUTH_USER_MODEL参数的设置一定要在第一次数据库迁移之前就设置好,否则后续使用可能出现未知错误。

执行数据库迁移

python manage.py makemigrations
python manage.py migrate

注册

创建好用户模型类后,我们开始来实现第一个业务逻辑——用户注册。

设计接口的思路

  • 分析要实现的业务逻辑,明确在这个业务中需要涉及到几个相关子业务,将每个子业务当做一个接口来设计。

  • 分析接口的功能任务,明确接口的访问方式与返回数据:

    • 接口的请求方式,如GET 、POST 、PUT等
    • 接口的URL路径定义
    • 需要前端传递的数据及数据格式(如路径参数、查询字符串、请求体表单、JSON等)
    • 返回给前端的数据及数据格式

在前后端分离的应用模式中,我们作为后端开发人员设计后端接口时,可以不用考虑返回给前端数据后,前端如何处理,这是前端开发人员的工作,我们只需明确我们要保存的或者要返回的是什么数据即可。

明确上述每一点后,即可开始编写接口。

注册业务接口分析

在用户注册中,需要实现以下接口:

  • 图片验证码
  • 短信验证码
  • 用户名判断是否存在
  • 手机号判断是否存在
  • 注册保存用户数据

图片验证码、短信验证码考虑到后续可能会在其他业务中也用到,因此我们将图片验证码独立,创建一个新应用verifications,在此应用中实现图片验证码、短信验证码

设计接口的思路

  • 分析要实现的业务逻辑,明确在这个业务中需要涉及到几个相关子业务,将每个子业务当做一个接口来设计。

  • 分析接口的功能任务,明确接口的访问方式与返回数据:

    • 接口的请求方式,如GET 、POST 、PUT等
    • 接口的URL路径定义
    • 需要前端传递的数据及数据格式(如路径参数、查询字符串、请求体表单、JSON等)
    • 返回给前端的数据及数据格式

在前后端分离的应用模式中,我们作为后端开发人员设计后端接口时,可以不用考虑返回给前端数据后,前端如何处理,这是前端开发人员的工作,我们只需明确我们要保存的或者要返回的是什么数据即可。

明确上述每一点后,即可开始编写接口。

注册业务接口分析

在用户注册中,需要实现以下接口:

  • 图片验证码
  • 短信验证码
  • 用户名判断是否存在
  • 手机号判断是否存在
  • 注册保存用户数据

图片验证码、短信验证码考虑到后续可能会在其他业务中也用到,因此我们将图片验证码独立,创建一个新应用verifications,在此应用中实现图片验证码、短信验证码

标签:meiduo,项目,redis,用户,django,文档,日志,Django
From: https://blog.51cto.com/u_13578013/9494281

相关文章

  • idea-Project Structre设置 Sources:显示项目的目录资源,那些是项目部署的时候需要的目
    idea-ProjectStructre设置ProjectStructreProject Projectname:定义项目的名称;ProjectSDK:设置该项目使用的JDK,也可以在此处新添加其他版本的JDK;Projectlanguagelevel:这个和JDK的类似,区别在于,假如你设置了JDK1.8,却只用到1.6的特性,那么这里可以设置语言等级为1.6,这个是......
  • 如何做好一个信息系统项目经理,一个项目经理的个人体会和经验总结(二)
    前言之前文章讲了在项目开始阶段,作为一个信息系统项目经理应该做好哪些内容(参见如何做好一个信息系统项目经理,一个项目经理的个人体会和经验总结(一)),这一篇我们继续聊聊在项目开发阶段,项目经理又需要做好哪些事情呢?......
  • [word] 100份PDF文档转换成Word,我只要10秒,不花钱就能搞定
    关注职场办公,分享实用干货,洞察科技资讯,这里是「职场科技范」。当领导发了100份PDF文档给你,并且要求在下班前整理成Word给他,你是不是已经准备提桶跑路了?而我只要10秒就能轻松搞定。方法一、Ctrl+C/V最简单的方法肯定是复制粘贴,操作简单,转换结果就是,内容基本完整保留,排版开始混乱,图片......
  • [word] word文档怎么自动编号?
    word文档怎么自动编号?在使用Word自动编号的时候,相信伙伴们遇到过各种问题,比如说编号间隙太长无法调整,总是更喜欢自己手动输入,当然这个方法的效率低于自动编号。下面小Q分享几个常见的自动编号问题。1.右键调整列表缩进,修改文本缩进,可以改为0,编号之后选择【不特别标注】。2.选中文本......
  • [职场] 通信专家求职简历项目经验范文(10篇)
    通信专家在找工作做简历的时候,经常不知道求职简历中的项目经验板块怎么写,下面是简历网小编整理的适合通信专家在做简历时写的项目经验范文10篇!希望能帮助到大家。范文1项目经历项目周期:2018.04-至今(5年1个月)参与角色:项目经理项目名称:沃尔沃汽车描述由瑞典政府资助的车联网无线通......
  • vue项目适配修改
    一、安装适配插件1、[email protected] 2、在根目录添加文件postcss.config.js,内容如下module.exports={plugins:{'postcss-px-to-viewport':{unitToConvert:'px',//需要转换的单位viewportWidth:1920,//视口宽度,等同......
  • 利用Jenkins自动构建并部署项目
    利用Jenkins自动构建并部署项目:https://blog.csdn.net/li532788/article/details/88031076?ops_request_misc=&request_id=&biz_id=102&utm_term=sudo%20rpm%20--import%20https://pkg.&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~defaul......
  • three学习-vscode-创建项目01
    安装node之后,使用vscode打开自己创建的一个文件夹1、创建我们的项目目录存放的文件夹study01再vscode中打开创建的文件夹2、创建vite支持环境npminitvite@latest输入y输入项目名称:studyapp01框架选择 3、进入项目,安装依赖,运行项目cdstudyapp01npminstallnpm......
  • springboot项目启动时候初始化一些数据
    最近在看缓存预热的问题的时候,其中有一种解决方法,就是在项目启动的时候就自动加载到缓存中那缓存我就不说了,就关于项目启动的时候,可以初始化一些数据,以下为两种初始化的方式,可以参考1、编写类去实现ApplicationRunner接口,实现run()方法。2、编写类去实现CommandLineRunner接口,......
  • 7000字详解Spring Boot项目集成RabbitMQ实战以及坑点分析
    本文给大家介绍一下在SpringBoot项目中如何集成消息队列RabbitMQ,包含对RibbitMQ的架构介绍、应用场景、坑点解析以及代码实战。最后文末有免费领取龙年红包封面以及腾讯云社区答题领奖福利,欢迎大家领取。我将使用waynboot-mall项目作为代码讲解,项目地址:https://github.co......