一、提交订单模块
1.在urls.py配置文件中定义路由
from django.conf.urls import url, include
from order import views
urlpatterns = [
# 结算订单页面
url(r'^place_order/', views.place_order, name='place_order'),
# 下单
url(r'^make_order/', views.make_order, name='make_order'),
]
2.生成随机订单号
import random
import time
# 生成订单交易号
def get_order_sn():
s = '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'
order_sn = ''
for i in range(3):
order_sn += random.choice(s)
order_sn += str(time.time())
return order_sn
3.提交订单功能
from django.http import JsonResponse
from django.shortcuts import render
from carts.models import ShoppingCart
from order.models import OrderInfo, OrderGoods
from user.models import UserAddress
from utils.function import get_order_sn
def place_order(request):
if request.method == 'GET':
user_id = request.session.get('user_id')
shop_carts = ShoppingCart.objects.filter(user_id=user_id, is_select=1)
user_address = UserAddress.objects.filter(user_id=user_id)
# 给购物车中的对象绑定一个新增的属性,其值为小计价格
all_total = 0
for carts in shop_carts:
carts.price = carts.nums * carts.goods.shop_price
all_total += carts.price
# 结算商品个数,总价
carts_count = len(shop_carts)
return render(request, 'place_order.html', {'shop_carts': shop_carts, 'carts_count': carts_count,
'all_total': all_total, 'user_address': user_address})
def make_order(request):
if request.method == 'POST':
user_id = request.session.get('user_id')
# 取购物车中勾选的商品
shop_carts = ShoppingCart.objects.filter(user_id=user_id, is_select=1)
# 计算下单的总价
order_mount = 0
for carts in shop_carts:
order_mount += carts.nums * carts.goods.shop_price
# 生成订单交易号
order_sn = get_order_sn()
# 1.创建订单
address_id = int(request.POST.get('address_id'))
user_address = UserAddress.objects.filter(pk=address_id).first()
order = OrderInfo.objects.create(user_id=user_id, order_sn=order_sn, order_mount=order_mount,
address=user_address.address, signer_name=user_address.signer_name,
signer_mobile=user_address.signer_mobile)
# 2.创建订单详情
for carts in shop_carts:
OrderGoods.objects.create(order=order, goods=carts.goods, goods_nums=carts.nums)
# 3.删除购物车中的商品
shop_carts.delete()
request.session.pop('goods')
return JsonResponse({'code': 200, 'msg': '请求成功'})
4.前端页面代码
{% extends 'base_main.html' %}
{% block title %}
天天生鲜-提交订单
{% endblock %}
{% block search %}
{% endblock %}
{% block content %}
<div class="search_bar clearfix">
{% load static %}
<a href="{% url 'goods:index' %}" class="logo fl"><img src="{% static 'images/logo.png' %}"></a>
<div class="sub_page_name fl">| 提交订单</div>
<div class="search_con fr">
<input type="text" class="input_text fl" name="" placeholder="搜索商品">
<input type="button" class="input_btn fr" name="" value="搜索">
</div>
</div>
<h3 class="common_title">确认收货地址</h3>
<div class="common_list_con clearfix">
<dl>
<dt>寄送到:</dt>
{% for user_address in user.useraddress_set.all %}
<dd><input type="radio" name="address" value="{{ user_address.id }}">{{ user_address.address }} ({{ user_address.signer_name }} 收) {{ user_address.signer_mobile }}</dd>
{% endfor %}
</dl>
<a href="{% url 'user:user_center_site' %}" class="edit_site">编辑收货地址</a>
</div>
<h3 class="common_title">支付方式</h3>
<div class="common_list_con clearfix">
<div class="pay_style_con clearfix">
<input type="radio" name="pay_style" checked>
<label class="cash">货到付款</label>
<input type="radio" name="pay_style">
<label class="weixin">微信支付</label>
<input type="radio" name="pay_style">
<label class="zhifubao"></label>
<input type="radio" name="pay_style">
<label class="bank">银行卡支付</label>
</div>
</div>
<h3 class="common_title">商品列表</h3>
<div class="common_list_con clearfix">
<ul class="goods_list_th clearfix">
<li class="col01">商品名称</li>
<li class="col02">商品单位</li>
<li class="col03">商品价格</li>
<li class="col04">数量</li>
<li class="col05">小计</li>
</ul>
{% for carts in shop_carts %}
<ul class="goods_list_td clearfix">
<li class="col01">{{ forloop.counter }}</li>
<li class="col02"><img src="/media/{{ carts.goods.goods_front_image }}"></li>
<li class="col03">{{ carts.goods.name }}</li>
<li class="col04">500g</li>
<li class="col05">{{ carts.goods.shop_price }}</li>
<li class="col06">{{ carts.nums }}</li>
<li class="col07">{{ carts.price }}</li>
</ul>
{% endfor %}
</div>
<h3 class="common_title">总金额结算</h3>
<div class="common_list_con clearfix">
<div class="settle_con">
<div class="total_goods_count">共<em>{{ carts_count }}</em>件商品,总金额<b>{{ all_total }}</b></div>
<div class="transit">运费:<b>10元</b></div>
<div class="total_pay">实付款:<b>{{ all_total | add:10 }}元</b></div>
</div>
</div>
<div class="order_submit clearfix">
<a href="javascript:;" id="order_btn">提交订单</a>
</div>
{% endblock %}
{% block footer %}
{{ block.super }}
<div class="popup_con">
<div class="popup">
<p>订单提交成功!</p>
</div>
<div class="mask"></div>
</div>
{% endblock %}
{% block js2 %}
{% csrf_token %}
<script type="text/javascript" src="{% static 'js/jquery-1.12.4.min.js' %}"></script>
<script type="text/javascript">
$('#order_btn').click(function() {
localStorage.setItem('order_finish',2);
address_radio = $('input[name="address"]')
for (var i=0; i<address_radio.length; i++){
if(address_radio[i].checked == true){
var value = address_radio[i].value
}
}
if(value){
var csrf = $('input[name="csrfmiddlewaretoken"]').val()
$.ajax({
url: '/order/make_order/',
type: 'POST',
data: {'address_id': value},
dataType: 'JSON',
headers: {'X-CSRFToken': csrf},
success: function (data) {
$('.popup p').text('订单提交成功!')
},
error: function (data) {
$('.popup p').text('订单提交失败!')
}
} )
}else{
$('.popup p').text('请选择收货地址!')
}
$('.popup_con').fadeIn('fast', function() {
setTimeout(function(){
$('.popup_con').fadeOut('fast',function(){
window.location.href = '{% url 'user:user_center_order' %}';
});
},3000)
});
});
</script>
{% endblock %}
二、个人信息模块
1.在urls.py配置文件中定义路由
from django.conf.urls import url, include
from user import views
urlpatterns = [
# 用户中心
url(r'^user_center_info/', views.user_center_info, name='user_center_info'),
]
2.个人信息
from django.shortcuts import render
def user_center_info(request):
if request.method == 'GET':
return render(request, 'user_center_info.html')
3.前端页面代码
{% extends 'base_main.html' %}
{% block title %}
天天生鲜-用户中心
{% endblock %}
{% block search %}
<div class="search_bar clearfix">
{% load static %}
<a href="{% url 'goods:index' %}" class="logo fl"><img src="{% static 'images/logo.png' %}"></a>
<div class="sub_page_name fl">| 用户中心</div>
<div class="search_con fr">
<input type="text" class="input_text fl" name="" placeholder="搜索商品">
<input type="button" class="input_btn fr" name="" value="搜索">
</div>
</div>
{% endblock %}
{% block content %}
<div class="main_con clearfix">
<div class="left_menu_con clearfix">
<h3>用户中心</h3>
<ul>
<li><a href="{% url 'user:user_center_info' %}" class="active">· 个人信息</a></li>
<li><a href="{% url 'user:user_center_order' %}">· 全部订单</a></li>
<li><a href="{% url 'user:user_center_site' %}">· 收货地址</a></li>
</ul>
</div>
<div class="right_content clearfix">
<div class="info_con clearfix">
<h3 class="common_title2">基本信息</h3>
<ul class="user_info_list">
<li><span>用户名:</span>{{ user.username }}</li>
<li><span>联系电话:</span>{{ user.mobile }}</li>
<li><span>联系邮箱:</span>{{ user.email }}</li>
</ul>
</div>
<h3 class="common_title2">最近浏览</h3>
<div class="has_view_list">
<ul class="goods_type_list clearfix">
<li>
<a href="detail.html"><img src="{% static 'images/goods/goods003.jpg' %}"></a>
<h4><a href="detail.html">大兴大棚草莓</a></h4>
<div class="operate">
<span class="prize">¥16.80</span>
<span class="unit">16.80/500g</span>
<a href="#" class="add_goods" title="加入购物车"></a>
</div>
</li>
<li>
<a href="#"><img src="{% static 'images/goods/goods004.jpg' %}"></a>
<h4><a href="#">吐鲁番梨光杏</a></h4>
<div class="operate">
<span class="prize">¥5.50</span>
<span class="unit">5.50/500g</span>
<a href="#" class="add_goods" title="加入购物车"></a>
</div>
</li>
<li>
<a href="#"><img src="{% static 'images/goods/goods005.jpg' %}"></a>
<h4><a href="#">黄肉桃</a></h4>
<div class="operate">
<span class="prize">¥10.00</span>
<span class="unit">10.00/500g</span>
<a href="#" class="add_goods" title="加入购物车"></a>
</div>
</li>
<li>
<a href="#"><img src="{% static 'images/goods/goods006.jpg' %}"></a>
<h4><a href="#">进口西梅</a></h4>
<div class="operate">
<span class="prize">¥28.80</span>
<span class="unit">28.8/500g</span>
<a href="#" class="add_goods" title="加入购物车"></a>
</div>
</li>
<li>
<a href="#"><img src="{% static 'images/goods/goods007.jpg' %}"></a>
<h4><a href="#">香梨</a></h4>
<div class="operate">
<span class="prize">¥6.45</span>
<span class="unit">6.45/500g</span>
<a href="#" class="add_goods" title="加入购物车"></a>
</div>
</li>
</ul>
</div>
</div>
</div>
{% endblock %}
三、订单详情模块
1.在urls.py配置文件中定义路由
from django.conf.urls import url, include
from user import views
urlpatterns = [
# 订单详情
url(r'^user_center_order/', views.user_center_order, name='user_center_order'),
]
2.订单详情
from django.core.paginator import Paginator
from django.shortcuts import render
from order.models import OrderInfo
def user_center_order(request):
if request.method == 'GET':
user_id = request.session.get('user_id')
page_num = request.GET.get('page', 1)
order_info = OrderInfo.objects.filter(user_id=user_id)
paginator = Paginator(order_info, 5)
page = paginator.page(page_num)
return render(request, 'user_center_order.html', {'page': page})
3.前端页面代码
{% extends 'base_main.html' %}
{% block title %}
天天生鲜-用户中心
{% endblock %}
{% block search %}
<div class="search_bar clearfix">
<a href="{% url 'goods:index' %}" class="logo fl"><img src="/static/images/logo.png"></a>
<div class="sub_page_name fl">| 用户中心</div>
<div class="search_con fr">
<input type="text" class="input_text fl" name="" placeholder="搜索商品">
<input type="button" class="input_btn fr" name="" value="搜索">
</div>
</div>
{% endblock %}
{% block content %}
<div class="main_con clearfix">
<div class="left_menu_con clearfix">
<h3>用户中心</h3>
<ul>
<li><a href="{% url 'user:user_center_info' %}">· 个人信息</a></li>
<li><a href="{% url 'user:user_center_order' %}" class="active">· 全部订单</a></li>
<li><a href="{% url 'user:user_center_site' %}">· 收货地址</a></li>
</ul>
</div>
<div class="right_content clearfix">
<h3 class="common_title2">全部订单</h3>
{% for order in page %}
<ul class="order_list_th w978 clearfix">
<li class="col01">{{ order.add_time }}</li>
<li class="col02">订单号:{{ order.order_sn }}</li>
<li class="col02 stress">{{ order.pay_status }}</li>
</ul>
<table class="order_list_table w980">
<tbody>
<tr>
<td width="55%">
{% for order_goods in order.goods.all %}
<ul class="order_goods_list clearfix">
<li class="col01"><img src="/media/{{ order_goods.goods.goods_front_image }}"></li>
<li class="col02">{{ order_goods.goods.name }}<em>{{ order_goods.goods.shop_price }}元/500g</em></li>
<li class="col03">{{ order_goods.goods_nums }}</li>
<li class="col04">11.80元</li>
</ul>
{% endfor %}
</td>
<td width="15%">{{ order.order_mount }}元</td>
<td width="15%">待付款</td>
<td width="15%"><a href="#" class="oper_btn">去付款</a></td>
</tr>
</tbody>
</table>
{% endfor %}
<div class="pagenation">
<a href="#"><上一页</a>
<a href="#" class="active">1</a>
<a href="#">2</a>
<a href="#">3</a>
<a href="#">4</a>
<a href="#">5</a>
<a href="#">下一页></a>
</div>
</div>
</div>
{% endblock %}
四、收货地址模块
1.在urls.py配置文件中定义路由
from django.conf.urls import url, include
from user import views
urlpatterns = [
# 用户收货地址
url(r'^user_center_site/', views.user_center_site, name='user_center_site'),
]
2.定义收货地址验证form表单
from django import forms
from user.models import User
class UserRegisterForm(forms.Form):
user_name = forms.CharField(max_length=20, min_length=5, required=True,
error_messages={
'required': '用户名必填',
'max_length': '用户名不能超过20位字符',
'min_length': '用户名不能少于5位字符',
})
pwd = forms.CharField(max_length=20, min_length=8, required=True,
error_messages={
'required': '密码必填',
'max_length': '密码不能超过20位字符',
'min_length': '密码不能少于8位字符'
})
cpwd = forms.CharField(max_length=20, min_length=8, required=True,
error_messages={
'required': '确认密码必填',
'max_length': '密码不能超过20位字符',
'min_length': '密码不能少于8位字符'
})
email = forms.CharField(required=True,
error_messages={
'required': '邮箱必填'
})
# 验证时,会自动调用
def clean(self):
# 校验用户名是否已存在于数据库
user =User.objects.filter(username=self.cleaned_data.get('user_name')).first()
if user:
# 用户已存在于数据库,抛出异常
raise forms.ValidationError({'user_name': '该用户已存在'})
# 校验密码是否相等
pwd = self.cleaned_data.get('pwd')
cpwd = self.cleaned_data.get('cpwd')
if pwd != cpwd:
raise forms.ValidationError({'pwd': '两次密码不一致'})
return self.cleaned_data
class UserLoginForm(forms.Form):
username = forms.CharField(required=True,
error_messages={
'required': '用户名必填',
})
pwd = forms.CharField(required=True,
error_messages={
'required': '密码必填',
})
# def clean(self):
# 验证登录的账号是否已经被注册过,注册过才能登录
# user = User.objects.filter(username=self.cleaned_data.get('username')).first()
# if not user:
# raise forms.ValidationError({'username': '该账号没有注册'})
#
# return self.cleaned_data
class UserAddressForm(forms.Form):
signer_name = forms.CharField(required=True,
error_messages={
'required': '收件人必填'
})
address = forms.CharField(required=True,
error_messages={
'required': '必填'
})
postcode = forms.CharField(required=True,
error_messages={
'required': '邮编必填'
})
mobile = forms.CharField(required=True,
error_messages={
'required': '手机必填'
})
3.收货地址
from django.shortcuts import render
from django.urls import reverse
from user.forms import UserAddressForm
from user.models import UserAddress
def user_center_site(request):
if request.method == 'GET':
user_id = request.session.get('user_id')
user_address = UserAddress.objects.filter(user_id=user_id)
return render(request, 'user_center_site.html', {'user_address': user_address})
if request.method == 'POST':
# 使用表单做校验
form = UserAddressForm(request.POST)
if form.is_valid():
user_id = request.session.get('user_id')
address = form.cleaned_data['address']
signer_name = form.cleaned_data['signer_name']
postcode = form.cleaned_data['postcode']
mobile = form.cleaned_data['mobile']
UserAddress.objects.create(user_id=user_id, address=address, signer_name=signer_name,
signer_postcode=postcode, signer_mobile=mobile)
return HttpResponseRedirect(reverse('user:user_center_site'))
else:
errors = form.errors
return render(request, 'user_center_site.html', {'errors': errors})
4.前端页面代码
{% extends 'base_main.html' %}
{% block title %}
天天生鲜-用户中心
{% endblock %}
{% block search %}
<div class="search_bar clearfix">
{% load static %}
<a href="{% url 'goods:index' %}" class="logo fl"><img src="{% static 'images/logo.png' %}"></a>
<div class="sub_page_name fl">| 用户中心</div>
<div class="search_con fr">
<input type="text" class="input_text fl" name="" placeholder="搜索商品">
<input type="button" class="input_btn fr" name="" value="搜索">
</div>
</div>
{% endblock %}
{% block content %}
<div class="main_con clearfix">
<div class="left_menu_con clearfix">
<h3>用户中心</h3>
<ul>
<li><a href="{% url 'user:user_center_info' %}">· 个人信息</a></li>
<li><a href="{% url 'user:user_center_order' %}">· 全部订单</a></li>
<li><a href="{% url 'user:user_center_site' %}" class="active">· 收货地址</a></li>
</ul>
</div>
<div class="right_content clearfix">
<h3 class="common_title2">收货地址</h3>
<div class="site_con">
<dl>
<dt>当前地址:</dt>
{% for address in user_address %}
{% if address %}
<dd>{{ address.address }} ({{ address.signer_name }} 收) {{ address.signer_mobile }}</dd>
{% else %}
<dd>无</dd>
{% endif %}
{% endfor %}
</dl>
</div>
<h3 class="common_title2">编辑地址</h3>
<div class="site_con">
<form action="" method="post">
{% csrf_token %}
<div class="form_group">
<label>收件人:</label>
<input type="text" name="signer_name">
{{ errors.signer_name }}
</div>
<div class="form_group form_group2">
<label>详细地址:</label>
<textarea class="site_area" name="address"></textarea>{{ errors.address }}
</div>
<div class="form_group">
<label>邮编:</label>
<input type="text" name="postcode">
{{ errors.postcode }}
</div>
<div class="form_group">
<label>手机:</label>
<input type="text" name="mobile">
{{ errors.mobile }}
</div>
<input type="submit" name="" value="提交" class="info_submit">
</form>
</div>
</div>
</div>
{% endblock %}