dDjango 19购物商城项目
1、新建axf_addr,收货地址表
(我的代码注释里面有时也称收货信息表)
模型:
# 收货信息(收货地址)
class Addr(models.Model):
# 所属用户
A_user = models.ForeignKey(AXFUser, on_delete=models.CASCADE)
# 订单
A_order_id = models.IntegerField(default=0)
# A_order_id = models.ForeignKey(Order,on_delete=models.CASCADE,default=None)
# 城市
A_city_id = models.IntegerField(default=0)
# A_city_iD = models.ForeignKey(City, on_delete=models.CASCADE)
# 详细地址
A_detail = models.CharField(max_length=125)
# 收货人
A_user_name = models.CharField(max_length=125)
# 电话
A_tell = models.IntegerField()
# 收货时间(**小时内送达)
A_time = models.IntegerField(default=1)
# 是否为默认地址
is_default = models.BooleanField(default=False)
class Meta:
db_table = 'axf_addr'
2、路由
所有路由,包括新加的 收货地址:添加、修改的路由
from App import views
from django.urls import path, re_path
app_name = 'axf01'
urlpatterns = [
path('home/', views.home, name='home'),
path('market/', views.market, name='market'),
path('cart/', views.cart, name='cart'),
path('mine/', views.mine, name='mine'),
re_path(r'^markets/(?P<typeid>\d+)&(?P<childcid>\d+)&(?P<order_rule>\d+)/', views.markets, name='markets'),
# 注册
path('register/', views.register, name='register'),
# 登录
path('login/', views.login, name='login'),
# 注册时预检测用户名是否可用
path('checkuser/', views.check_user, name='check_user'),
# 注册时预检测用邮箱是否可用
path('checkemail/', views.check_email, name='check_email'),
# 退出登录
path('logout/', views.logout, name='logout'),
# 激活
path('activate/', views.activate, name='activate'),
# 添加商品
path('addtocart/', views.add_to_cart, name='add_to_cart'),
# 删除商品
path('subtocart/', views.sub_to_cart, name='sub_to_cart'),
# 购物车里的物品选中状态改变
path('changecart/', views.change_cart, name='change_cart'),
# 购物车全选
path('allselect/', views.all_select, name='all_select'),
# 生成订单
path('makeorder/', views.make_order, name='make_order'),
# 订单详情与支付
path('orderdetail/', views.order_detail, name='order_detail'),
# 待付款订单列表
path('ordernotpay/', views.order_not_pay, name='order_not_pay'),
# 支付完成
# path('payed/', views.payed, name='payed'),
# 支付宝支付
path('alipay/', views.alipay, name='alipay'),
# 支付成功后接收,跳转页面
path('payreturn/', views.pay_return, name='pay_return'),
# 收货地址列表
path('orderaddrlist/', views.order_addr_list, name='order_addr_list'),
# 收货地址等信息编辑
path('orderaddrPCA/', views.order_addrPCA, name='order_addrPCA'),
# 收货地址等信息编辑时异步传回
path('PCA/', views.PCA, name='PCA'),
# 删除收货地址
path('orderaddrdel/', views.order_addr_del, name='order_addr_del'),
# 设置用户默认的收货地址
path('orderaddrselect/', views.order_addr_select, name='order_addr_select'),
]
3、cart页面,添加默认收货地址
cart.html
修改内容比较多,下面是cart.html所有内容
{% extends 'base_main.html' %}
{% load static %}
{% block ext_css %}
{{ block.super }}
<link rel="stylesheet" href="{% static 'axf/main/css/cart.css' %}">
{% endblock %}
{% block ext_js %}
{{ block.super }}
<script type="text/javascript" src="{% static 'axf/main/js/cart.js' %}"></script>
{% endblock %}
{% block content %}
<div id="cart">
<h3>购物车</h3>
<div class="full">
<section>
{% if user_addr %}
<ul>
<li>收 货 人: {{ user_addr.A_user_name }}</li>
<li>电 话: {{ user_addr.A_tell }}</li>
<li>地 址: {{ user_addr.A_detail }}</li>
<a class="addr" href="{% url 'axf:order_addr_list' %}">修改收货信息</a>
</ul>
{% else %}
<ul>
<br>
<li>您还未填写收货信息</li>
<br>
<a class="addr" href="{% url 'axf:order_addrPCA' %}">填写收货信息</a>
</ul>
{% endif %}
<div class="bill">
<p>闪送超市</p>
<p>0元起送,满30送10</p>
<a href="#">凑单专区</a>
</div>
<div class="delivery">
<span>收货时间:</span>
{% if user_addr %}
<span><input id="time" value="{{ user_addr.A_time }}">小时送达</span>
{% else %}
<span><input id="time" value="1">小时送达</span>
{% endif %}
<span><a href="#">可预订></a></span>
</div>
<div class="delivery">
<span>收货备注:</span>
<input type="text" placeholder="可输入100字">
</div>
{# 商品信息展示 #}
<ul>
{% for cart in carts %}
<li class="menuList" cartid="{{ cart.id }}" goodsid="{{ cart.C_goods_id }}">
<div class="confirm">
<span>
{% if cart.C_is_select %}
<span>√</span>
{% else %}
<span></span>
{% endif %}
</span>
</div>
<a href="#">
<img src="{{ cart.C_goods.productimg }}" alt="{{ cart.C_goods.productlongname }}">
<p>{{ cart.C_goods.productlongname }}</p>
<p class="presenPrice">{{ cart.C_goods.price }}</p>
</a>
<section>
<button class="subShopping">-</button>
<span>{{ cart.C_goods_num }}</span>
<button class="addShopping">+</button>
</section>
</li>
{% endfor %}
</ul>
<div class="payTheBill">
<div class="all_select">
<span>
{% if is_all_select %}
<span>√</span>
{% else %}
<span></span>
{% endif %}
</span>
</div>
<p>
<span>全选</span>
<span>共计:</span>
<span id="total_price">{{ total_price }}</span>
</p>
<span id="make_order">下单</span>
</div>
</section>
</div>
</div>
{% endblock %}
4、视图(主要修改了cart、新建了收货地址相关方法)
下面是视图里面的所有代码
import uuid
from AXF01.pay import pay, my_alipay
from AXF01.settings import MEDIA_KEY_PREFIX
from App.models import MainWheel, MainNav, MainMustBuy, MainShop, MainShow, FoodType, Goods, AXFUser, Cart, Order, \
OrderGoods, City, Addr
from App.views_constant import ALL_TPYE, ORDER_TOTAL, ORDER_PRICE_UP, ORDER_PRICE_DOWN, ORDER_SALE_UP, ORDER_SALE_DOWN, \
HTTP_USER_EXIST, HTTP_OK, ORDER_STATUS_NOT_PAY, ORDER_STATUS_NOT_RECEIVE, ORDER_STATUS_NOT_SEND
from App.views_heiper import send_email_activate, get_total_price
from django.contrib.auth.hashers import make_password, check_password
from django.core.cache import cache
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect
from django.urls import reverse
def home(request):
main_wheels = MainWheel.objects.all()
main_navs = MainNav.objects.all()
main_mustbuys = MainMustBuy.objects.all()
main_shops = MainShop.objects.all()
main_shop0_1 = main_shops[0:1]
main_shop1_3 = main_shops[1:3]
main_shop3_7 = main_shops[3:7]
main_shop7_11 = main_shops[7:11]
main_shows = MainShow.objects.all()
data = {
"title": "首页",
"main_wheels": main_wheels,
"main_navs": main_navs,
"main_mustbuys": main_mustbuys,
"main_shop0_1": main_shop0_1,
"main_shop1_3": main_shop1_3,
"main_shop3_7": main_shop3_7,
"main_shop7_11": main_shop7_11,
"main_shows": main_shows,
}
return render(request, 'main/home.html', context=data)
def market(request):
return redirect(reverse('axf:markets', kwargs={
"typeid": 1001,
"childcid": 0,
"order_rule": 0,
}))
# 访问market时 先传入各项 参数 的默认值,然后重定向到markets
# 重定向到markets后根据 传入的参数 获取数据 并传给 market.html 展示到前端
def markets(request, typeid, childcid, order_rule):
foodtypes = FoodType.objects.all()
goods_list = Goods.objects.filter(categoryid=typeid)
if childcid == ALL_TPYE:
pass
else:
goods_list = goods_list.filter(childcid=childcid)
if order_rule == ORDER_TOTAL:
pass
elif order_rule == ORDER_PRICE_UP:
goods_list = goods_list.order_by("price")
elif order_rule == ORDER_PRICE_DOWN:
goods_list = goods_list.order_by("-price")
elif order_rule == ORDER_SALE_UP:
goods_list = goods_list.order_by("productnum")
elif order_rule == ORDER_SALE_DOWN:
goods_list = goods_list.order_by("-productnum")
foodtype = foodtypes.get(typeid=typeid)
"""
全部分类:0#进口水果:1001#国产水果:1002
切割#: [全部分类:0 ,进口水果:1001 , 国产水果:1002]
切割:。。。。。
"""
foodtype_childnames = foodtype.childtypenames
f_list = foodtype_childnames.split("#")
f_list_list = []
for f in f_list:
f_list_list.append(f.split(":"))
order_rule_list = [
['综合排序', ORDER_TOTAL],
['价格升序', ORDER_PRICE_UP],
['价格降序', ORDER_PRICE_DOWN],
['销量升序', ORDER_SALE_UP],
['销量降序', ORDER_SALE_DOWN],
]
data = {
"title": "商城",
"foodtypes": foodtypes,
"goods_list": goods_list,
"typeid": int(typeid),
"f_list_list": f_list_list,
"childcid": childcid,
"order_rule_list": order_rule_list,
"order_rule_view": order_rule,
}
return render(request, 'main/market.html', context=data)
def cart(request):
# 传递购物车数据
carts = Cart.objects.filter(C_user=request.user)
# 查看购物车表里是否存在未选中状态的数据
# 有未选中的,is_all_select为False,全部都是选中的,is_all_select为True
is_all_select = not carts.filter(C_is_select=False).exists()
data = {
"title": '购物车',
'carts': carts,
'is_all_select': is_all_select,
"total_price": get_total_price(),
}
# 传递用户地址信息
user_addrs = Addr.objects.filter(A_user=request.user)
# 确认用户地址信息(如果有,选择默认地址)
if user_addrs.exists():
if user_addrs.filter(is_default=1).count() != 1:
# 确保数据库里至少有一个是选中的
for user_addr in user_addrs:
user_addr.is_default = 0
if user_addr == user_addrs[1]:
user_addr.is_default = 1
user_addr.save()
user_addr = user_addrs.get(is_default=1)
data["user_addr"] = user_addr
return render(request, 'main/cart.html', context=data)
def mine(request):
user_id = request.session.get("user_id")
data = {
"title": "我的个人中心",
"is_login": False,
}
if user_id:
user = AXFUser.objects.get(pk=user_id)
if user.u_icon:
data["icon"] = MEDIA_KEY_PREFIX + user.u_icon.url
data["username"] = user.u_name
data["is_login"] = True
data['order_not_pay'] = Order.objects.filter(O_user=user).filter(O_status=ORDER_STATUS_NOT_PAY).count()
# 已付款未发货和已发货都属于 待收货 里的
data['order_not_receive'] = Order.objects.filter(O_user=user).filter(
O_status__in=[ORDER_STATUS_NOT_RECEIVE, ORDER_STATUS_NOT_SEND]).count()
return render(request, 'main/mine.html', context=data)
def register(request):
# 请求
if request.method == "GET":
data = {
"title": "注册"
}
return render(request, 'user/register.html', context=data)
# 提交
elif request.method == "POST":
username = request.POST.get("username")
email = request.POST.get("email")
password = request.POST.get("password")
icon = request.FILES.get("icon")
print(request.POST)
print(password)
# password=hash_str(password)
password = make_password(password)
user = AXFUser()
user.u_name = username
user.u_password = password
user.u_icon = icon
user.u_email = email
user.save()
# 用uuid得到唯一激活码,再哈希加密
u_token = uuid.uuid4().hex
# 缓存过期时间为1天
cache.set(u_token, user.id, timeout=60 * 60 * 24)
send_email_activate(username, email, u_token)
return redirect(reverse("axf:login"))
def login(request):
if request.method == "GET":
error_msg = request.session.get('error_msg')
data = {
"title": "登录"
}
if error_msg:
# 如果session['error_msg']存在就删除,并将error_msg显示在页面上
del request.session['error_msg']
data['error_msg'] = error_msg
return render(request, 'user/login.html', context=data)
elif request.method == "POST":
username = request.POST.get("username")
password = request.POST.get("password")
users = AXFUser.objects.filter(u_name=username)
# exists()方法主要是判断查询的数据是否存在,存在时返回True,否则返回False
# first() 返回queryset中匹配到的第一个对象,如果没有匹配到对象则为None
if users.exists():
user = users.first()
if check_password(password, user.u_password):
if user.is_active:
request.session['user_id'] = user.id
return redirect(reverse('axf:mine'))
else:
request.session['error_msg'] = '未激活'
return redirect(reverse('axf:login'))
else:
# 密码错误
request.session['error_msg'] = '密码错误'
return redirect(reverse('axf:login'))
# 用户名不存在
request.session['error_msg'] = '用户不存在'
return redirect(reverse('axf:login'))
def check_user(request):
username = request.GET.get("T_name")
user = AXFUser.objects.filter(u_name=username)
data = {
"status": HTTP_OK,
"msg": 'user can use',
}
# exists()判断路径是否存在
if user.exists():
data["status"] = HTTP_USER_EXIST
data["msg"] = 'user already exist'
else:
pass
return JsonResponse(data=data)
def check_email(request):
email = request.GET.get("T_name")
e = AXFUser.objects.filter(u_email=email)
data = {
"status": HTTP_OK,
"msg": 'email can use',
}
# exists()判断路径是否存在
if e.exists():
data["status"] = HTTP_USER_EXIST
data["msg"] = 'email already exist'
else:
pass
return JsonResponse(data=data)
def logout(request):
request.session.flush()
return redirect(reverse("axf:mine"))
def activate(request):
# 获取从用户点击 激活 传过来的u_token
u_token = request.GET.get("u_token")
user_id = cache.get(u_token)
if user_id:
# 拿到激活码后就从cache里面把u_token删了,防止用户第二次点击激活
cache.delete(u_token)
user = AXFUser.objects.get(pk=user_id)
user.is_active = True
user.save()
request.session['error_msg'] = '成功激活,请登录'
return redirect(reverse('axf:login'))
return render(request, 'user/activate_fail.html')
def add_to_cart(request):
goodsid = request.GET.get('goodsid')
# 获取购物车里的数据
carts = Cart.objects.filter(C_user=request.user).filter(C_goods_id=goodsid)
print(request.user)
# 有数据+1
if carts.exists():
c_obj = carts.first()
c_obj.C_goods_num = c_obj.C_goods_num + 1
# 没有数据创建新的
else:
c_obj = Cart()
c_obj.C_goods_id = goodsid
c_obj.C_user = request.user
c_obj.save()
data = {
'msg': 1,
'status': 200,
"C_goods_num": c_obj.C_goods_num,
"total_price": get_total_price(),
}
return JsonResponse(data=data)
def sub_to_cart(request):
goodsid = request.GET.get('goodsid')
carts = Cart.objects.filter(C_user=request.user).filter(C_goods_id=goodsid)
data = {
'msg': 0,
}
if carts.exists():
c_obj = carts.first()
if c_obj.C_goods_num >= 1:
c_obj.C_goods_num = c_obj.C_goods_num - 1
c_obj.save()
data = {
'msg': 1,
'status': 200,
"C_goods_num": c_obj.C_goods_num,
"total_price": get_total_price(),
}
if c_obj.C_goods_num == 0:
Cart.objects.filter(pk=c_obj.id).delete()
return JsonResponse(data=data)
def change_cart(request):
cart_id = request.GET.get('cartid')
cart_obj = Cart.objects.get(pk=cart_id)
# 取反
cart_obj.C_is_select = not cart_obj.C_is_select
cart_obj.save()
is_all_select = not Cart.objects.filter(C_user=request.user).filter(C_is_select=False).exists()
data = {
'status': 200,
'msg': '选中与否状态改变成功',
"C_is_select": cart_obj.C_is_select,
"is_all_select": is_all_select,
"total_price": get_total_price(),
}
return JsonResponse(data=data)
def all_select(request):
cart_list = request.GET.get('cart_list')
cart_list = cart_list.split("#")
carts = Cart.objects.filter(id__in=cart_list)
for cart in carts:
cart.C_is_select = not cart.C_is_select
cart.save()
print(cart_list)
data = {
"status": 200,
"total_price": get_total_price(),
}
return JsonResponse(data=data)
def make_order(request):
# 获取选中状态的商品
carts = Cart.objects.filter(C_user=request.user).filter(C_is_select=True)
# 创建订单存入数据
order = Order()
order.O_user = request.user
order.O_price = get_total_price()
order.save()
# 循环 存入商品信息
for cart_obj in carts:
ordergoods = OrderGoods()
# ordergoods.O_user里存的是订单号
ordergoods.O_user = order
# 商品数量
ordergoods.O_goods_num = cart_obj.C_goods_num
# 商品
ordergoods.O_goods = cart_obj.C_goods
ordergoods.save()
cart_obj.delete()
data = {
"status": 200,
# 把订单id传到前端
"order_id": order.id
}
return JsonResponse(data=data)
# 订单详情
def order_detail(request):
# request:orderid(订单的id)、AXFUser(中间件传递)
order_id = request.GET.get("orderid")
order = Order.objects.get(pk=order_id)
print(order)
data = {
"title": "订单详情",
# 这里的order包含 单个订单的全部信息
"order": order,
}
return render(request, "order/order_detail.html", context=data)
# 待付款订单列表
def order_not_pay(request):
orders = Order.objects.filter(O_user=request.user).filter(O_status=ORDER_STATUS_NOT_PAY)
data = {
'title': "待付款订单列表",
'orders': orders,
}
return render(request, 'order/order_not_pay.html', context=data)
# 跳转去支付页面
def alipay(request):
if request.method == "POST":
order_id = request.POST.get("orderid")
print(order_id)
order = Order.objects.get(pk=order_id)
O_price = order.O_price
O_user = order.O_user.u_name
return_url = 'http://127.0.0.1:8000/axf/payreturn'
return redirect(pay(order_id, O_price, O_user, return_url=return_url))
# 支付成功后执行
def pay_return(request):
# 支付成功后的回调函数 -- 重定向自己的网站
# 同时在重定向之前会校验此次支付信息是否正确
params = request.GET.dict()
# 获取字典里的'sign'的值,然后移除这个数据
sign = params.pop('sign', None)
alipay = my_alipay()
status = alipay.verify(params, sign) # 返回 True or False
if status:
order_id = params.get('out_trade_no')
order = Order.objects.get(pk=order_id)
order.O_status = ORDER_STATUS_NOT_SEND
order.save()
data = {
'status': 200,
}
# 支付成功
return redirect(reverse('axf:mine'))
return HttpResponse('支付失败')
# p省级城市、c市级城市、a区县级城市
def order_addrPCA(request):
data = {}
# 编辑
if request.method == "GET":
# 如果是编辑把addr传过去
if request.GET.get("addrid"):
addr_id = request.GET.get("addrid")
addr = Addr.objects.get(pk=addr_id)
data["addr"] = addr
# 如果是新添加直接进入页面
return render(request, 'order/oder_addr.html', context=data)
# 提交
if request.method == "POST":
user_addrs = Addr.objects.filter(A_user=request.user)
if request.POST.get("addr_id"):
addr_id = request.POST.get("addr_id")
user_addr = user_addrs.get(pk=addr_id)
user_addr.A_user_name = request.POST.get("order_name")
user_addr.A_tell = request.POST.get("order_tell")
user_addr.A_time = int(request.POST.get("order_time"))
user_addr.A_detail = request.POST.get("order_detail")
is_default = request.POST.get("is_default")
if is_default == "on":
# 设置这个地址为默认地址
for addr in user_addrs:
addr.is_default = 0
addr.save()
user_addr.is_default = 1
user_addr.save()
print("编辑")
else:
user_addr = Addr()
user_addr.A_user = request.user
user_addr.A_user_name = request.POST.get("order_name")
user_addr.A_tell = request.POST.get("order_tell")
user_addr.A_time = int(request.POST.get("order_time"))
user_addr.A_detail = request.POST.get("order_detail")
is_default = request.POST.get("is_default")
if is_default == "on":
# 设置这个地址为默认地址
for addr in user_addrs:
addr.is_default = 0
addr.save()
user_addr.is_default = 1
user_addr.save()
print("新建")
return redirect(reverse('axf:order_addr_list'))
# oder_addr.html的异步请求
def PCA(request):
data = {}
if request.GET.get("p"):
ps = City.objects.filter(pid=0)
ps_all = []
for p in ps:
temp = []
temp.append(p.id)
temp.append(p.name)
ps_all.append(temp)
data['ps_all'] = ps_all
elif request.GET.get("c_pid"):
cs = City.objects.filter(pid=request.GET.get("c_pid"))
cs_all = []
for c in cs:
temp1 = []
temp1.append(c.id)
temp1.append(c.name)
cs_all.append(temp1)
data['cs_all'] = cs_all
elif request.GET.get("a_pid"):
a_s = City.objects.filter(pid=request.GET.get("a_pid"))
as_all = []
for a in a_s:
temp2 = []
temp2.append(a.id)
temp2.append(a.name)
as_all.append(temp2)
data['as_all'] = as_all
return JsonResponse(data)
def order_addr_list(request):
user_addrs = Addr.objects.filter(A_user=request.user)
if user_addrs.filter(is_default=1).count() > 1:
for user_addr in user_addrs:
user_addr.is_default = 0
user_addr.save()
data = {
"user_addrs": user_addrs
}
return render(request, 'order/oder_addr_list.html', context=data)
def order_addr_del(request):
addr_id = request.GET.get("addrid")
addr = Addr.objects.get(pk=addr_id)
addr.delete()
return redirect(reverse('axf:order_addr_list'))
def order_addr_select(request):
user = request.user
addr_select_id = request.GET.get("addr_select_id")
user_addrs = Addr.objects.filter(A_user=user)
print(addr_select_id)
for user_addr in user_addrs:
if user_addr.id == int(addr_select_id):
user_addr.is_default = 1
user_addr.save()
else:
user_addr.is_default = 0
user_addr.save()
data = {
"status": 200,
}
return JsonResponse(data)
5、收货地址列表
order_addr_list.html
{% extends "bese_order.html" %}
{% load static %}
{% block ext_css %}
{{ block.super }}
<link rel="stylesheet" href="{% static 'axf/order/css/order_order_list.css' %}">
{% endblock %}
{% block ext_js %}
{{ block.super }}
<script type="text/javascript" src="{% static 'axf/order/js/order_addr_list.js' %}"></script>
{% endblock %}
{% block header %}
<div class="title">
<a href="#" onclick="javascript:history.back(-1);">
<div class="arrow-box nav-left">
返回
</div>
</a>
<a id="edi_new" href="{% url 'axf:order_addrPCA' %}">
<div class="arrow-box nav-left">
添加
</div>
</a>
<p class="font">地址列表</p>
</div>
{% endblock %}
{% block content %}
<div id="order_addr_list" class="container">
<ol>
{% for user_addr in user_addrs %}
<ul class="user_addr">
<div class="is_select" addrid="{{ user_addr.id }}">
{% if user_addr.is_default %}
<span>√</span>
{% else %}
<span></span>
{% endif %}
</div>
<li class="menuList">
<p>
<span id="name">{{ user_addr.A_user_name }}</span>
<span id="tell">{{ user_addr.A_tell }}</span>
</p>
<br>
<div id="detail">收货地址:{{ user_addr.A_detail }}</div>
<div id="toto">
<a addrid="{{ user_addr.id }}" class="edi">编辑</a> | <a
addrid="{{ user_addr.id }}" class="del">删除</a>
</div>
</li>
</ul>
{% endfor %}
</ol>
<a id="back_button" href="{% url 'axf:cart' %}" class="btn btn-success btn-block">确定</a>
<br>
<br>
<br>
<br>
</div>
{% endblock %}
order_addr_list.js
$(function () {
var $del = $(".del");
$del.click(function () {
var $del = $(this);
var addr_id = $del.attr("addrid");
window.open('/axf/orderaddrdel/?addrid=' + addr_id, target = "_self");
});
var $edi = $(".edi");
$edi.click(function () {
var $edi = $(this);
var addr_id = $edi.attr("addrid");
window.open('/axf/orderaddrPCA/?addrid=' + addr_id, target = "_self");
});
$(".is_select").click(function () {
console.log("点到我了");
$(".is_select").each(function () {
var $other_select = $(this);
$other_select.find("span").html('');
});
var $the_select = $(this);
$the_select.find("span").html("√");
var addr_select_id = $the_select.attr("addrid");
$.get("/axf/orderaddrselect/", {"addr_select_id": addr_select_id}, function (data) {
console.log('保存默认地址成功');
console.log(data["status"])
});
});
});
order_addr_list.css
.title {
width: 100%;
height: 50px;
background-color: #009688;
}
.font {
color: #fff;
line-height: 50px;
font-size: 20px;
text-indent: -2em;
text-align: center
}
.nav-left {
float: left;
}
.arrow-box {
width: 50px;
height: 26px;
position: relative;
border-radius: 10% 10%;
background: #fff;
text-align: center;
line-height: 26px;
top: 12px;
font-size: 14px;
left: 10px;
}
.container {
padding: 0.2rem 0.5rem 0.5rem 0.5rem;
overflow: auto;
height: 100%;
width: 100%;
position: fixed;
}
.menuList {
border-bottom: 0.04rem solid lightgray;
margin-left: 1.1rem;
}
#name {
font-size: 0.4rem;
}
#tell {
font-size: 0.3rem;
color: gray;
margin-left: 0.5rem;
margin-right: 15%;
}
#detail {
font-size: 0.3rem;
color: grey;
}
#toto {
border: 0.05rem solid lightgray;
position: absolute;
border-radius: 0.3rem;
padding: 0 0.3rem;
font-size: 0.35rem;
line-height: 0.65rem;
top: 0;
right: 0.5rem;
}
#toto,#toto > a {
color: #ababab;
}
.user_addr {
position: relative;
margin-top: 1rem;
}
.is_select{
box-sizing: border-box;
border: 0.04rem solid orange;
background: white;
display: inline-block;
width: 0.6rem;
height: 0.6rem;
overflow: hidden;
border-radius: 50%;
line-height: 0.6rem;
position: absolute;
margin-top: 0.5rem;
}
.is_select>span{
background: yellow;
font-size: 0.5rem;
display: block;
line-height: 0.6rem;
margin-left: 0.1rem;
}
#back_button{
margin-top: 1rem;
background: #009688;
}
#edi_new{
position: absolute;
right: 0.5rem;
}
#edi_new>div{
background: #009688;
border: 0.05rem solid lightgray;
color: white;
}
6、收货地址编辑、新建页面(这部分重点在js上)
{% extends "bese_order.html" %}
{% load static %}
{% block ext_css %}
{{ block.super }}
<link rel="stylesheet" href="{% static 'axf/order/css/order_addr.css' %}">
{% endblock %}
{% block ext_js %}
{{ block.super }}
<script type="text/javascript" src="{% static 'axf/order/js/order_addr.js' %}"></script>
{% endblock %}
{% block footer %}
<div class="title">
<a href="#" onclick="javascript:history.back(-1);">
<div class="arrow-box nav-left">
返回
</div>
</a>
<p class="font">编辑收货地址</p>
</div>
{% endblock %}
{% block content %}
<div class="container">
<form method="POST" action="{% url 'axf:order_addrPCA' %}" class="bs-example bs-example-form" role="form"
onsubmit="return all_right();">
{% csrf_token %}
{% if addr %}
<input name="addr_id" type="hidden" value="{{ addr.id }}" >
<div class="input-group">
<span class="input-group-addon">收货人:</span>
<input id="order_name" name="order_name" type="text" class="form-control"
value="{{ addr.A_user_name }}">
</div>
<span class="name_a"></span>
<br>
<div class="input-group">
<span class="input-group-addon">电 话:</span>
<input id="tell" name="order_tell" type="text" class="form-control" value="{{ addr.A_tell }}">
</div>
<span class="tell_a"></span>
<br>
<div class="input-group">
<span class="input-group-addon">收货时间:</span>
<input id="time" name="order_time" type="text" class="form-control" placeholder="1"
value="{{ addr.A_time }}">
<span class="input-group-addon">小时后收货</span>
</div>
<span class="time_a"></span>
<br>
<div class="input-group">
<span class="input-group-addon">收货地址:</span>
<select id="p">
<option value="1">请选择</option>
</select>
<select id="c">
<option value="1">请选择</option>
</select>
<select id="a">
<option value="1">请选择</option>
</select>
</div>
<br>
<div class="input-group">
<span class="input-group-addon">详细地址:</span>
<input id="addr_dail" name="order_detail" type="text" class="form-control" placeholder=""
value="{{ addr.A_detail }}">
</div>
<span class="addr_dail_a"></span>
<br>
<br>
<div>
<span id="checkbox">默认地址<input name="is_default" type="checkbox""></span>
</div>
{% else %}
<div class="input-group">
<span class="input-group-addon">收货人:</span>
<input id="order_name" name="order_name" type="text" class="form-control"
value="">
</div>
<span class="name_a"></span>
<br>
<div class="input-group">
<span class="input-group-addon">电 话:</span>
<input id="tell" name="order_tell" type="text" class="form-control" value="">
</div>
<span class="tell_a"></span>
<br>
<div class="input-group">
<span class="input-group-addon">收货时间:</span>
<input id="time" name="order_time" type="text" class="form-control" placeholder="1"
value="1">
<span class="input-group-addon">小时后收货</span>
</div>
<span class="time_a"></span>
<br>
<div class="input-group">
<span class="input-group-addon">收货地址:</span>
<select id="p">
<option value="1">请选择</option>
</select>
<select id="c">
<option value="1">请选择</option>
</select>
<select id="a">
<option value="1">请选择</option>
</select>
</div>
<br>
<div class="input-group">
<span class="input-group-addon">详细地址:</span>
<input id="addr_dail" name="order_detail" type="text" class="form-control" placeholder=""
value="">
</div>
<span class="addr_dail_a"></span>
<br>
<br>
<div>
<span id="checkbox">默认地址<input id="is_default" name="is_default" type="checkbox"></span>
</div>
{% endif %}
<br>
<br>
<button type="submit" class="btn btn-success btn-block">保存</button>
</form>
</div>
{% endblock %}
order_addr.js
$(function () {
the_changge(); // 当输入有变化时,执行
var $p = $('#p');
var $c = $('#c');
var $a = $('#a');
// 点击p时获取省级城市名单
$.get("/axf/PCA/", {"p": 0}, function (data) {
console.log(data['ps_all']);
var ps_all = data['ps_all'];
var l = ps_all.length;
for (var i = 0; i < l; i++) {
$p.append('<option value="' + ps_all[i][0] + '">' + ps_all[i][1] + '</option>');
$c.hide();
$a.hide();
}
$p.append('<option value="' + "1" + '">' + "" + '</option>');
$p.append('<option value="' + "1" + '">' + "" + '</option>');
$p.append('<option value="' + "1" + '">' + "" + '</option>');
});
// p发生变化就移除c、a中的值,并获取新的
$p.change(function () {
if ($("#p option:selected").val() == 1) {
$c.hide();
$a.hide();
$("#addr_dail").val('');
} else {
p_dail = $("#p option:selected").text();
$("#addr_dail").val(p_dail + ",");
$(".addr_dail_a").html("").css("color", "green");
$(".addr_dail_a").children().remove();
$c.children().not(':eq(0)').remove();
$c.show();
$a.children().not(':eq(0)').remove();
$a.hide();
c_pid = $("#p option:selected").val();
console.log(c_pid);
// 返回选中数据
$.get("/axf/PCA/", {"c_pid": c_pid}, function (data) {
var cs_all = data['cs_all'];
for (var i = 0; i < cs_all.length; i++) {
$c.append('<option value="' + cs_all[i][0] + '">' + cs_all[i][1] + '</option>');
}
});
}
});
// c发生变化就移除a中的值,并获取新的
$c.change(function () {
if ($("#c option:selected").val() == 1) {
$a.hide();
$("#p option:selected").val();
$("#addr_dail").val(p_dail);
} else {
p_dail = $("#p option:selected").text();
c_dail = $("#c option:selected").text();
$("#addr_dail").val(p_dail + c_dail + ",");
$a.children().not(':eq(0)').remove();
a_pid = $("#c option:selected").val();
console.log(a_pid);
// 返回选中数据
$.get("/axf/PCA/", {"a_pid": a_pid}, function (data) {
var as_all = data['as_all'];
if (as_all.length > 0) {
$a.show();
for (var i = 0; i < as_all.length; i++) {
$a.append('<option value="' + as_all[i][0] + '">' + as_all[i][1] + '</option>');
}
}
});
}
});
// a发生变化时,将p\c\a中的城市地名设为详细地址的值
$a.change(function () {
// 如果a选中的是“请选择”,给详细地址复制的是p+c
if ($("#a option:selected").val() == 1) {
$("#p option:selected").val();
$("#c option:selected").val();
$("#addr_dail").val(p_dail + c_dail + ",");
} else {
p_dail = $("#p option:selected").text();
c_dail = $("#c option:selected").text();
a_dail = $("#a option:selected").text();
$("#addr_dail").val(p_dail + c_dail + a_dail + ",");
}
});
})
;
function the_changge() {
// 姓名输入后,验证姓名
var $order_name = $('#order_name');
var order_name = $order_name.val().trim();
var $name_a = $(".name_a");
$order_name.change(function () {
if (!order_name) {
$name_a.html("").css("color", "green");
$name_a.children().remove();
}
});
// 地址输入后,验证地址
var $addr_dail = $('#addr_dail');
var addr_dail = $addr_dail.val().trim();
var $addr_dail_a = $(".addr_dail_a");
$addr_dail.change(function () {
if (!addr_dail) {
$addr_dail_a.html("").css("color", "green");
$addr_dail_a.children().remove();
}
});
// 电话输入后,验证电话
var $tell = $('#tell');
var $tell_a = $(".tell_a");
$tell.change(function () {
if ($tell.val().trim()) {
var reg = /^[\d]{4,20}$/;
if (!reg.test(jQuery($tell).val())) {
jQuery($tell).focus();
$tell_a.html("请输入正确的大于3位的手机号").css("color", "red");
$tell_a.append('<br>');
} else {
$tell_a.html("").css("color", "green");
$tell_a.children().remove();
}
}
console.log($tell_a.css("color"));
});
console.log($tell_a.css("color"));
// 时间输入后,验证输入时间
var $time = $('#time');
var $time_a = $(".time_a");
$time.change(function () {
var time_num = $time.val().trim();
if (time_num) {
var reg = /^\d{1,}$/;
if (reg.test(time_num)) {
if (time_num < 100) {
jQuery($time).focus();
$time_a.html("").css("color", "green");
$time_a.children().remove();
} else {
$time_a.html("请输入正确的时间,1-99").css("color", "red");
$time_a.append('<br>');
}
} else {
$time_a.html("请输入正确的时间,1-99").css("color", "red");
$time_a.append('<br>');
}
}
console.log($time_a.css("color"));
});
console.log($time_a.css("color"));
$("#is_default").change(function () {
var is_default = $("#is_default").prop("checked");
if (is_default === true) {
var is_default = 1;
console.log("选为当前用户的默认地址");
} else {
var is_default = 0;
console.log("非默认地址")
}
});
}
function all_right() {
var not_null = 0;
var $order_name = $("#order_name");
var order_name = $order_name.val().trim();
var $name_a = $(".name_a");
var name_color = $name_a.css("color");
var $tell = $("#tell");
var tell = $tell.val().trim();
var $tell_a = $(".tell_a");
var tell_color = $tell_a.css("color");
var $addr_dail = $("#addr_dail");
var addr_dail = $addr_dail.val().trim();
var $addr_dail_a = $(".addr_dail_a");
var addr_dail_color = $addr_dail_a.css("color");
if (!order_name) {
$name_a.html("姓名不能为空").css("color", "red");
$name_a.append('<br>');
not_null = 1;
} else if (name_color === 'rgb(255, 0, 0)') {
console.log("有红");
not_null = 1;
}
if (!tell) {
$tell_a.html("电话不能为空").css("color", "red");
$tell_a.append('<br>');
not_null = 1;
} else if (tell_color === 'rgb(255, 0, 0)') {
console.log("有红");
not_null = 1;
}
if (!addr_dail) {
$addr_dail_a.html("地址不能为空").css("color", "red");
$addr_dail_a.append('<br>');
not_null = 1;
} else if (addr_dail_color === 'rgb(255, 0, 0)') {
console.log("有红");
not_null = 1;
}
if (not_null === 0) {
console.log("通过");
return true
}
console.log("未通过");
return false
}
order_addr.css
.title {
width: 100%;
height: 50px;
background-color: #009688;
}
.font {
color: #fff;
line-height: 50px;
font-size: 20px;
text-indent: -2em;
text-align: center
}
.nav-left {
float: left;
}
.arrow-box{
width: 50px;
height: 26px;
position: relative;
border-radius: 10% 10%;
background: #fff;
text-align: center;
line-height: 26px;
top: 12px;
font-size: 14px;
left: 10px;
}
.container {
padding: 2rem 0.5rem;
overflow: auto;
height: 100%;
width: 100%;
position: fixed;
}
.input-group-addon{
font-size: 10px;
}
#p,#c,#a{
width: 33.3%;
padding: 6px 0px;
font-size: 10px;
font-weight: normal;
line-height: 1;
color: #555;
text-align: center;
background-color: #eee;
border: 1px solid #000000;
border-radius: 4px;
}
input[type="checkbox"]{
margin-left: 0.2rem;
margin-top: 0;
height: 0.5rem;
width: 0.5rem;
}
#checkbox{
float: right;
margin-right: 0.4rem;
}
.tell_a,.time_a,.name_a,.addr_dail_a{
margin-left: 2rem;
}
7、中间件
记得在中间件里面添加上这几个路径,收货信息编辑和保存时需要获取的登录信息
"/axf/orderaddrPCA/",
"/axf/orderaddrlist/",
"/axf/orderaddrselect/",
8、访问截图