Django 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>&nbsp;&nbsp;人:&nbsp;{{ user_addr.A_user_name }}</li>
                        <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;话:&nbsp;{{ user_addr.A_tell }}</li>
                        <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;址:&nbsp;{{ 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="#">可预订&gt;</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>&nbsp;&nbsp;|&nbsp;&nbsp;<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">&nbsp;&nbsp;&nbsp;&nbsp;话:</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">&nbsp;&nbsp;&nbsp;&nbsp;话:</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、访问截图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

发布了87 篇原创文章 · 获赞 20 · 访问量 1617

猜你喜欢

转载自blog.csdn.net/a__int__/article/details/103839134