1.先搭建django虚拟环境
pip install virtualenv
在创建项目的文件夹中打开doc,virtualenv env
激活虚拟环境env\Script\activate.bat
下载django pip install django == 2.1.2
剩下的在pycharm中下载
**导出包列表
pip freeze > package.txt
**使用导好的列表安装django
pip install -r package.txt
# 创建登录装饰器
# 判断用户是否已登录,没有登录的话就重定向到登录界面
def login_docorator(func):
def inner(request):
uesrname = request.session.get('username')
if username:
return func(request)
else:
return redirect('/seller/login/')
return inner
# md5加密 , 不可逆算法
import hashlib
def pwd_jm(password):
md5 = hashlib.md5()
md5.update(password.encode())
result = md5.hexdigest()
return result
# 注册功能,可以使用form表单
from django import forms
form django.forms import widgets
# 创建form表单类
class RegisterForm(forms.Form):
username = forms.CharField(
label = '用户名',
required = True,
min_length = 3,
widget = widgets.TextInput(attrs={''placeholder': '用户名', 'class': 'layui-input''})
)
password = forms.CharField(
label = '密码',
required = True,
min_length = 3,
widget = widgets.TextInput(attrs={''placeholder': '密码', 'class': 'layui-input''})
)
nickname = forms.CharField(
label = '昵称',
required = True,
min_length = 3,
widget = widgets.TextInput(attrs={''placeholder': '昵称', 'class': 'layui-input''})
)
picture = forms.CharField(
label = '头像',
required = True,
widget = widgets.FileInput(attrs={''placeholder': '头像', 'class': 'layui-input''})
)
# 注册功能
# 导入时间模块 , 给上传的头像加时间戳确保上传的图片名称不一样
import time
def register(request):
registerform = RegisterForm()
if request.method == 'POST':
registerform = RegisterForm(request.POST,request.FILES)
if registerform.is_valid():
data = registerform.cleaned_data
username = data.get('username')
nickname = data.get('nickname')
password = data.get('password')
picture = request.FILES.get('picture')
time_temp = time.time()
path = 'static/touxiang/'+str(time_temp)+'_'+picture.name
with open(path,mode='wb') as f:
for content in picture.chunks()
f.write(content)
# 需使用加密后的密码存入数据库
password = pwd_jm(password)
models.Seller.objects.create(
name=username,
nickname=nickname,
password=password,
picture='touxiang/' + str(time_temp) + '-' + picture.name
)
return redirect('/seller/login/')
return render(request, 'seller/register.html', {'registerform': registerform})
# 创建登录时提交的form表单类
class LoginForm(form.Form):
username = forms.CharField(
label='用户名',
required=True,
min_length=3,
widget=widgets.TextInput(attrs={'placeholder': '用户名', 'class': 'layui-input'})
)
password = forms.CharField(
label='密码',
required=True,
min_length=3,
widget=widgets.PasswordInput(attrs={'placeholder': '密码', 'class': 'layui-input'})
)
# 登录功能
def login(request):
loginForm = LoginForm()
error_msg = ''
if request.method == "POST":
loginForm = LoginForm(request.POST)
if loginForm.is_valid():
data = loginForm.cleaned_data
username = data.get('username')
password = data.get('password')
pwd = pwd_jm(password)
ret = models.Seller.objects.filter(name=username, password=pwd)
if ret:
# 设置session为了登录验证
request.session['username'] = username
nickname = ret[0].nickname
request.session['nickname'] = nickname
request.session['seller_id'] = ret[0].id
return redirect('/seller/index/')
else:
error_msg = '用户名或密码错误'
return render(request, 'seller/login.html', {'error_msg': error_msg})
# 导入模块 , 在页面显示登录时间
import datetime
# 加上装饰器
@login_docorator
def index(request):
time = datetime.datetime.now()
seller_id = request.session.get('seller_id')
seller_obj = models.Seller.objects.get(id = seller_id)
return render(request,'seller/index.html',locals())
# 退出登录
@login_docorator
def logout(request):
# 清除session
request.session.clear()
# 重定向到登录界面
return redirect('/seller/login/')
# 商品类增加
def type_add(request):
error_msg = ''
if request.method == 'POST':
type_name = request.POST.get('type_name')
if type_name:
# 查询数据库是否重名
ret = models.GoodsType.objects.filter(name=type_name)
if not ret:
models.GoodsType.objects.create(name=type_name)
return redirect('/seller/goods_type_list/')
else:
error_msg='此类型已经存在'
return render(request,'seller/type_add.html',{'error_msg':error_msg})
# 为商品添加操作添加ajax请求,失去鼠标触点就发送ajax请求
from django.http import JsonResponse
def type_add_ajax(request):
dec = {'status':'true'}
name = request.GET.get('name')
type_obj = models.GoodsType.objects.filter(name=name)
if type_obj:
dic['status] = 'false'
return JsonResponse(dic)
def goods_type_list(request):
goods_type_obj_list = models.GoodsType.objects.all()
return render(request,'seller/type_list.html',locals())
def goods_type_delete(request):
id = request.GET.get('id')
models.GoodsType.objects.get(id = id).delete()
return redirect('/seller/goods_type_list/')
def goods_type_change(request):
if request.method == 'POST':
name = request.POST.get('type_name')
id = request.POST.get('id')
goods_type_obj = models.GoodsType.objects.get(id=id)
goods_type_obj.name = name
goods_type_obj.save()
return redirect('/seller/goods_type_list/')
else:
id = request.GET.get('id')
goods_type_obj = models.GoodsType.objects.get(id=id)
return render(request,'seller/type_change.html',{'goods_type_obj':goods_type_obj})
商品添加:
1.创建商品类,图片类
商品与商品类一对多
商品与商家一对多
商品与图片一对多
2.将商品类型导入商品添加页码
3.后台接受页面提交的数据
create新数据
获取图片(多个)
将图片存在后台static中
将图片路径保存到图片类数据库中
商品展示:
1.获取当前账户id
2.获取当前账户的商品
商品删除:
1.先删除图片的相关信息(后台及数据库)
使用os.remove(path)
2.后删除商品相关信息
商品修改:
1.将当前商品信息传入页面
2.获取页面传入的数据并更新商品数据库
3.删除原有商品图片
4.保存新上传的图片信息
用户界面:
需要导入卖家模型类 , 卖家视图的函数(密码加密等)
一.创建首页
将所有商家商品导入
点击单个商品进入该商品详情,同时有其他商品链接
方法一:
正常操作
goods_obj_list = seller_models.Goods.objects.all()
return render(request,'buyer/index.html',{'goods_obj_list':goods_obj_list})
方法二:
在后台写好前端的逻辑
def index(request):
goods_image_obj_list = []
goods_obj_list = seller_models.Goods.objects.all()
for goods_obj in goods_obj_list:
image_obj = goods_obj.goodimages_set.first()
image_path = image_obj.img_address.name
dic = {'goods_obj':goods_obj,'image_path':image_path}
goods_image_obj_list.append(dic)
return render(requst,'buyer/index.html',{'goods_image_obj_list':goods_image_obj_list})
二.用户注册及登录
正常操作
注意设置session及ajax验证
设置session:
1.方法一
obj = models.Buyer.objects.filter(name=uesrname,password=password).first()
if obj:
request.session['name'] = obj.name
2.方法二
querset = models.Buyer.objects.filter(name=uesrname,password=password)
if querset:
request.session['name'] = querset[0].name
删除session
删除session
request.session.flush() # 将整个session删除
request.session.clear() # 将session的内容删除
设置session失效时间
request.session.set_expiry(value) # value为失效时间值
设置cookie
response = redirect('/buyer/index/')
response.set_cookie('name',querset[0].name)
return response
删除cookie
response.set_cookie('username',max_age=0) # 设置失效时间
response.delete_cookie('username') # 直接删 除
三.登录后个人中心显示
显示收货地址信息及其曾删改查操作
四.购物车
def car_jump(request):
# 1.判断用户是否已登录
buyer_id = request.session.get(buyer_id)
if buyer_id:
# 2.若是先加入购物车后登录的,获取Session或cookie中数据并去数据库调用相关数据
if request.method == 'GET':
# 从cookie中获取商品id和数量
goods_id = request.COOKIES.get('goods_id')
count = request.COOKIES.get('count')
# 查询数据库, 将信息返回给页面
goods_obj = seller_models.Goods.objects.get(id=goods_id)
goods_name = goods_obj.good_name
goods_image_path = goods_obj.goodimages_set.first().img_address
goods_price = goods_obj.goods_xprice
all_goods_price = int(goods_price) * int(count)
buyer_car_obj = models.Car.objects.filter(goods_id=goods_id,buyer_id=buyer_id).first()
# 判断该商品是否已加入购物车,若已加入则修改数量
if buyer_car_obj:
buyer_car_obj.goods_num += int(count)
buyer_car_obj.save()
else:
models.Car.objects.create(
goods_id=goods_id,
goods_name=goods_name,
goods_picture=goods_img_path,
goods_price=goods_price,
goods_num=count,
buyer_id=buyer_id
)
# 删除cookie
response = render(request,'buyer/car_jump.html',locals())
response.delete_cookie('goods_id')
response.delete_cookie('count')
return response
# 3.若是已登录后添加购物车的,按正常操作
else:
goods_id = request.GET.get('id')
count = request.POST.get('count') # 商品数量
goods_name = request.POST.get('goods_name') # 商品名称
goods_price = request.POST.get('goods_cprice') # 商品现价
goods_img_path = request.POST.get('goods_img_path') # 商品缩略图
all_goods_price = int(goods_price) * int(count)
buyer_car_obj = models.Car.objects.filter(goods_id=goods_id,buyer_id=buyer_id).first()
# 判断该商品是否已加入购物车,若已加入则修改数量
if buyer_car_obj:
buyer_car_obj.goods_num += int(count)
buyer_car_obj.save()
else:
models.Car.objects.create(
goods_id=goods_id,
goods_name=goods_name,
goods_picture=goods_img_path,
goods_price=goods_price,
goods_num=count,
buyer_id=buyer_id
)
return render(request,'buyer/car_jump.html',locals())
# 4.若未登录,获取传过来的数据,保存在session中或cookie中,重定向到登录界面
goods_id = request.GET.get('goods_id')
count = request.POST.get('count')
response = redirect('/buyer/login/')
response.set_cookie('goods_id',goods_id)
response.set_cookie('count',count)
return response
购物车列表显示 , 删除 , 清空
五.确认订单
创建订单模型类和订单中商品的详情模型类
class Order(models.Model):
order_num = models.CharField(max_length = 32) # 订单号
order_time = models.DateField()
order_status = models.CharField(max_length=32) # 订单状态
order_total = models.FloatField()# 商品总价
buyer = models.ForeignKey(to='Buyer',on_delete=models.CASCADE)
address = models.ForeignKey(to='Address',on_delete=models.CASCADE)
class OrderGoods(models.Model):
# 跟购物车的模型类一样 , 只是这里跟订单类建立了一对多关系
goods_name = models.CharField(max_length=32) # 商品名字
goods_picture = models.CharField(max_length=32) # 商品缩略图
goods_num = models.IntegerField() # 商品数量
goods_price = models.FloatField() # 商品单价
goods_id = models.IntegerField() # 商品id
order = models.ForeignKey(to='Order',on_delete=models.CASCADE)
import random , time , datatime
# 生成随机数拼接订单号
def get_random_num():
num = random.randint(1000,9999)
return num
def enter_order(request):
address_id = rquest.POST.get('address')
address_obj = models.Address.objects.get(id = address_id)
times = datetime.datetime.now()
now_time = times.strftime('%Y-%m-%d')
new_buycar_list = []
goods_all_price = 0
# 获取后台传来的数据
for key,value in request.POST.items():
if key.startswith('name_'):
buycar_obj = models.Car.objects.get(id=value)
goods_xiaoji = int(buycar_obj.goods_num)*fioat(buycar_obj.goods_price)
dic = {'buyer_obj':buycar_obj,'goods_xiaoji':goods_xiaoji}
new_buycar_list.append(dic)
goods_all_price += goods_xiaoji
# 保存到订单数据库
order_obj = models.Order.objects.create(
order_num = now_time + str(get_random_num()),
order_time = now_time,
order_status = '1',
order_total = goods_all_price,
buyer_id = request.session.get('buyer_id'),
address = address_obj,
)
# 保存订单中的商品详情
for new_buycar_dic in new_buycar_list:
buycar_obj = new_buycar_dic.get('buycar_obj')
models.OrderGoods.objects.create(
goods_id = buycar_obj.goods_id,
oods_name=buycar_obj.goods_name,
goods_num=buycar_obj.goods_num,
goods_price=buycar_obj.goods_price,
goods_picture=buycar_obj.goods_picture,
order=order_obj
)
return render(request,'buyer/enter_order.html',locals())
六.添加支付宝
加载第三方模块
python-alipay-sdk
教程网址:https://github.com/fzlee/alipay/blob/master/README.zh-hans.md
蚂蚁金服官网入驻 , 使用沙箱支付宝 , 下载RSA签名工具生成秘钥和公钥
from alipay import AliPay
def alipay_method(request):
order_num = request.GET.get('order_num')
total = request.GET.get('total')
# 商家私有秘钥
app_private_key_string = """-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAyxlAeCqSs3qmB6zIlhAmqRQsetRM3H176CsnFTdBzlBRRKf7l266QHgWmHFovSqw4pAUnEBRJYE1slbLg6Mn3TzNhyeJSt+jZC9l2Ylz+NVOqmpCDPzMPbhnODrt2qgiNcoqjG3N9OEQqHACJ32g2Ei/oiS5uAD7x/G0WigzAaMkc0yTCf1gCg7AeUaCOK/+Pn5P+JPdjzwMDTgB17k/aLZwLWzN4bAHdgT21aYFeGtgn2V4ce78KjA9ekZITFraTY2xbl7ofcVXi/dXViNQEVqIOKcoAX5CUdGou3MEfkeL2pgRmvdHLCS4cFkM8DRwMA+XArbBp3SkuOXuXeYpJQIDAQABAoIBAQCajMG5b7Qo7ekQKBSP1QSGX3qlkY5XrwmuF8Bq7Zye8hGVrDrQ9oq26mtPX+WzJZxrG/cDHBJj9to0tsWxi2OXgGBqO9TG7D26zDK2AloE/dUZ6zgOCAUn5n5tlLJRVOaLhicwq5IxiV8SvgF1qazPSTTCny3QbrcqZKy4eqSt1eouhkjgqY7o+xuYsy9dAGW958U0SGMvLrb1erTF3aEXDxFRHFZTCwyWmjYjwUxBm8BKQRXIuzagYOkFQmRJT05CbO8IWoc8JBM+00dKxD7yeyKtTifQY2FzqtwCERuMzBrwz0wo1G5t5mJ9ZERc0u4W9OfJl/6lppI7I1nbmNohAoGBAPohxh3jqes9WrN+6VhH1VtCPU+EGXzOXdHuRCpMMhViP5tunu0BmigI0Cafv49Bn1FyCNG1xZwlsE7+M6Npj35+V/BQmhUGBv8DYnf/qXLdjM5NavsD8/cGDMrhy9LUHhWy53HdHx/cusZLHLoolpfZyXPXOxrFCDCm39o1ddqJAoGBAM/dAiqumJKLQ79tCV0BYRKPXBrQXX2j7rgr/h9gb/4wXwVoViStq4DqQ28izWVl5QMziQh7sXc+EkngRYmSzhy9FrDVCHVpu7skxe9zaMwpUOPcQIHxWlcWN6hp3Fh3pcEN/I9qzlPDLLGq/RqE2NOUPhWqt3qGWPfc4FQyCMK9AoGBAOAhC0kVCtjC7VcRTT3RgBh5zj5F/CCdOew2N9Y+2FHY6233PWjZmqxs2TcCxb8z6fIs4EIpQpycGNNvbA3tNKr/wwSO9MIJ2JMBEWa9K7TFWLozHL032Y9rWGMi2GRdtWd0G3cn0A/Y1XOBMoiMfgQrHhwyq79c9e3CWatJZAUhAoGAGZ72O2iV6co8qYW5F7upyW3ePnfcbjYcoJrbkeaDJ2Oy8qmvpIm7kAJQGYzCoHL0zXY2t9L3Rulhu7VnHNP5j9VGzLkVd9N2jlS0CRXCnxegntVxJhMnvYBBkAKsZEMrLSaaMNtLX0u5YJTg6bniOAIXvPfz8ahJoxOYmwgnyEkCgYEAncNyAiBPS5nFcJq0yxtaqdfAfIW+h6SxXBWkdI66bK+YEZ3hvoW42z4cyuo9WbdoKJ4UKP8m0UAQ+qF6gxTvo5jpbaxgYDRpzTbj4B5exUqvH4jyVjZ+U1ASoC/MOVw+HApvdLpcnd9kcIRfNk8FuA6Fvj6UmQJLsc0pA+b19KI=
-----END RSA PRIVATE KEY-----"""
# 支付宝返回的支付宝公钥
alipay_public_key_string = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlTKZzALbl67tl//jq7pWyjUsRe887eogf67LLFkR+AnDN6CRtkG5VIlHOQrL3xgBKZkrT6LeOFIyBy82fRM5yXOTJsyqxfwM5Bi+2sOs2QpzonkxPDFQUPmp8svgX7suXtAIZPNDfpVMb3AZ5JkpczGfFE8bEMo0CoVbpQbPLdjFFlTfoPfEmj6jWVTO7StSBrNwTfT1VxcGjtlTao73WQ3NquWDzxdkvsb3Jq5gB2hOsCU5vB71sedQWtbuFHdulZK9PUytn9xd0r5chZyN0+k+bGrEQD7tuj1rnDkJEGF/bCGK9Z7U1E7+2dRo4u1WmQ+T1Y35OYyxoc3MAr+jiQIDAQAB
-----END PUBLIC KEY-----"""
alipay = AliPay(
appid="2016101300679685", # 看用户信息
app_notify_url=None, # 默认回调url
app_private_key_string=app_private_key_string,
# 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
alipay_public_key_string=alipay_public_key_string,
sign_type="RSA2", # RSA 或者 RSA2 , 看用户信息
debug=True, # 默认False
)
order_string = alipay.api_alipay_trade_page_pay(
out_trade_no=str(order_num), # 订单号
total_amount=str(total), # 总价
subject='水果商城', # 标题
return_url=None,
notify_url=None, # 可选, 不填则使用默认notify url
)
return redirect('https://openapi.alipaydev.com/gateway.do?' + order_string)
七.邮箱验证
# 设置settings
EMAIL_HOST_USER = '你的163邮箱'
EMAIL_HOST_PASSWORD = '邮箱授权码设置的密码'
EMAIL_USE_SSL = True
EMAIL_HOST = 'smtp.163.com'
EMAIL_PORT = 994
# 创建邮箱模型类用于储存邮箱账户,验证码,时间戳
class EmailVaild(models.Model):
email_name = models.CharField(max_length=32)
value = models.CharField(max_length=32)
time = models.DateTimeField()
from django.core.mail import EmailMultiAlternatives
from django.http import JsonResponse
def send_message(request):
result = {'status':'error','data':''}
if request.method == 'GET':
email_name = request.GET.get('email')
if email_name:
try:
subject = '全球生鲜商城验证码'
yzm = get_random_num()
text_content = str(yzm)
msg = EmailMultiAlternatives(subject,text_content,'你的邮箱',[email_name])
msg.send()
eccept Exception as e:
# 有异常执行
result['data'] = str(e)
else:
result['status'] = 'success'
result['data'] = 'success'
models.EmailVaild.object.create(
email_name = email_name,
value = yzm,
time = datetime.datetime.now()
)
finally:
return JsonResponse(result)
return redirect('/buyer/register_email/')
def register_email(request):
error_msg={}
if request.method == 'POST':
email_name = request.POST.get('emailname')
code = request.POST.get('code')
userpass = request.POST.get('userpass')
email_obj = models.EmailVaild.objects.filter(email_name=email_name).first()
if email_obj:
if code == email_obj.value:
db_time = time.mktime(email_obj.time.timetuple())
now_time = time.time()
if now_time-db_time<180: # 3min
models.Buyer.objects.create(
name = email_name,
password = pwd_jm(userpass)
)
email_obj.delete()
return redirect('/buyer/login/')
else:
error_msg['yam_sx'] = '验证码失效'
else:
error_msg['yzm_error'] == '验证码错误'
else:
error_msg['email_error'] == '邮箱不存在'
return render(request,'buyer/register_email',{'error_msg':error_msg})
八.电话短信验证
# 短信验证http://www.ihuyi.com/
官网接口文档修修改改就ok
其他步骤同上