周末手撸管理系统(一)
已完成
大体模板
- 用户登入注册
明天加商品订单商品进去
完成效果图
注册
登入
1.首先进行设置
settings.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',
]
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.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# 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 = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# 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")
2.创建模型以及form组件
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
# 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
userinfo_form.py
from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError
from drf_api import models
class Register(forms.Form):
username=forms.CharField(max_length=18,min_length=3,label="用户名",
error_messages={'max_length':'太长了',
'min_length':'太短了',
'required':'不能为空'},
widget=widgets.TextInput(attrs={'class':'form-control'}),
)
password=forms.CharField(max_length=18,min_length=3,label="密码",
error_messages={'max_length':'太长了',
'min_length':'太短了',
'required':'不能为空'},
widget=widgets.PasswordInput(attrs={'class':'form-control'}),
)
re_pwd=forms.CharField(max_length=18,min_length=3,label="确认密码",
error_messages={'max_length':'太长了',
'min_length':'太短了',
'required':'不能为空'},
widget=widgets.PasswordInput(attrs={'class':'form-control'}),
)
email=forms.EmailField(max_length=18,min_length=3,label="邮箱",
error_messages={'max_length':'太长了',
'min_length':'太短了',
'required':'不能为空'},
widget=widgets.EmailInput(attrs={'class':'form-control'}),
)
def clean_username(self):
name=self.cleaned_data.get('username')
user=models.UserInfo.objects.filter(username=name).first()
if user:
raise ValidationError('用户已经存在')
else:
return name
def clean(self):
pwd=self.cleaned_data.get('password')
r_pwd=self.cleaned_data.get('re_pwd')
if pwd==r_pwd:
return self.cleaned_data
else:
raise ValidationError('两次密码不一致')
3.页面
母版
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>
.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_right{
float: right;
line-height: 100px;
}
.body {
position: fixed;
top: 100px;
left: 0;
bottom: 20px;
width: 100%;
}
.body_left {
position: fixed;
top: 100px;
left: 0;
bottom: 20px;
width: 20%;
background: white;
}
.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_right">
<a href="http://127.0.0.1:8000/login/">登入</a>
<a href="http://127.0.0.1:8000/register/">注册</a>
</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="#">查看商品</a></li>
<li role="presentation"><a href="#">添加商品</a></li>
<li role="presentation"><a href="#">删除商品</a></li>
</ul>
<ul class="nav nav-pills nav-stacked nav-pills-stacked-example">
<li role="presentation" class="active"><a>订单管理</a></li>
<li role="presentation"><a href="#">查看订单</a></li>
<li role="presentation"><a href="#">添加订单</a></li>
<li role="presentation"><a href="#">删除订单</a></li>
<li role="presentation"><a href="#">订单号快速查询</a></li>
</ul>
</div>
<div class="body_right">
{% block data %}
{% endblock %}
</div>
</div>
<div class="footer"></div>
</body>
</html>
{% block new_js %}
{% endblock %}
登入
login.html
{% extends 'template.html' %}
{% block title_text %}
登入
{% endblock %}
{% block new_css %}
{% 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');
window.location.replace('http://www.baidu.com');
}
}
})
})
</script>
{% 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">
<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 () {
var file = $("#id_file")[0].files[0]
var filereader = new FileReader()
filereader.readAsDataURL(file)
filereader.onload = function () {
$("#id_img").attr('src', filereader.result)
}
})
$("#id_submit").click(function () {
var formdata = new FormData()
var my_form_data = $("#my_form").serializeArray()
$.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,
contentType: false,
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 %}
4.路由
urls.py
from django.conf.urls import url
from django.contrib import admin
from drf_api import views
from django.views.static import serve
from .settings import MEDIA_ROOT
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^register/', views.register),
url(r'^login/', views.login),
url(r'^get_code/', views.get_code),
url(r'^img/(?P<path>.*)', serve, {'document_root': MEDIA_ROOT}),
]
5.视图
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
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 HttpResponse('登入成功')
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 =''
# 生成随机8位数字
for x_index in range(1, 8):
num = chr(random.randint(48, 57))
word = chr(random.randint(65, 90))
word_1 = chr(random.randint(97, 122))
text =random.choice((num, word, word_1))
draw.text((x_index * 32, 0),text, font=font)
new_text +=text
# 加点线
width = 320
height = 35
for i in range(5):
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(33):
# 画点
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())
大家周末娱乐