之前的内容
一.实现的内容
-
商品退货
-
商品库存
-
商品进货
-
商品删除
-
商品还原
-
时钟
-
优化模型
二.后续内容准备优化内容
- 把数据库查询的内容存在缓存中
- 增加按日期,按商品名查询
- 增加快捷商品增加
- 优化代码
- 优化界面
三.目录结构
drf_test
|___drf_api
| |___admin.py
| |___apps.py
| |___migrations
| |___models.py
| |___tests.py
| |___userinfo_form.py
| |___views
| | |____commodity.py
| | |____user.py
| |_____init__.py
|___drf_test
| |___settings.py
| |___urls.py
| |___wsgi.py
| |_____init__.py
|___img
| |___avatar
|___manage.py
|___static
| |___bootstrap-3.3.7-dist
| |___jquery-3.4.1.min.js
|___templates
| |___aa.html
| |___add.html
| |___del.html
| |___index.html
| |___login.html
| |___register.html
| |___return.html
| |___sales.html
| |___show.html
| |___show_del.html
| |___template.html
|_____pycache__
| |___manage.cpython-37.pyc
四.代码
1.配置
setting.py
"""
Django settings for drf_test project.
Generated by \'django-admin startproject\' using Django 1.11.22.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = \'ppa5l3jvxr4k^ow*4o+0_^7@&sa3x+!hb_$artwraa%60iq@g7\'
# SECURITY WARNING: don\'t run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
\'django.contrib.admin\',
\'django.contrib.auth\',
\'django.contrib.contenttypes\',
\'django.contrib.sessions\',
\'django.contrib.messages\',
\'django.contrib.staticfiles\',
\'drf_api\',
\'rest_framework\',
]
MIDDLEWARE = [
\'django.middleware.security.SecurityMiddleware\',
\'django.contrib.sessions.middleware.SessionMiddleware\',
\'django.middleware.common.CommonMiddleware\',
\'django.middleware.csrf.CsrfViewMiddleware\',
\'django.contrib.auth.middleware.AuthenticationMiddleware\',
\'django.contrib.messages.middleware.MessageMiddleware\',
\'django.middleware.clickjacking.XFrameOptionsMiddleware\',
]
ROOT_URLCONF = \'drf_test.urls\'
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\',
],
},
},
]
WSGI_APPLICATION = \'drf_test.wsgi.application\'
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
DATABASES = {
\'default\': {
\'ENGINE\': \'django.db.backends.mysql\', # 数据库引擎
\'NAME\': \'mib\', # 你要存储数据的库名,事先要创建之
\'USER\': \'root\', # 数据库用户名
\'PASSWORD\': \'16745\', # 密码
\'HOST\': \'localhost\', # IP
\'PORT\': \'3306\', # 数据库使用的端口
}
}
# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
\'NAME\': \'django.contrib.auth.password_validation.UserAttributeSimilarityValidator\',
},
{
\'NAME\': \'django.contrib.auth.password_validation.MinimumLengthValidator\',
},
{
\'NAME\': \'django.contrib.auth.password_validation.CommonPasswordValidator\',
},
{
\'NAME\': \'django.contrib.auth.password_validation.NumericPasswordValidator\',
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/
LANGUAGE_CODE = \'zh-hans\'
TIME_ZONE = \'Asia/Shanghai\'
USE_I18N = True
USE_L10N = True
USE_TZ = False
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
STATIC_URL = \'/static/\'
STATICFILES_DIRS=(os.path.join(BASE_DIR,\'static\'),)
AUTH_USER_MODEL = "drf_api.UserInfo"
MEDIA_URL = "/img/"
MEDIA_ROOT = os.path.join(BASE_DIR, "img")
# REST_FRAMEWORK = {
# \'DEFAULT_AUTHENTICATION_CLASSES\': (
# \'rest_framework.authentication.TokenAuthentication\',
# )
# }
2.模型
from django.db import models
from django.contrib.auth.models import AbstractUser
from rest_framework import mixins
# Create your models here.
class UserInfo(AbstractUser):
avatar = models.FileField(upload_to=\'avatar/\', default=\'avatar/default.png\')
class Meta:
verbose_name=\'用户表\'
verbose_name_plural = verbose_name
class Commodity(models.Model):
name = models.CharField(max_length=60,db_column=\'商品名\',null=True)
inventory = models.IntegerField(db_column=\'库存\',null=True)
cost = models.DecimalField (max_digits=60,decimal_places=2,db_column=\'总成本\',null=True)
selling_price= models.DecimalField (max_digits=60,decimal_places=2,db_column=\'总销售价格\',default=0)
batch = models.CharField(max_length=60, db_column=\'批号\', null=True)
quantity_in = models.IntegerField(db_column=\'进货总数量\',null=True)
sales_volume = models.IntegerField(db_column=\'销售量总数量\',default=0)
return_volume = models.IntegerField(db_column=\'退货总数量\',default=0)
is_delete = models.BooleanField(default=False, db_column=\'是否删除\')
def __str__(self):
return self.name
class Meta:
db_table = "库存表"
class DaySales(models.Model):
date = models.CharField(max_length=60,db_column=\'日期\')
number = models.DecimalField(max_digits=60, decimal_places=2, db_column=\'营业总额\', null=True)
is_delete = models.BooleanField(default=False, db_column=\'是否删除\')
date_changed = models.DateTimeField(auto_now=True,db_column=\'最后修改日期\')
def __str__(self):
return self.date
class Meta:
db_table = "日销售表"
class DayStock(models.Model):
date = models.CharField(max_length=60,db_column=\'日期\')
number = models.DecimalField(max_digits=60, decimal_places=2, db_column=\'进货总额\', null=True)
is_delete = models.BooleanField(default=False, db_column=\'是否删除\')
date_changed = models.DateTimeField(auto_now=True,db_column=\'最后修改日期\')
def __str__(self):
return self.date
class Meta:
db_table = "日进货表"
class DayReturn(models.Model):
date = models.CharField(max_length=60,db_column=\'日期\')
number = models.DecimalField(max_digits=60, decimal_places=2, db_column=\'退货总额\', null=True)
is_delete = models.BooleanField(default=False, db_column=\'是否删除\')
date_changed = models.DateTimeField(auto_now=True,db_column=\'最后修改日期\')
def __str__(self):
return self.date
class Meta:
db_table = "日退货表"
class CommoditySales(models.Model):
name = models.CharField(max_length=60,db_column=\'商品名\',null=True)
data = models.ForeignKey(\'DaySales\',\'id\',db_column=\'销售日期\',null=True)
selling_price= models.DecimalField (max_digits=60,decimal_places=2,db_column=\'销售价格\',null=True)
sales_volume = models.IntegerField(db_column=\'销售量数量\',null=True)
batch = models.CharField(max_length=60,db_column=\'批号\',null=True)
is_delete = models.BooleanField(default=False, db_column=\'是否删除\')
date_changed = models.DateTimeField(auto_now=True,db_column=\'最后修改日期\')
def __str__(self):
return self.name
class Meta:
db_table = "商品销售表"
class CommodityStock(models.Model):
name = models.CharField(max_length=60,db_column=\'商品名\',null=True)
data = models.ForeignKey(\'DayStock\',\'id\',db_column=\'进货日期\',null=True)
cost = models.DecimalField (max_digits=60,decimal_places=2,db_column=\'单件成本\',null=True)
Stock_volume = models.IntegerField( db_column=\'进货数量\', null=True)
batch = models.CharField(max_length=60,db_column=\'批号\',null=True)
is_delete = models.BooleanField(default=False, db_column=\'是否删除\')
date_changed = models.DateTimeField(auto_now=True,db_column=\'最后修改日期\')
def __str__(self):
return self.name
class Meta:
db_table = "商品进货表"
class CommodityReturn(models.Model):
name = models.CharField(max_length=60,db_column=\'商品名\',null=True)
data = models.ForeignKey(\'DayReturn\',\'id\',db_column=\'退货日期\',null=True)
cost = models.DecimalField (max_digits=60,decimal_places=2,db_column=\'退货价格\',null=True)
return_volume = models.IntegerField( db_column=\'退货数量\', null=True)
batch = models.CharField(max_length=60,db_column=\'批号\',null=True)
is_delete = models.BooleanField(default=False, db_column=\'是否删除\')
date_changed = models.DateTimeField(auto_now=True,db_column=\'最后修改日期\')
def __str__(self):
return self.name
class Meta:
db_table = "商品退货表"
3.路由
"""drf_test URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r\'^$\', views.home, name=\'home\')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r\'^$\', Home.as_view(), name=\'home\')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r\'^blog/\', include(\'blog.urls\'))
"""
from django.conf.urls import url
from django.contrib import admin
from django_filters import views
from drf_api.views import user
from drf_api.views import commodity
from django.views.static import serve
from .settings import MEDIA_ROOT
urlpatterns = [
url(r\'^admin/\', admin.site.urls),
url(r\'^register/\', user.register),
url(r\'^test/\', user.test),
url(r\'^login/\', user.login),
url(r\'^loginout/\', user.loginout),
url(r\'^get_code/\', user.get_code),
url(r\'^show/\', commodity.Show.as_view()),
url(r\'^add/\', commodity.Add.as_view()),
url(r\'^del/\', commodity.Del.as_view()),
url(r\'^show_del/\', commodity.ShowDel.as_view()),
url(r\'^sales/\', commodity.Sales.as_view()),
url(r\'^return/\', commodity.Return.as_view()),
url(r\'\', user.index),
url(r\'^img/(?P<path>.*)\', serve, {\'document_root\': MEDIA_ROOT}),
]
4.用户视图
user.py
from django.shortcuts import render,HttpResponse,redirect
from django.http import JsonResponse
from PIL import Image,ImageDraw,ImageFont
import random
from io import BytesIO
from django.contrib import auth
from drf_api.userinfo_form import Register
from drf_api import models
from rest_framework.throttling import SimpleRateThrottle
def test(request):
return render(request, \'aa.html\')
def register(request):
if request.method==\'GET\':
form=Register()
return render(request, \'register.html\', {\'form\':form})
elif request.is_ajax():
response={\'code\':100,\'msg\':None}
form = Register(request.POST)
if form.is_valid():
#校验通过的数据
clean_data=form.cleaned_data
#把re_pwd剔除
clean_data.pop(\'re_pwd\')
#取出头像
avatar=request.FILES.get(\'avatar\')
if avatar:
clean_data[\'avatar\']=avatar
user=models.UserInfo.objects.create_user(**clean_data)
if user:
response[\'msg\'] = \'创建成功\'
else:
response[\'code\'] = 103
response[\'msg\'] = \'创建失败\'
else:
response[\'code\']=101
#把校验不通过的数据返回
response[\'msg\']=form.errors
print(type(form.errors))
return JsonResponse(response,safe=False)
def login(request):
if request.method==\'GET\':
return render(request, \'login.html\')
else:
print(request.POST)
user_name=request.POST.get(\'name\')
pwd=request.POST.get(\'pwd\')
code=request.POST.get(\'code\')
user=auth.authenticate(username=user_name,password=pwd)
print(user)
if request.session.get(\'code\').upper() !=code.upper(): #忽略大小写
return HttpResponse(\'验证码错误\')
elif not user:
return HttpResponse(\'账号密码错误\')
else:
auth.login(request,user)
return redirect(\'/show/\')
def get_code(request):
if request.method == \'GET\':
img = Image.new(\'RGB\', (350, 40), (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
# 写文字
# 生成一个字体对象
font = ImageFont.truetype(\'/static/Gabriola.ttf\', 34)
# 调用方法,返回一个画板对象
draw = ImageDraw.Draw(img)
new_text =\'\'
x = 100
# 生成随机4位数字
text_chiose = \'zxcvbnmasdfghjklqwertyup23456789ZXCVBNMASDFGHJKLQWERTYUP\'
text_list=random.sample(text_chiose,4)
for text in text_list:
x+=20
y = random.randint(1,5)
draw.text((x, y), text, (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)),
font=font)
new_text +=text
# 加点线
width = 320
height = 35
for i in range(2):
x1 = random.randint(0, width)
x2 = random.randint(0, width)
y1 = random.randint(0, height)
y2 = random.randint(0, height)
# 在图片上画线
draw.line((x1, y1, x2, y2), fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
for i in range(10):
# 画点
draw.point([random.randint(0, width), random.randint(0, height)], fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
x = random.randint(0, width)
y = random.randint(0, height)
# 画弧形
draw.arc((x, y, x + 4, y + 4), 0, 90, fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
print(new_text)
#存在session中
request.session[\'code\']=new_text
#存内存
f = BytesIO()
img.save(f, \'png\')
return HttpResponse(f.getvalue())
def loginout(request):
auth.logout(request)
return redirect(\'/login\')
def index(request):
return render(request,\'index.html\')
5.商品视图
commodity.py
这里Return视图类有点偷懒了里面变量名用的非常非常不规范请见谅
import datetime
from django.shortcuts import render, HttpResponse
from rest_framework.views import APIView
from drf_api.models import *
class Show(APIView):
def get(self, request):
Commodity_list = Commodity.objects.filter(is_delete=False).order_by(\'name\').all()
print(Commodity_list)
return render(request, \'show.html\', {\'Commodity_list\': Commodity_list})
class Add(APIView):
def get(self, request):
Commodity_list = Commodity.objects.filter(is_delete=False).order_by(\'name\').all()
print(Commodity_list)
return render(request, \'add.html\')
def post(self, request):
print(request.POST)
name = request.POST.get(\'name\') # type:str
batch = request.POST.get(\'batch\') # type:str
cost = request.POST.get(\'cost\') # type:str
Stock_volume = request.POST.get(\'Stock_volume\') # type:str
time = str(datetime.datetime.now()).split(\' \')[0].replace(\'-\', \'\')
DayStock_obj = DayStock.objects.filter(date=time).first()
try:
number = float(cost) * int(Stock_volume)
except:
return HttpResponse(\'数量和价格请输入数字\')
try:
if not DayStock_obj:
DayStock_obj = DayStock.objects.create(date=time, number=number)
else:
old_number = float(DayStock_obj.number)
DayStock_obj.number = old_number + number
DayStock_obj.save()
CommodityStock_obj = CommodityStock.objects.create(name=name, data=DayStock_obj, cost=number,
Stock_volume=int(Stock_volume), batch=batch)
obj = Commodity.objects.filter(is_delete=False, name=name, batch=batch).first()
if obj:
obj.quantity_in += int(Stock_volume)
obj.inventory += int(Stock_volume)
old_number = float(obj.cost)
obj.cost = old_number + number
obj.save()
else:
Commodity.objects.create(name=name, inventory=int(Stock_volume), cost=float(cost),
quantity_in=int(Stock_volume), batch=batch)
return HttpResponse(\'添加成功\')
except:
return HttpResponse(\'添加失败\')
class Del(APIView):
def get(self, request):
Commodity_list = Commodity.objects.filter(is_delete=False).order_by(\'name\').all()
print(Commodity_list)
return render(request, \'del.html\', {\'Commodity_list\': Commodity_list})
def post(self, request):
c_id = request.POST.get(\'c_id\')
Commodity_obj = Commodity.objects.filter(id=c_id).first()
Commodity_obj.is_delete = True
Commodity_obj.save()
return HttpResponse(\'删除成功\')
class ShowDel(APIView):
def get(self, request):
Commodity_list = Commodity.objects.filter(is_delete=True).all()
print(Commodity_list)
return render(request, \'show_del.html\', {\'Commodity_list\': Commodity_list})
def post(self, request):
c_id = request.POST.get(\'c_id\')
Commodity_obj = Commodity.objects.filter(id=c_id).first()
Commodity_obj.is_delete = False
Commodity_obj.save()
return HttpResponse(\'恢复成功\')
class Sales(APIView):
def get(self, request):
Commodity_list = Commodity.objects.filter(is_delete=False).order_by(\'name\').all()
print(Commodity_list)
return render(request, \'sales.html\', {\'Commodity_list\': Commodity_list})
def post(self, request):
c_id = request.POST.get(\'c_id\')
selling_price = request.POST.get(\'selling_price\')
sales_volume = request.POST.get(\'sales_volume\')
try:
selling_price = float(selling_price)
sales_volume = int(sales_volume)
except:
return HttpResponse(\'数量和价格请输入数字\')
try:
Commodity_obj = Commodity.objects.filter(id=c_id).first()
name = Commodity_obj.name
batch = Commodity_obj.batch
time = str(datetime.datetime.now()).split(\' \')[0].replace(\'-\', \'\')
DaySales_obj = DaySales.objects.filter(date=time).first()
number = selling_price * sales_volume
if not DaySales_obj:
DaySales_obj = DaySales.objects.create(date=time, number=number)
else:
old_number = float(Commodity_obj.selling_price)
DaySales_obj.number = old_number + number
DaySales_obj.save()
CommoditySales_obj = CommoditySales.objects.create(name=name, data=DaySales_obj, selling_price=selling_price,
sales_volume=sales_volume, batch=batch)
Commodity_obj.sales_volume += sales_volume
Commodity_obj.inventory -= sales_volume
old_number = float(Commodity_obj.selling_price)
Commodity_obj.selling_price = old_number + number
Commodity_obj.save()
return HttpResponse(\'出售成功\')
except:
return HttpResponse(\'数据异常\')
class Return(APIView):
def get(self, request):
Commodity_list = Commodity.objects.filter(is_delete=False).order_by(\'name\').all()
print(Commodity_list)
return render(request, \'return.html\', {\'Commodity_list\': Commodity_list})
def post(self, request):
c_id = request.POST.get(\'c_id\')
selling_price = request.POST.get(\'selling_price\')
sales_volume = request.POST.get(\'sales_volume\')
try:
selling_price = float(selling_price)
sales_volume = int(sales_volume)
except:
return HttpResponse(\'数量和价格请输入数字\')
try:
Commodity_obj = Commodity.objects.filter(id=c_id).first()
name = Commodity_obj.name
batch = Commodity_obj.batch
time = str(datetime.datetime.now()).split(\' \')[0].replace(\'-\', \'\')
DayReturn_obj = DayReturn.objects.filter(date=time).first()
number = selling_price * sales_volume
if not DayReturn_obj:
DayReturn_obj = DayReturn.objects.create(date=time, number=number)
else:
old_number = float(Commodity_obj.selling_price)
DayReturn_obj.number = old_number + number
DayReturn_obj.save()
CommodityReturn_obj = CommodityReturn.objects.create(name=name, data=DayReturn_obj, cost=selling_price,
return_volume=sales_volume, batch=batch)
Commodity_obj.return_volume += sales_volume
Commodity_obj.inventory -= sales_volume
old_number = float(Commodity_obj.selling_price)
Commodity_obj.selling_price = old_number + number
Commodity_obj.save()
return HttpResponse(\'退货成功\')
except:
return HttpResponse(\'数据异常\')
6.网页
模板template.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="/static/jquery-3.4.1.min.js"></script>
<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
<title>{% block title_text %}{% endblock %}</title>
</head>
<style>
table{
background: antiquewhite;
}
.header {
position: fixed;
top: 0;
left: 0;
height: 100px;
width: 100%;
background: red;
}
.header_left {
position: absolute;
line-height: 100px;
font-size: 50px;
width: 20%;
text-align: center;
background: black;
color: white;
}
.header_middle {
position: absolute;
line-height: 100px;
font-size: 50px;
width: 20%;
background: none;
color: white;
left: 20%;
}
.header_right {
float: right;
}
.body {
position: fixed;
top: 100px;
left: 0;
bottom: 20px;
width: 100%;
}
.body_left {
position: fixed;
top: 100px;
bottom: 20px;
width: 20%;
background: white;
left: 0;
}
.body_right {
overflow: auto;
position: fixed;
top: 100px;
left: 20%;
bottom: 20px;
width: 80%;
background: #2aabd2;
}
.footer {
position: fixed;
left: 0;
bottom: 0;
height: 20px;
width: 100%;
background: black;
}
</style>
{% block new_css %}
{% endblock %}
<body>
<div class="header">
<div class="header_left">管理系统</div>
<div class="header_middle"><span id="clock"></span></div>
<div class="header_right">
{% if request.user.is_authenticated %}
<span><img src=http://127.0.0.1:8000/img/{{ request.user.avatar }} alt="" style="height: 30px;width: 30px">尊敬的{{ request.user.username }}</span>
<span class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="true" style="font-size: 12px">
更多操作
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1" >
<li><a href="#" style="line-height: 0.428571;">修改头像</a><a href="#">修改密码</a></li>
<li role="separator" class="divider"></li>
<li><a href="/loginout/" style="line-height: 0.428571;">登出</a></li>
</ul>
</span>
{% else %}
<spen style="line-height: 50px;float: right;position: absolute;right: 120px;"><a
href="/login/">登入</a>{{ request.user.username }}</spen>
<spen style="line-height: 50px;float: right;position: absolute;right: 80px;"><a
href="/register/">注册</a>{{ request.user.username }}</spen>
{% endif %}
</div>
</div>
<div class="body">
<div class="body_left">
<ul class="nav nav-pills nav-stacked nav-pills-stacked-example">
<li role="presentation" class="active"><a>库存管理</a></li>
<li role="presentation"><a href="/show/">商品库存</a></li>
<li role="presentation"><a href="/add/">商品进货</a></li>
<li role="presentation"><a href="/return/">商品退货</a></li>
<li role="presentation"><a href="/sales/">商品销售</a></li>
<li role="presentation"><a href="/del/">删除库存商品</a></li>
<li role="presentation"><a href="/show_del/">删除商品查看</a></li>
</ul>
</div>
<div class="body_right">
{% block data %}
{% endblock %}
</div>
</div>
<div class="footer"></div>
</body>
</html>
<script>
function get_time() {
var obj = new Date();
var hour = obj.getHours();
var min = obj.getMinutes();
var seconds = obj.getSeconds();
if (parseInt(seconds)<10)seconds=\'0\'+seconds;
if (parseInt(hour)<10)hour=\'0\'+hour;
if (parseInt(min)<10)min=\'0\'+min;
var time = hour + \':\' + min + \':\' + seconds
var clock = document.querySelector(\'#clock\')
clock.innerText = time
}
setInterval(get_time,1000)
</script>
{% block new_js %}
{% endblock %}
注册register.html
{% extends \'template.html\' %}
{% block title_text %}
注册
{% endblock %}
{% block new_css %}
{% endblock %}
{% block data %}
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1>注册</h1>
<form id="my_form">
{% for foo in form %}
<div class="form-group">
{#foo.auto_id 就是foo生成的input的id#}
<label for="{{ foo.auto_id }}">{{ foo.label }}</label>
{{ foo }} <span style="color: red" class="error pull-right"></span>
</div>
{% endfor %}
<div class="form-group">
<label for="id_file">头像
<img src="/img/avatar/default.png" width="80" height="80" style="margin-left: 20px"
id="id_img">
</label>
<input type="file" name="file" id="id_file" style="display: none">
</div>
<input type="button" class="btn btn-success" value="提交" id="id_submit">
</form>
</div>
</div>
</div>
{% endblock %}
{% block new_js %}
<script>
//当该控件发生变化,响应该事件
$("#id_file").change(function () {
//alert(1)
//取到文件对象
var file = $("#id_file")[0].files[0]
//放到img控件上,借助于filereader 中间的东西,文件阅读器
//生成一个文件阅读器对象赋值给filereader
var filereader = new FileReader()
//把文件读到filereader对象中
//读文件需要时间,需要文件读完再去操作img
filereader.readAsDataURL(file)
filereader.onload = function () {
$("#id_img").attr(\'src\', filereader.result)
}
})
$("#id_submit").click(function () {
//ajax 上传文件
var formdata = new FormData()
//一个一个往里添加,稍微复杂,用简便方法
// formdata.append(\'name\',$("#id_name").val())
// formdata.append(\'pwd\',$("#id_pwd").val())
//简便方法
//form 对象的serializeArray,它会把form中的数据包装到一个对象中(不包含文件)
var my_form_data = $("#my_form").serializeArray()
//console.log(typeof my_form_data)
//console.log(my_form_data)
//jq的循环,传两个参数,第一个是要循环的对象,第二个参数是一个匿名函数
$.each(my_form_data, function (k, v) {
{#console.log(k)#}
{#console.log(v)#}
formdata.append(v.name, v.value)
})
formdata.append(\'avatar\', $("#id_file")[0].files[0])
$.ajax({
url: \'/register/\',
type: \'post\',
processData: false, //告诉jQuery不要去处理发送的数据
contentType: false,// 告诉jQuery不要去设置Content-Type请求头
data: formdata,
success: function (data) {
//console.log(data)
if (data.code == 100) {
location.href = \'/login/\'
} else if (data.code == 101) {
$.each(data.msg, function (k, v) {
console.log(k)
console.log(v)
$("#id_" + k).next().html(v[0])
if (k == \'__all__\') {
$("#id_re_pwd").next().html(v[0])
}
})
}
//定时器
setTimeout(function () {
$(".error").html("")
}, 3000)
}
})
})
</script>
{% endblock %}
登入login.html
{% extends \'template.html\' %}
{% block title_text %}
登入
{% endblock %}
{% block new_css %}
<style>
.img-code:hover{
}
</style>
{% endblock %}
{% block data %}
<div class="container-fluid center-block">
<div class="row">
<div class="col-md-6 col-md-offset-3">
{% csrf_token %}
<h1>登陆</h1>
<form action="">
<div class="form-group">
<label for="id_name">用户名</label>
<input type="text" name="name" id="id_name" class="form-control">
</div>
<div class="form-group">
<label for="pwd">密码</label>
<input type="password" name="pwd" id="pwd" class="form-control">
</div>
<div class="form-group">
<label for="id_code">验证码</label>
<div class="row">
<div class="col-md-6">
<input type="text" name="code" id="id_code" class="form-control">
</div>
<div class="col-md-6" id="img">
<img src="/get_code/" height="40" width="240" class="img-code">
</div>
</div>
</div>
<input type="button" value="提交" class="btn-success" id="up_data">
<span style="color: red" id="msg"></span>
</form>
</div>
</div>
</div>
{% endblock %}
{% block new_js %}
<script>
$(\'.img-code\').click(function () {
var img_code_src = $(this).attr(\'src\');
img_code_src += \'1\';
console.log(img_code_src);
$(this).attr(\'src\', img_code_src)
})
</script>
<script>
$(\'#up_data\').click(function () {
$.ajax({
type: \'post\',
url: \'/login/\',
data: {
\'name\': $(\'#id_name\').val(),
\'pwd\': $(\'#pwd\').val(),
\'code\': $(\'#id_code\').val(),
\'csrfmiddlewaretoken\': \'{{csrf_token}}\'
},
success: function (msg) {
console.log(msg);
$(\'#msg\').text(msg);
if (msg == \'登入成功\') {
console.log(\'sb\');
}
}
})
})
</script>
{% endblock %}
首页index.html
{% extends \'template.html\' %}
{% block title_text %}
首页
{% endblock %}
{% block new_css %}
{% endblock %}
{% block data %}
<div class="msg" style=" font-size: 100px;
text-align: center;
color: red;
}">欢迎光临
</div>
{% endblock %}
{% block new_js %}
{% endblock %}
进货add.html
{% extends \'template.html\' %}
{% block title_text %}
添加商品
{% endblock %}
{% block new_css %}
{% endblock %}
{% block data %}
<form action="" method="post">
{% csrf_token %}
<label for="name">商品名</label>
<input type="text" id="name" name="name">
<label for="Stock_volume">商品数量</label>
<input type="text" id="Stock_volume" name="Stock_volume">
<label for="batch">商品批号</label>
<input type="text" id="batch" name="batch">
<label for="cost">商品单价(元)</label>
<input type="text" id="cost" name="cost">
<input type="button" value="提交" class="custom_button">
</form>
<div class="msg"></div>
{% endblock %}
{% block new_js %}
<script>
var new_show_msg =\'\'
var custom_button = document.querySelector(\'.custom_button\');
custom_button.onclick = function () {
var name = document.querySelector(\'#name\').value;
var Stock_volume = document.querySelector(\'#Stock_volume\').value;
var batch = document.querySelector(\'#batch\').value;
var cost = document.querySelector(\'#cost\').value;
var show_msg = \'商品名:\' + name + \'\n批号:\' + batch + \'\n数量:\' + Stock_volume + \'\n成本单价:\' + cost+\'元\'
if (name && Stock_volume && batch && cost) {
if (confirm(show_msg)){
$.ajax(
{
type: \'post\',
url: \'/add/\',
data: {
\'name\': name,
\'Stock_volume\': Stock_volume,
\'batch\': batch,
\'cost\': cost,
\'csrfmiddlewaretoken\': \'{{csrf_token}}\'
}, success: function (msg) {
var show = document.querySelector(\'.msg\')
new_show_msg += \'<div style="white-space: pre-line;border: 2px solid;position: inherit;"><div style="color:red">\'+msg+\'</div>\'+show_msg+\'</div>\'
show.innerHTML=new_show_msg
}
}
)
}
} else {
alert(\'内容不能为空\')
}
}
</script>
{% endblock %}
销售sales.html
{% extends \'template.html\' %}
{% block title_text %}
删除商品库存
{% endblock %}
{% block new_css %}
{% endblock %}
{% block data %}
<table class="table table-hover">
<thead>
<tr>
<th></th>
<th>商品名</th>
<th>商品批号</th>
<th>库存</th>
<th>总成本</th>
<th>总销售额</th>
<th>进货总数量</th>
<th>销售量总数量</th>
<th>退货总数量</th>
<th>销售</th>
</tr>
</thead>
<tbody>
{% for Commodity_obj in Commodity_list %}
<tr>
<th scope="row">1</th>
<td>{{ Commodity_obj.name }}</td>
<td>{{ Commodity_obj.batch }}</td>
<td>{{ Commodity_obj.inventory }}</td>
<td>{{ Commodity_obj.cost }}</td>
<td>{{ Commodity_obj.selling_price }}</td>
<td>{{ Commodity_obj.quantity_in }}</td>
<td>{{ Commodity_obj.sales_volume }}</td>
<td>{{ Commodity_obj.return_volume }}</td>
<td>
<button class="del_button" inventory={{ Commodity_obj.inventory }} batch={{ Commodity_obj.batch }} c_id={{ Commodity_obj.id }}>出售</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
{% block new_js %}
<script>
var del_button = document.querySelectorAll(\'.del_button\')
for (var index = 0; index < del_button.length; index++) {
del_button[index].onclick = function () {
if (confirm(\'是否确定出售\')) {
var selling_price = parseFloat(prompt(\'出售价格\'));
var sales_volume = parseInt(prompt(\'出售数量\'));
var c_id = this.getAttribute(\'c_id\');
var inventory = this.getAttribute(\'inventory\');
if(sales_volume<=inventory){
$.ajax({
url: /sales/,
type: \'post\',
data: {
\'c_id\': c_id,
\'selling_price\': selling_price,
\'sales_volume\': sales_volume,
\'csrfmiddlewaretoken\': \'{{csrf_token}}\'
},
success: function (msg) {
alert(msg)
window.location.replace(\'/sales/\')
}
})
}else {
alert(\'库存不足\')
}
}
}
}
</script>
{% endblock %}
退货return.html
{% extends \'template.html\' %}
{% block title_text %}
删除商品库存
{% endblock %}
{% block new_css %}
{% endblock %}
{% block data %}
<table class="table table-hover">
<thead>
<tr>
<th></th>
<th>商品名</th>
<th>商品批号</th>
<th>库存</th>
<th>总成本</th>
<th>总销售额</th>
<th>进货总数量</th>
<th>销售量总数量</th>
<th>退货总数量</th>
<th>退货</th>
</tr>
</thead>
<tbody>
{% for Commodity_obj in Commodity_list %}
<tr>
<th scope="row">1</th>
<td>{{ Commodity_obj.name }}</td>
<td>{{ Commodity_obj.batch }}</td>
<td>{{ Commodity_obj.inventory }}</td>
<td>{{ Commodity_obj.cost }}</td>
<td>{{ Commodity_obj.selling_price }}</td>
<td>{{ Commodity_obj.quantity_in }}</td>
<td>{{ Commodity_obj.sales_volume }}</td>
<td>{{ Commodity_obj.return_volume }}</td>
<td>
<button class="del_button" inventory={{ Commodity_obj.inventory }} batch={{ Commodity_obj.batch }} c_id={{ Commodity_obj.id }}>退货</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
{% block new_js %}
<script>
var del_button = document.querySelectorAll(\'.del_button\')
for (var index = 0; index < del_button.length; index++) {
del_button[index].onclick = function () {
if (confirm(\'是否确定退货\')) {
var selling_price = parseFloat(prompt(\'退货单价\'));
var sales_volume = parseInt(prompt(\'退货数量\'));
var c_id = this.getAttribute(\'c_id\');
var inventory = this.getAttribute(\'inventory\');
if(sales_volume<=inventory){
$.ajax({
url: /return/,
type: \'post\',
data: {
\'c_id\': c_id,
\'selling_price\': selling_price,
\'sales_volume\': sales_volume,
\'csrfmiddlewaretoken\': \'{{csrf_token}}\'
},
success: function (msg) {
alert(msg)
window.location.replace(\'/return/\')
}
})
}else {
alert(\'库存不足\')
}
}
}
}
</script>
{% endblock %}
删除商品del.html
{% extends \'template.html\' %}
{% block title_text %}
删除商品库存
{% endblock %}
{% block new_css %}
{% endblock %}
{% block data %}
<table class="table table-hover">
<thead>
<tr>
<th></th>
<th>商品名</th>
<th>商品批号</th>
<th>库存库存</th>
<th>总成本</th>
<th>总销售额</th>
<th>进货总数量</th>
<th>销售量总数量</th>
<th>退货总数量</th>
<th>是否删除</th>
</tr>
</thead>
<tbody>
{% for Commodity_obj in Commodity_list %}
<tr>
<th scope="row">1</th>
<td>{{ Commodity_obj.name }}</td>
<td>{{ Commodity_obj.batch }}</td>
<td>{{ Commodity_obj.inventory }}</td>
<td>{{ Commodity_obj.cost }}</td>
<td>{{ Commodity_obj.selling_price }}</td>
<td>{{ Commodity_obj.quantity_in }}</td>
<td>{{ Commodity_obj.sales_volume }}</td>
<td>{{ Commodity_obj.return_volume }}</td>
<td>
<button class="del_button" c_id={{ Commodity_obj.id }}>删除</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
{% block new_js %}
<script>
var del_button = document.querySelectorAll(\'.del_button\')
for (var index = 0; index < del_button.length; index++) {
del_button[index].onclick = function () {
if (confirm(\'是否确定删除\')) {
var c_id = this.getAttribute(\'c_id\');
$.ajax({
url: /del/,
type: \'post\',
data: {
\'c_id\': c_id,
\'csrfmiddlewaretoken\': \'{{csrf_token}}\'
},
success: function (msg) {
alert(msg)
window.location.replace(\'/del/\')
}
})
}
}
}
</script>
{% endblock %}
展示show.html
{% extends \'template.html\' %}
{% block title_text %}
查看商品
{% endblock %}
{% block new_css %}
{% endblock %}
{% block data %}
<table class="table table-hover">
<thead>
<tr>
<th></th>
<th>商品名</th>
<th>批号</th>
<th>库存库存</th>
<th>总成本</th>
<th>总销售额</th>
<th>进货总数量</th>
<th>销售量总数量</th>
<th>退货总数量</th>
</tr>
</thead>
<tbody>
{% for Commodity_obj in Commodity_list %}
<tr>
<th scope="row">1</th>
<td>{{ Commodity_obj.name}}</td>
<td>{{ Commodity_obj.batch}}</td>
<td>{{ Commodity_obj.inventory}}</td>
<td>{{ Commodity_obj.cost}}</td>
<td>{{ Commodity_obj.selling_price}}</td>
<td>{{ Commodity_obj.quantity_in}}</td>
<td>{{ Commodity_obj.sales_volume}}</td>
<td>{{ Commodity_obj.return_volume}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
{% block new_js %}
{% endblock %}
展示删除show_del.html
{% extends \'template.html\' %}
{% block title_text %}
删除商品查看及还原
{% endblock %}
{% block new_css %}
{% endblock %}
{% block data %}
<table class="table table-hover">
<thead>
<tr>
<th></th>
<th>商品名</th>
<th>商品批号</th>
<th>库存库存</th>
<th>总成本</th>
<th>总销售额</th>
<th>进货总数量</th>
<th>销售量总数量</th>
<th>退货总数量</th>
<th>是否还原</th>
</tr>
</thead>
<tbody>
{% for Commodity_obj in Commodity_list %}
<tr>
<th scope="row">1</th>
<td>{{ Commodity_obj.name }}</td>
<td>{{ Commodity_obj.batch }}</td>
<td>{{ Commodity_obj.inventory }}</td>
<td>{{ Commodity_obj.cost }}</td>
<td>{{ Commodity_obj.selling_price }}</td>
<td>{{ Commodity_obj.quantity_in }}</td>
<td>{{ Commodity_obj.sales_volume }}</td>
<td>{{ Commodity_obj.return_volume }}</td>
<td>
<button class="del_button" c_id={{ Commodity_obj.id }}>还原</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
{% block new_js %}
<script>
var del_button = document.querySelectorAll(\'.del_button\')
for (var index = 0; index < del_button.length; index++) {
del_button[index].onclick = function () {
if (confirm(\'是否确定还原\')) {
var c_id = this.getAttribute(\'c_id\');
$.ajax({
url: /show_del/,
type: \'post\',
data: {
\'c_id\': c_id,
\'csrfmiddlewaretoken\': \'{{csrf_token}}\'
},
success: function (msg) {
alert(msg)
window.location.replace(\'/show_del/\')
}
})
}
}
}
</script>
{% endblock %}
五.自动生成项目目录树状图
import os
def dirsTree():
PATH = os.path.dirname(__file__)
print(PATH)
lis = os.listdir(PATH)
if lis != None:
for a in lis:
print(f\'|___{a}\')
if \'.\' not in a:
a_path = os.path.join(PATH,a)
lis_2 = os.listdir(a_path)
if lis_2 != None:
for b in lis_2:
if b != \'__pycache__\':
print(f\'| |___{b}\')
if __name__ == \'__main__\':
dirsTree()
#弄了两级也没有用递归来做啦