一、团队协作、项目初始化
1、小组担任人在本地新建一个Djang项目
// 新建项目
django-admin startproject inventory_management_django_system
2、在gitee上新建库房,将本地项目上传到新建的gitee库房中
- 这部分参阅博客:blog.csdn.net/qq_48278620…
3、团队成员协作开发(前提:团队成员电脑上已装置Git和Gitee账号已用邮箱注册)
-
项目办理员在库房分支办理中手动添加分支【分支称号】
-
在想要放置项意图文件夹里右键,履行git init指令进行初始化
-
履行git clone 【项目地址】 把项目克隆到本地
-
成员进入项目文件夹,在此目录下顺次履行以下几条指令:
git checkout 【分支称号】 git add . git commit -m "描绘内容“ git pull --rebase origin 【分支称号】 git push -u origin 【分支称号】
此刻成员的本地项目便与库房中属于自己的分支相关联了
- 进入PythonCharm,下载Gitee插件,项目更改后能够将项目右键挑选提交与推送到自己的分支
- 假如推送时出现下面的错误提示:
并且输入暗码后依然像下面显示的那样,推送失利:
此刻测验履行以下指令,铲除本地的gitee用户名和暗码:
git config --system --unset credential.helper
假如依然推送失利,重启PyCharm,从头进行推送。
二、数据库建表作业
1、创立并注册这部分模块的app
- 创立app:
//创立app(app的名字自界说)
python .\manage.py startapp app01
- 注册app(settings.py里的INSTALLED_APPS代码块如图修正):
- 运转这个初始化项目:
//运转Django项目
python .\manage.py runserver
2、创立并衔接数据库
- 在pgAdmin 4手动创立数据库:
- 项目设置文件settings.py中更改DATABASE部分代码如下:
3、在创立表之前观察后台办理体系需求完结的功用
- 本体系为一个简略的后台办理体系,可为企业供给后台办理服务,首要包括体系用户的登录注册、库存办理、订单办理、暂时订单、用户办理、数据可视化六大板块的功用。
- 其间体系用户分为两类,一类是高权限的超级办理员,另一类是低权限的一般办理员,其间一般办理员不具备用户办理功用。体系用户既是体系的办理员,也是订单的担任人,每个办理员担任自己的订单与暂时订单。
- 在注册页面默认注册低权限的一般办理员,超级办理员可在用户办理板块中对体系的用户权限进行修正。
- 每个订单/暂时订单会经过userId这个特点与用户绑定,相似于公司中某个订单是谁担任的,添加订单/暂时订单时经过验证现在所登录信息来做到绑定。
- 数据可视化模块中,首要对公司近十年具体的出售额数据进行可视化,里边的数据经过sql句子初始化在数据库表里边,前端无需供给,后端也无法更改,相当于一个独立静态的模块,无数据的改动。
登录注册:(触及体系用户user表)——完结体系的登录、登录之后所登录用户信息的回来、体系用户的注册
库存办理:(触及物品ware表)——完结对库存物品的增、删、改、查,以及挑选物品参加订单或许暂时订单
订单办理:(触及订单order表、体系用户user表、暂时订单cart表)——完结对订单的删、查
暂时订单:(触及暂时订单cart表、订单order表、体系用户user表)——完结暂时订单的删去、修正,以及挑选暂时订单参加订单库房
用户办理:(触及体系用户user表)——完结对体系用户的增、删、改、查(留意:只有高权限的体系用户才具有这项功用,在登录时便可进行验证所登录用户是否为高权限用户;【添加用户】与【注册用户】实质是同一个功用)
数据可视化:(触及公司出售额sales表)——完结公司近十年每年具体出售数据的可视化
4、项目中需求创立的表
从上面展现的六大模块功用能够看出,项目总共触及五个表,分别是体系用户user表、物品ware表、订单order表、暂时订单cart表、公司出售额sales表。
其间每个表的特点介绍如下:
- 体系用户user表:【userId,userName,userPassword,userPower,createTime,updateTime
- 物品ware表:【wareId,wareName,warePower,wareCount,createTime,updateTime】
- 订单order表:【orderId,userId,userName,wareId,wareName,wareCount,createTime】
- 暂时订单cart表:【orderId,userId,userName,wareId,wareName,wareCount,createTime,updateTime】
- 公司出售额sales表:【salesId,yearName,yearSales,yearEvents,monthSales,wareSales】
留意:订单order表与暂时订单cart表实质是相同的表,但它们的区别是,挑选物品参加订单时,库房中对应的物品会削减,而挑选物品参加暂时订单时,库房中对应的物品不会削减。
5、进行表的创立
在项目app文件夹里边的models.py文件进行表模型的构造:
(有关这部分的文档可见:docs.djangoproject.com/zh-hans/4.1…)
本项意图models.py如下:
from django.db import models
from django.db.models import Max, Count
# 导入`connection`用于履行原生sql句子
from django.db import connection
# Create your models here.
# 体系用户user表:【userId,userName,userPassword,userPower,createTime,updateTime】
class User(models.Model):
# primary_key=True表明该特点为该表的主键,暗示null=False和unique=True。
id = models.AutoField(primary_key=True)
userId = models.CharField(max_length=20)
userName = models.CharField(unique=True, max_length=15)
userPassword = models.CharField(max_length=20)
userPower = models.DecimalField(max_digits=3, decimal_places=0, default=10)
createTime = models.DateTimeField(auto_now_add=True)
updateTime = models.DateTimeField(auto_now=True)
def save(self, **kwargs):
if not self.id:
idCount = User.objects.aggregate(Count('id')).get("id__count")
cursor = connection.cursor()
if idCount == 0:
# 要想运用sql原生句子,有必要用到execute()函数,然后在里边写入sql原生句子
cursor.execute("TRUNCATE app_user RESTART IDENTITY")
maxid = User.objects.aggregate(Max('id')).get("id__max")
# 让主键从什么方位开端排序
if maxid is not None:
cursor.execute("ALTER SEQUENCE app_user_id_seq RESTART WITH %s", [maxid+1])
self.userId = "{}{:06d}".format('user', (maxid+1) if maxid is not None else 1)
super().save(*kwargs)
# 物品ware表:【wareId,wareName,warePower,wareCount,createTime,updateTime】
class Ware(models.Model):
id = models.AutoField(primary_key=True)
wareId = models.CharField(max_length=20)
wareName = models.CharField(unique=True, max_length=15)
warePower = models.DecimalField(max_digits=8, decimal_places=0, default=0)
wareCount = models.DecimalField(max_digits=10, decimal_places=0, default=0)
createTime = models.DateTimeField(auto_now_add=True)
updateTime = models.DateTimeField(auto_now=True)
def save(self, **kwargs):
if not self.id:
idCount = Ware.objects.aggregate(Count('id')).get("id__count")
cursor = connection.cursor()
if idCount == 0:
# 要想运用sql原生句子,有必要用到execute()函数,然后在里边写入sql原生句子
cursor.execute("TRUNCATE app_ware RESTART IDENTITY")
maxid = Ware.objects.aggregate(Max('id')).get("id__max")
# 让主键从什么方位开端排序
if maxid is not None:
cursor.execute("ALTER SEQUENCE app_ware_id_seq RESTART WITH %s", [maxid+1])
self.wareId = "{}{:06d}".format('ware', (maxid+1) if maxid is not None else 1)
super().save(*kwargs)
# 订单order表:【orderId,userId,userName,wareId,wareName,wareCount,createTime】
class Order(models.Model):
id = models.AutoField(primary_key=True)
orderId = models.CharField(max_length=20)
userId = models.CharField(max_length=20)
userName = models.CharField(max_length=15)
wareId = models.CharField(max_length=20)
wareName = models.CharField(max_length=15)
wareCount = models.DecimalField(max_digits=10, decimal_places=0, default=0)
createTime = models.DateTimeField(auto_now_add=True)
def save(self, **kwargs):
if not self.id:
idCount = Order.objects.aggregate(Count('id')).get("id__count")
cursor = connection.cursor()
if idCount == 0:
# 要想运用sql原生句子,有必要用到execute()函数,然后在里边写入sql原生句子
cursor.execute("TRUNCATE app_order RESTART IDENTITY")
maxid = Order.objects.aggregate(Max('id')).get("id__max")
# 让主键从什么方位开端排序
if maxid is not None:
cursor.execute("ALTER SEQUENCE app_order_id_seq RESTART WITH %s", [maxid+1])
self.orderId = "{}{:06d}".format('order', (maxid+1) if maxid is not None else 1)
super().save(*kwargs)
# 暂时订单cart表:【cartId,userId,userName,wareId,wareName,wareCount,createTime,updateTime】
class Cart(models.Model):
id = models.AutoField(primary_key=True)
cartId = models.CharField(max_length=20)
userId = models.CharField(max_length=20)
userName = models.CharField(max_length=15)
wareId = models.CharField(max_length=20)
wareName = models.CharField(max_length=15)
wareCount = models.DecimalField(max_digits=10, decimal_places=0, default=0)
createTime = models.DateTimeField(auto_now_add=True)
updateTime = models.DateTimeField(auto_now=True)
def save(self, **kwargs):
if not self.id:
idCount = Cart.objects.aggregate(Count('id')).get("id__count")
cursor = connection.cursor()
if idCount == 0:
# 要想运用sql原生句子,有必要用到execute()函数,然后在里边写入sql原生句子
cursor.execute("TRUNCATE app_cart RESTART IDENTITY")
maxid = Cart.objects.aggregate(Max('id')).get("id__max")
# 让主键从什么方位开端排序
if maxid is not None:
cursor.execute("ALTER SEQUENCE app_cart_id_seq RESTART WITH %s", [maxid+1])
self.cartId = "{}{:06d}".format('cart', (maxid+1) if maxid is not None else 1)
super().save(*kwargs)
# 公司出售额sales表:【salesId,yearName,yearSales,yearEvents,monthSales,wareSales】
class Sales(models.Model):
id = models.AutoField(primary_key=True)
salesId = models.CharField(max_length=20)
yearName = models.CharField(max_length=5)
yearSales = models.DecimalField(max_digits=10, decimal_places=2, default=0)
yearEvents = models.CharField(max_length=30, default="")
monthSales = models.JSONField(null=True)
wareSales = models.JSONField(null=True)
def save(self, **kwargs):
if not self.id:
idCount = Sales.objects.aggregate(Count('id')).get("id__count")
cursor = connection.cursor()
if idCount == 0:
# 要想运用sql原生句子,有必要用到execute()函数,然后在里边写入sql原生句子
cursor.execute("TRUNCATE app_sales RESTART IDENTITY")
maxid = Sales.objects.aggregate(Max('id')).get("id__max")
# 让主键从什么方位开端排序
if maxid is not None:
cursor.execute("ALTER SEQUENCE app_sales_id_seq RESTART WITH %s", [maxid+1])
self.salesId = "{}{:06d}".format('sales', (maxid+1) if maxid is not None else 1)
super().save(*kwargs)
//之后顺次履行以下两条句子完结表的创立完结
python .\manage.py makemigrations
python .\manage.py migrate
此刻在pgAdmin4中能够看到,表的创立完结:
三、登录注册模块的开发
API文档:docs.djangoproject.com/zh-hans/4.1…(包括: 回来新 QuerySet 的办法 , 回来新 QuerySet 的操作符 , 不回来 QuerySet 的办法 , Field 查找 , 聚合函数 , 查询相关东西等各种相关查询东西的API)
1、注册功用
注册功用——前端提交一个User类,相似这种:
实际上后端只需求拿到userId、userName这两项,剩余的特点靠后端处理得到,再整合到一同,将整合后的成果存储到数据库对应的表中。后端需求处理的特点是createTime、updateTime、userId、userPower,实际上到这步现已无需理会这几项,由于在建user表时,就现已做出了相应处理:
- userPower字段中的deafult = 10特点表明注册的用户默认权限为10(没有额别传别的的值时);
- auto_now_add=True表明当一条新数据被创立成功后,将该入参auto_now_add对应的表字段的值设置为创立成功时的体系时间,今后修正这条新数据时,该表字段的值不会再更新;
- auto_now=True当一条新数据被修正成功后,将该入参auto_now对应的表字段的值设置为修正成功时的体系时间;
- 重写的save函数表明新建一条数据时,自动生成并保存诸如:“userXXXXXX”这种仅有确定的userId。
下面在app文件夹里边的view.py写注册功用函数:
# 导入所需模块
import json
from app01.models import *
# 处理跨域
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse
from django.shortcuts import render
# Create your views here.
# 注册功用
@csrf_exempt #处理跨域
def register(request):
# 获取前端传过来的值--request.body表明前端传过来的值,.decode()表明使中文不乱码,用json.loads转换为json格局
reqBody = json.loads(request.body.decode())
# print(reqBody)
username = reqBody['userName']
password = reqBody['userPassword']
if username and password:
# 判别字符串长度
if len(username) > 15 or len(password) > 20:
return JsonResponse({'code': -1, 'msg': '用户名或暗码过长'})
# 查找数据库中是否现已存在相同的userName
user_name = User.objects.filter(userName=username)
if user_name.exists():
return JsonResponse({'code': -1, 'msg': '用户已存在'})
# 假如不重复,在保存有关信息
uesr_save = User(userName=username, userPassword=password)
uesr_save.save()
# 回来注册成功信息给前端
return JsonResponse({'code': 0, 'msg': 'success'})
else:
return JsonResponse({'code': -1, "msg": "用户名或暗码不能为空"})
然后在urls.py注册路由:
之后运转现在的Django项目:
python .\manage.py runserver
之后我们去测验写的注册功用接口,用【postman】这个软件来测验:
发现报错,由于触及到跨域问题,处理办法:
在视图views.py里边加上下面两行:
此刻,从头在postman上建议恳求,发现恳求成功:
再去数据库检查数据,发现数据现已进入数据库:
测验注册一个已存在的用户,也成功:
至此,注册功用已完结。
2、登录功用
注册功用——前端提交一个User类,相似这种:
完成登录功用与其它功用操作上相差无几,便是多一个redis缓存的运用,方便获取现在所登录用户的信息,后端回来一个cookie。
过程如下:
- 装置Redis
- 在settings.py里边装备redis:
# 装备Django缓存存储
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
# 让Django默认运用缓存作为存储session贮存后端,这样也不需求装置任何额外的 backend
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
- 在views.py里边编写登录函数
# 导入所需模块
from app01.models import *
# 处理跨域
from django.views.decorators.csrf import csrf_exempt
# JSON目标序列化
import json
from django.core import serializers
from django.http import JsonResponse
# 避免重复登录
from django.contrib.sessions.models import Session
from django.utils import timezone
# 登录功用
@csrf_exempt # 处理跨域
def userLogin(request):
# 获取前端传过来的值--request.body表明前端传过来的值,.decode()表明使中文不乱码,用json.loads转换为json格局
reqBody = json.loads(request.body.decode())
# print(reqBody)
username = reqBody['userName']
password = reqBody['userPassword']
if username and password:
# 查找契合条件的用户信息
user = User.objects.filter(userName=username)
if user.exists():
if user.first().userPassword != password:
return JsonResponse({'code': 0, 'msg': '暗码输入错误'})
else:
userInfo = (json.loads(serializers.serialize("json", user)))[0]
# 当时的一切session--避免重复登录
valid_session_obj_list = Session.objects.filter(expire_date__gt=timezone.now())
flag = 0
for session_obj in valid_session_obj_list:
print(session_obj.get_decoded().get("userInfo"))
if session_obj.get_decoded().get("userInfo").pk == userInfo.pk:
flag = 1
break
if flag == 0:
# 将所登录的用户信息存储在session中(现已改session的默认存储方位为redis中),回来给前端的cookie是sessionid
# 只需前端每次恳求都带上cookie,后端便可依据每个用户的sessionid查找或许操作对应的登录状况和登录信息
request.session['userInfo'] = userInfo
# 这句话完结了下面几步:
# 1.生成随机的sessionid字符串
# 2.将sessionid和用户的信息在数据库中保存为一个键值对
# 3.经过cookie将sessionid保存在客户端上
# 这时候经过用户再次向服务器发送恳求时服务器就能够经过恳求中的sessionid判别用户的信息了,从而到达保存登录状况的要求。
# 回来登录成功信息给前端
return JsonResponse({'code': 0, 'msg': 'success', 'userInfo': userInfo})
else:
return JsonResponse({'code': -1, 'msg': '该用户已登录', 'userInfo': userInfo})
else:
return JsonResponse({'code': -1, "msg": "该用户不存在"})
else:
return JsonResponse({'code': -1, "msg": "用户名或暗码不能为空"})
- 在urls.py里边注册路由
path("miserauth/login", views.userLogin),
- 运转项目并在postman里测验接口
能够看出,登录成功,并成功设置cookie。
get知识点1:将XX.objects.filter查找到的数据转换为JSON格局的办法
# 1--导入json和serializers模块
import json
from django.core import serializers
# 2--获取数据(此刻获取到的是契合要求的目标调集),user.first()表明该调集的第一个目标
user = User.objects.filter(userName=username)
# 3--将目标调集转为JSON格局
# (serializers.serialize表明将目标调集转化为JSON字符串,json.loads表明将该字符串转为真正的JSON格局,[0]表明取得到的数组中的第0个)
return JsonResponse({'code': 0, 'msg': 'success', 'userInfo': (json.loads(serializers.serialize("json", user)))[0]})
# 4--输出如下:
{
"code": 0,
"msg": "success",
"userInfo": {
"model": "app01.user",
"pk": 1,
"fields": {
"userId": "user000001",
"userName": "scucsyyds",
"userPassword": "123456",
"userPower": "10",
"createTime": "2022-11-23T04:45:02.747Z",
"updateTime": "2022-11-23T04:45:02.747Z"
}
}
}
get知识点2:Redis下载和装置(Windows体系)
参阅链接:c.biancheng.net/redis/windo…
(留意:在履行redis-server.exe –service-start前要把客户端发动关掉,不然端口会被占用)
get知识点3:windows免费装置redis desktop manager
上github找到免费版最新的是2018年的,能够直接下载exe履行程序:github.com/uglide/Redi…
3、获取当时登录信息
获取获取当时登录信息——前端只建议get恳求,无需提交任何东西;后端从redis中回来登录用户的信息。
获得当时登录信息,需求用到的地方:
1、登录时验证是否为超级办理员,是的话开放用户办理功用,一起暂时订单展现一切;不是则封闭用户办理功用,一起暂时订单展现该办理员对应的暂时订单。
2、在物品办理页面参加订单或许暂时订单时,绑定当时所登录用户信息
首要思想便是依据前端恳求携带的cookie,经过cookie中的sessionid,在redis中找到对应的登录信息。
# 获取当时登录信息
@csrf_exempt # 处理跨域
def getLoginUser(request):
try:
userInfo = request.session.get('userInfo', None)
if userInfo:
# 回来登录成功信息给前端
return JsonResponse({'code': 0, 'msg': 'success', 'userInfo': userInfo})
else:
return JsonResponse({'code': -1, "msg": "未查找到登录信息"})
# 避免反常处理过分广泛
except AttributeError:
return JsonResponse({'code': -2, 'msg': '发生反常'})
登录之后用postman测验该功用:
能够看出,获取登录用户信息,该接口是成功的。
4、退出登录功用
首要思想将后端redis缓存的登录状况cookie铲除掉,回来退出成功信息给前端。
# 退出登录
@csrf_exempt # 处理跨域
def loginOut(request):
try:
# 退出登录的前提是现已登录
userInfo = request.session.get('userInfo', None)
if userInfo:
# 铲除该用户在服务器中的session,删去客户端的sessionid在服务器中保存的状况
del request.session['userInfo']
# 回来退出成功信息给前端
return JsonResponse({'code': 0, 'msg': 'success'})
else:
return JsonResponse({'code': -1, 'msg': '当时用户未登录'})
# 避免反常处理过分广泛
except AttributeError:
return JsonResponse({'code': -2, 'msg': '退出失利'})
此刻用postman测验该功用:
然后再去获取登录用户信息:
能够看出,现在没有登录信息,接口是成功的。
四、数据可视化模块的开发
1、将模仿数据存入数据库
首先界说项目中静态文件的方位:
然后在setting.py里边注册静态文件的路径:
STATIC_URL = "static/"
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
接着写好模仿数据的JSON,如下所示:
在views.py写好存入数据库的函数:
# 将出售数据传入数据库
@csrf_exempt # 处理跨域
def saveSalesData(request):
# 获取前端传过来的值--request.body表明前端传过来的值,.decode()表明使中文不乱码,用json.loads转换为json格局
reqBody = json.loads(request.body.decode())
# print(reqBody)
try:
# 查找数据库中是否现已存在相同的yearName
year_name = Sales.objects.filter(yearName=reqBody['yearName'])
if year_name.exists():
return JsonResponse({'code': -1, 'msg': '该年数据已存在'})
# 假如不重复,在保存有关信息
sales_save = Sales(yearName=reqBody['yearName'],
yearSales=reqBody['yearSales'],
yearEvents=reqBody['yearEvents'],
monthSales=reqBody['monthSales'],
wareSales=reqBody['wareSales']
)
sales_save.save()
return JsonResponse({'code': 0, 'msg': 'success'})
# 避免反常处理过分广泛
except AttributeError:
return JsonResponse({'code': -1, 'msg': '保存失利'})
在urls.py注册路由:
path("saveSalesData", views.saveSalesData),
用postman建议恳求来存入数据:
去数据库中检查数据:
能够看出,该接口成功。
2、获取数据库中的数据
总共三个不同的可视化图表,但切换时,前端只建议同一个恳求,后端回来sales表中的悉数数据供前端处理(反正数据也不多,这个表本便是相当于独立静态的)
在views.py写好获取出售数据函数:
# 获取数据库中的出售数据
@csrf_exempt # 处理跨域
def getSalesData(request):
try:
salesData = (json.loads(serializers.serialize("json", Sales.objects.all())))
return JsonResponse({'code': 0, 'msg': 'success', 'salesData': salesData})
# 避免反常处理过分广泛
except AttributeError:
return JsonResponse({'code': -1, 'msg': '获取失利'})
在urls.py注册路由:
path("getSalesData", views.getSalesData)
运转项目,并在postman里测验接口:
能够看到,数据获取成功,该接口有效。
五、库存办理模块的开发
获取库房中的悉数物品信息——前端只建议get恳求,无需提交任何东西
获取库房中某个物品信息——前端只需提交一个wareId来建议get恳求,相似这种:
添加物品——前端提交一个Ware类,相似这种:(后端只需拿到wareName、wareCount、warePower,剩余的特点在models里边现已处理好了)
删去一个或多个物品——前端提交wareId的数组,相似这种:
修正某个物品信息,前端提交一个Ware类,相似这种:(后端只需拿到更新后的wareName、wareCount、warePower,剩余的特点在models里边现已处理好了)
六、用户办理模块的开发
留意:该模块只对超级办理员开放,前端来做这个判别处理即可
获取体系中的悉数用户信息——前端只建议get恳求,无需提交任何东西
获取体系中某个用户信息——前端只需提交一个userId来建议get恳求,相似这种:
添加用户——前端提交一个User类,相似这种:(后端只需拿到userName、userPassword、userPower,剩余的特点在models里边现已处理好了)
删去一个或多个物品——前端提交userId的数组,相似这种:
修正某个用户信息,前端提交一个User类,相似这种:(后端只需拿到更新后的userName、userPassword、userPower,剩余的特点在models里边现已处理好了)
七、订单办理模块的开发
获取体系中的悉数订单信息——前端只建议get恳求,无需提交任何东西
获取体系中某个订单信息——前端只需提交一个orderId来建议get恳求,相似这种:
添加订单——前端提交一个Order类,相似这种:(后端只需拿到userId、userName、wareCount、wareId、wareName,剩余的特点在models里边现已处理好了,留意此刻库房中对应wareId物品的数量会随之削减)
删去一个或多个订单——前端提交orderId的数组,相似这种:
八、暂时订单模块的开发
获取体系中的暂时订单信息——前端只建议get恳求,无需提交任何东西(这个功用需求需求留意的点是,关于超级办理员回来悉数暂时订单信息,关于一般办理员回来该办理员对应的暂时订单信息——后端经过匹配现在的登录信息userId做到)
添加暂时订单——前端提交一个Cart类,相似这种:(后端只需拿到userId、userName、wareCount、wareId、wareName,剩余的特点在models里边现已处理好了)
删去一个或多个暂时订单——前端提交cartId的数组,相似这种:
修正某个暂时订单信息,前端提交一个Cart类,相似这种:(后端只需拿到更新后的wareCount,剩余的特点不变)
将暂时订单参加订单,前端提交一个Cart类数组,相似这种:(后端只需拿到该数组中每个项中的userId、userName、wareCount、wareId、wareName,并用这些信息新建订单即可,留意此刻库房中对应wareId的物品会随之削减、体系中会添加相应的订单、对应的暂时订单随之消失)
九、与前端对接接口时发生的问题及处理
1、接口跨域问题
参阅博客:
【处理Django与Vue的跨域问题】:
blog.csdn.net/weixin_4232…
【vue+django跨域问题处理方案(前后端两种方案)】:blog.csdn.net/qq_41000891…
2、cookie被阻拦的问题
参阅博客:
【DJango碰到samesite无法登录Chrom(处理DJango无法获取Chrom的cookie问题)】:
blog.csdn.net/weixin_4268…
此刻发现尽管浏览器没有阻拦cookie,似乎却仍没有保存到浏览器中,可是事实上现已能获取到cookie了。
3、Vue3+Django4项目整合
参阅博客:
【vue+django的项目布置问题】:
blog.csdn.net/qq_44774831…
【Vue3+Django4项目整合】:
blog.csdn.net/a820206256/…
十、项目布置
将数据库导出为sql文件:
布置参阅博客:(记住python项目办理器必定要用1.9版本的)
zhuanlan.zhihu.com/p/476724776
浮屠终端中用到的指令:
//进入虚拟环境
source /www/wwwroot/82.157.247.180/82.157.247.180_venv/bin/activate
// 进入项目文件夹
cd /www/wwwroot/82.157.247.180
// 运转项目
python manage.py runserver
最终仍失利(数据库衔接出了问题)。。。现在不知道怎么处理。
之后依照这篇博客blog.csdn.net/u010775335/…处理了数据库衔接的问题,(实质是在终端新建一个数据库)。
python manage.py runserver指令之后没有报错,可是浏览器拜访ip地址报下面的错:
之后更改鼠标所选部分ip(更改为127.0.0.1,在python项目办理器重启项目)
此刻拜访成功。
可是发现,这种问题:
处理办法:更改前端恳求的根路由。
此刻拜访成功,但Redis部分出错,导致登录后无法获取登录信息:
此刻检查登录接口的响应头,发现cookie没有被设置上:
处理办法: (将SESSION_COOKIE_SECURE设置为Flase,不然只能经过https拜访了。)
此刻依然没有设置上cookie:
此刻处理方案:
(即注释掉)
布置成功。
此刻若想用已备案已解析的域名进行拜访,则在网站-域名办理里边添加域名即可:
此刻发现新的问题,cookie没有设置上:
此刻处理方案:布置ssl证书:(腾讯云申请的免费ssl证书)
此刻无法建议恳求:
此刻参阅了这两篇博客:
【Django处理https装备问题】:
blog.csdn.net/Happy_EndNo…
【Django应用装备https拜访,将拜访django的http恳求转成https恳求】:
blog.csdn.net/hzw6991/art…
仍没有用。。。
最终,改动前端恳求跟路由即可:
项目链接:www.anlh.xyz/
nice!
十一、总结
本文具体地介绍了开发、布置一个简略的后台办理体系的的过程,包括了团队协作开发、Django开发、接口调试、前后端联调、浮屠布置的过程及遇到一些问题的处理方案,可供初学者进行学习参阅。
附上项目源码:(欢迎各位看官给个star)
项目后端源码:XC0703/inventory_management_django_system (github.com)
项现在端源码:XC0703/inventory_management_system (github.com)