目录
[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的实战项目。
