Django项目实战

目录

前言

引言

一、项目环境准备

二、项目环境配置

[1. 创建 Django 项目](#1. 创建 Django 项目)

[2. 配置 MySQL 连接](#2. 配置 MySQL 连接)

[3. 配置静态文件路径](#3. 配置静态文件路径)

[4. 配置 Redis 缓存](#4. 配置 Redis 缓存)

三、首页响应实现

[1. 创建应用:](#1. 创建应用:)

[2. 配置 URL 和视图](#2. 配置 URL 和视图)

四、用户注册功能实现

[1. 创建用户应用](#1. 创建用户应用)

[2. 响应注册页面](#2. 响应注册页面)

[3. 定义用户数据模型](#3. 定义用户数据模型)

[4. 后端数据校验](#4. 后端数据校验)

[5. 实现图片验证码](#5. 实现图片验证码)

[6. 实现短信验证码](#6. 实现短信验证码)

[7. 完善注册视图](#7. 完善注册视图)

[8. 校验用户名重复](#8. 校验用户名重复)

结语:


前言

从这篇文章开始,博主就会开始分享关于Django框架的项目实战这个项目其实是我之前就做好的,但是最近比较忙所有就没分享出来,关于这个Django项目的实战的话,最好希望各位看官能够自己真正动手去敲一下,我们这个项目是直接用python语言写的直接可以在pycharm里面进行操作的,好的接下来就让我们一起进入这篇文章的:

引言

在当今数字化时代,电商系统已成为互联网应用的重要组成部分。本文将详细介绍如何使用 Django 框架开发一个完整的电商系统,从环境搭建到用户注册功能的实现,让你一步步掌握电商系统开发的核心技术。同时我们的这个项目是MVT的架构的。

一、项目环境准备

在开始开发之前,我们需要准备好以下环境:

  • Python 3.8.10
  • Django 3.2
  • MySQL 5.7.40
  • Redis

二、项目环境配置

首先,我们需要创建一个 Django 项目并配置相关环境。

1. 创建 Django 项目

打开终端,执行以下命令创建名为 ShopSystem 的 Django 项目:

python 复制代码
django-admin startproject ShopSystem 
cd ShopSystem

2. 配置 MySQL 连接

settings.py中配置 MySQL 数据库连接信息:

python 复制代码
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'shop',  # 数据库名称
        'HOST': '127.0.0.1',  # 数据库主机
        'USER': 'root',  # 数据库用户名
        'PASSWORD': 'root',  # 数据库密码
        'PORT': 3306,  # 数据库端口
    }
}

3. 配置静态文件路径

settings.py中添加静态文件配置:

python 复制代码
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]  # 静态文件存放目录

4. 配置 Redis 缓存

settings.py中添加 Redis 缓存配置:

python 复制代码
# 配置Redis缓存数据库信息
CACHES = {
    # 默认使用的Redis数据库
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/0",  # Redis服务器地址和端口,使用0号数据库
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient"
        }
    },
    # 将session的数据保存位置修改到Redis中
    "session": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",  # 使用1号数据库存储session
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient"
        }
    },
}

# 修改session默认的存储机制
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
# 配置session要缓存的数据库引擎
SESSION_CACHE_ALIAS = "session"

三、首页响应实现

1. 创建应用:

创建一个名为contents的应用来处理首页响应:

python 复制代码
python manage.py startapp contents

记住这个是在pycharm里面的操作面板厘米进行操作的

2. 配置 URL 和视图

urls.py中配置首页路由:

python 复制代码
from django.urls import path
from . import views

urlpatterns = [
    path('', views.IndexView.as_view()),  # 首页路由
]

views.py中实现首页视图:

python 复制代码
from django.views import View
from django.shortcuts import render

class IndexView(View):
    '''
    响应首页
    '''
    def get(self, request):
        return render(request, 'index.html')  # 返回首页模板

记住这些操作都是在你生成的contents的包里面完成的,顺序不要弄错了

四、用户注册功能实现

1. 创建用户应用

创建一个名为users的应用来处理用户相关功能:

python 复制代码
python manage.py startapp users

2. 响应注册页面

urls.py中配置注册路由:

python 复制代码
from django.urls import path
from . import views

urlpatterns = [
    path('register/', views.RegisterView.as_view(), name='register'),  # 注册页面路由
]

views.py中实现注册视图:

python 复制代码
from django.views import View
from django.shortcuts import render

class RegisterView(View):
    '''
    用户注册
    '''
    def get(self, request):
        return render(request, 'register.html')  # 返回注册页面模板

3. 定义用户数据模型

使用 Django 的 auth 模块自定义用户认证模型:

python 复制代码
from django.db import models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    '''
    用户数据认证模型类
    '''
    mobile = models.CharField(max_length=11, unique=True)  # 添加手机号字段
    
    class Meta:
        db_table = 'user'  # 数据库表名

settings.py中配置自定义用户模型:

python 复制代码
# 配置自定义认证模型类
AUTH_USER_MODEL = 'users.User'

4. 后端数据校验

创建forms.py文件实现用户注册数据校验:

python 复制代码
from django import forms
import re

class RegisterForm(forms.Form):
    '''
    实现校验用户注册数据
    '''
    username = forms.CharField(min_length=5, max_length=15,
                               error_messages={
                                   "min_length": "用户名过短",
                                   "max_length": "用户名过长",
                                   "required": "用户名不允许为空",
                               })
    password = forms.CharField(min_length=6, max_length=20,
                               error_messages={
                                   "min_length": "密码过短",
                                   "max_length": "密码过长",
                                   "required": "密码不允许为空",
                               })
    password2 = forms.CharField(min_length=6, max_length=20,
                               error_messages={
                                   "min_length": "密码过短",
                                   "max_length": "密码过长",
                                   "required": "密码不允许为空",
                               })
    mobile = forms.CharField(min_length=11, max_length=11,
                               error_messages={
                                   "min_length": "手机号过短",
                                   "max_length": "手机号过长",
                                   "required": "手机号不允许为空",
                               })

    def clean_username(self):
        name = self.cleaned_data.get('username')
        if not re.match(r'^[A-Za-z0-9_]{5,15}$', name):
            self.add_error('username', '用户名数据不合法')
        return name
    
    def clean(self):
        clean_data = super().clean()
        passwd = clean_data.get('password')
        passwd2 = clean_data.get('password2')
        if passwd != passwd2:
            raise forms.ValidationError('两次密码不一致')
        return clean_data

在注册视图Views中添加数据校验逻辑:

python 复制代码
from django.http import HttpResponse
from .forms import RegisterForm

class RegisterView(View):
    '''
    用户注册
    '''
    def get(self, request):
        return render(request, 'register.html')

    def post(self, request):
        # 获取用户提交的数据,将数据传递给forms组件进行数据校验
        register_form = RegisterForm(request.POST)

        # 判断用户校验的数据是否合法
        if register_form.is_valid():
            return HttpResponse('注册成功')
        return HttpResponse('注册失败')

5. 实现图片验证码

创建一个名为verfications的应用来处理验证码功能:

python 复制代码
python manage.py startapp verfications

配置 Redis 缓存验证码:

python 复制代码
# 在settings.py中添加验证码缓存配置
CACHES = {
    # 缓存验证码
    "ver_code": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/2",  # 使用2号数据库存储验证码
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient"
        }
    },
}

实现图片验证码视图:

python 复制代码
from django.views import View
from django.http import HttpResponse
from django_redis import get_redis_connection
import random
import string
from PIL import Image, ImageDraw, ImageFont

class ImageCodeView(View):
    '''
    生成图片验证码
    '''
    def get(self, request, uuid):
        # 生成随机验证码
        code = ''.join(random.choices(string.ascii_letters + string.digits, k=4))
        
        # 创建图片
        image = Image.new('RGB', (120, 40), color=(240, 240, 240))
        draw = ImageDraw.Draw(image)
        font = ImageFont.load_default()
        
        # 绘制验证码
        for i, char in enumerate(code):
            draw.text((30 * i + 15, 10), char, font=font, fill=(random.randint(0, 100), random.randint(0, 100), random.randint(0, 100)))
        
        # 添加干扰线
        for _ in range(5):
            x1 = random.randint(0, 120)
            y1 = random.randint(0, 40)
            x2 = random.randint(0, 120)
            y2 = random.randint(0, 40)
            draw.line((x1, y1, x2, y2), fill=(random.randint(100, 255), random.randint(100, 255), random.randint(100, 255)))
        
        # 保存验证码到Redis
        redis_conn = get_redis_connection('ver_code')
        redis_conn.setex('image_%s' % uuid, 300, code)  # 验证码有效期5分钟
        
        # 返回图片
        from io import BytesIO
        buffer = BytesIO()
        image.save(buffer, 'PNG')
        return HttpResponse(buffer.getvalue(), content_type='image/png')

在前端页面中添加验证码标签:

html 复制代码
<li>
    <label>图形验证码:</label>
    <input type="text" name="image_code" id="pic_code" class="msg_input"
           v-model="image_code" @blur="check_image_code">
    <img v-bind:src="image_code_url" alt="图形验证码" class="pic_code"
         @click="generate_image_code">
    <span class="error_tip" v-show="error_image_code">请填写图形验证码</span>
</li>

6. 实现短信验证码

使用容联云通讯平台发送短信验证码,首先安装 SDK:

python 复制代码
pip install ronglian-sms-sdk

创建ronglianyun/ccp_sms.py实现短信发送功能:

python 复制代码
from ronglian_sms_sdk import SmsSDK
import json

accId = '#######'  # 容联云账户ID
accToken = '#########'  # 容联云账户授权令牌
appId = '##############'  # 容联云应用ID

# 单例模式
class CCP:
    _instance = None
    
    def __new__(cls, *args, **kwargs):
        # 确保单例
        if cls._instance is None:
            cls._instance = super().__new__(cls, *args, **kwargs)
        return cls._instance
    
    def send_message(self, mobile, datas):
        # 发送短信
        sdk = SmsSDK(accId, accToken, appId)
        tid = '1'  # 短信模板ID
        resp = sdk.sendMessage(tid, mobile, datas)
        resp = json.loads(resp)
        
        # 判断短信验证码是否发送成功
        if resp['statusCode'] == "000000":
            # 短信验证码发送成功
            return 0
        else:
            return -1
        
send_code = CCP()  # 创建单例对象

自己去自己的容连云账号上把对应的信息填上去,这里就不填博主自己的内容了.

在前端页面中添加短信验证码标签:

python 复制代码
<li>
    <label>短信验证码:</label>
    <input type="text" name="sms_code" id="msg_code" class="msg_input"
           v-model="sms_code" @blur="check_sms_code">
    <a @click="send_sms_code" class="get_msg_code">获取短信验证码</a>
    <span class="error_tip" v-show="error_sms_code">请填写短信验证码</span>
</li>

实现短信验证码视图:

python 复制代码
from django.views import View
from django.http import JsonResponse, HttpResponseForbidden
from django_redis import get_redis_connection
import random
from . import constants
from utils.response_code import RETCODE

class SmsCodeView(View):
    '''
    发送短信验证码
    1、校验图片验证码(验证码是否正确,验证码是否在有效期内)
    2、图片验证码正确,删除数据库中的图片验证码
    3、生成短信验证码数据
    4、调用发送短信验证码的功能
    5、保存短信验证码
    
    在接收发送短信验证码的期间,不允许重复的调用该视图
    '''
    def get(self, request, mobile):
        # 接收参数: uuid,用户输入的图片验证码
        uuid = request.GET.get('uuid')
        image_code_clinet = request.GET.get('image_code')

        # 校验请求中的数据是否完整
        if not all([uuid, image_code_clinet]):
            return HttpResponseForbidden("缺少必要的参数")

        # 从Redis数据库中获取到该用户生成的图片验证码
        redis_conn = get_redis_connection('ver_code')
        image_code_server = redis_conn.get('image_%s' % uuid)
        
        # 从redis数据库中获取手机号的标记数据
        send_flag = redis_conn.get('send_%s' % mobile)
        
        # 判断该手机号是否被标记,如果被标记,不允许发送短信
        if send_flag:
            return JsonResponse({'code': RETCODE.THROTTLINGERR, 'errmsg': '发送短信验证码过于频繁'})
        
        # 验证码是否在有效期内
        if image_code_server is None:
            return JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '图片验证码失效'})

        # 判断图片验证码是否正确
        image_code_server = image_code_server.decode()
        if image_code_server.lower() != image_code_clinet.lower():
            return JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '图片验证码输入有误'})

        # 图片验证码正确,发送短信验证码
        # 生成短信验证码
        sms_code = "%06d" % random.randint(0, 999999)
        print(f"短信验证码: {sms_code}")  # 测试阶段打印验证码,实际生产环境应删除
        
        # 保存短信验证码
        redis_conn.setex("code_%s" % mobile, 300, sms_code)  # 验证码有效期5分钟
        # 保存该手机号的标记
        redis_conn.setex('send_%s' % mobile, 60, 1)  # 1分钟内不允许重复发送
        
        # 发送短信验证码(测试阶段注释掉,避免真的发送短信)
        # from ronglianyun.ccp_sms import send_code
        # send_code.send_message(mobile, (sms_code, 5))
        
        return JsonResponse({'code': RETCODE.OK, 'errmsg': '短信验证码发送成功'})

7. 完善注册视图

添加短信验证码校验逻辑:

python 复制代码
from django.shortcuts import render, redirect
from django.http import HttpResponse
from .forms import RegisterForm
from django_redis import get_redis_connection
from .models import User

class RegisterView(View):
    '''
    用户注册
    '''
    def get(self, request):
        return render(request, 'register.html')

    def post(self, request):
        # 获取用户提交的数据,将数据传递给forms组件进行数据校验
        register_form = RegisterForm(request.POST)
        
        # 判断用户校验的数据是否合法
        if register_form.is_valid():
            username = register_form.cleaned_data.get('username')
            password = register_form.cleaned_data.get('password')
            mobile = register_form.cleaned_data.get('mobile')

            # 判断短信验证码是否正确,正确:注册成功;用户数据保存到数据库中
            # 从redis中获取到生成的短信验证码
            redis_conn = get_redis_connection('ver_code')
            sms_code_server = redis_conn.get("code_%s" % mobile)

            # 获取到用户输入的短信验证码
            sms_code_client = request.POST.get('sms_code')

            # 判断验证码是否在有效期内
            if sms_code_server is None:
                return render(request, 'register.html', {'sms_code_errmsg': '短信验证码失效'})
            
            # 判断验证码是否正确
            if sms_code_client != sms_code_server.decode():
                return render(request, 'register.html', {'sms_code_errmsg': '短信验证码错误'})

            # 验证码正确,将用户的数据保存到数据库中
            user = User.objects.create_user(username=username, password=password, mobile=mobile)
            
            # 注册成功,响应到登录页面
            return redirect('/login/')
        else:
            # 用户数据不合法
            # 从forms组件中获取到数据异常信息
            context = {'forms_errmsg': register_form.errors}
            return render(request, 'register.html', context=context)

修改前端注册页面,添加错误提示:

html 复制代码
<li>
    <label>短信验证码:</label>
    <input type="text" name="sms_code" id="msg_code" class="msg_input"
           v-model="sms_code" @blur="check_sms_code">
    <a @click="send_sms_code" class="get_msg_code">[[ sms_code_tip ]]</a>
    <span class="error_tip" v-show="error_sms_code">请填写短信验证码</span>
    <!-- 获取后端校验短信验证码的异常信息 -->
    {% if sms_code_errmsg %}
    <span style="color: red">{{ sms_code_errmsg }}</span>                            
    {% endif %} 
</li>
html 复制代码
<li class="reg_sub">
    <input type="submit" value="注 册">
    <!-- 获取后端校验表单数据的异常信息 -->
    {% if forms_errmsg %}
    <span style="color: red">{{ forms_errmsg }}</span>
    {% endif %}
</li>

8. 校验用户名重复

添加用户名重复校验视图:

python 复制代码
from django.views import View
from django.http import JsonResponse
from .models import User

class UsernameCountView(View):
    '''
    判断用户名是否重复
    '''
    def get(self, request, username):
        # 根据参数从数据库获取用户数据
        count = User.objects.filter(username=username).count()
        return JsonResponse({'code': 200, 'errmsg': 'OK', 'count': count})

结语:

好的,今天的分享就先到这里了,后面的内容我也会继续在这里进行更新的,这篇文章如果还有哪些不足之处也欢迎各位大佬进行斧正。也希望大家可以多多支持博主,接下来我会继续更新我的这个Django的实战项目。

相关推荐
MAOX78915 分钟前
基于python的web系统界面登录
前端·python
一颗红心丶1 小时前
Windows系统上离线部署Python运行飞桨(PaddlePaddle) OCR服务
windows·python·paddlepaddle
我爱音乐yyy1 小时前
pythonday50
pytorch·python·深度学习
子恒20051 小时前
警惕GO的重复初始化
开发语言·后端·云原生·golang
daiyunchao1 小时前
如何理解"LLM并不理解用户的需求,只是下一个Token的预测,但他能很好的完成任务,比如写对你想要的代码"
后端·ai编程
white.tie1 小时前
一个手机请求头的随机库
开发语言·javascript·python
Mikhail_G1 小时前
Python初学者入门指南
大数据·运维·开发语言·python·数据分析
Android洋芋1 小时前
SettingsActivity.kt深度解析
后端
onejason2 小时前
如何利用 PHP 爬虫按关键字搜索 Amazon 商品
前端·后端·php
和我乘风破浪2 小时前
iOS自动化录屏在Chrome浏览器打不开处理方法
python·测试