25.Django大型电商项目之地址管理——如何使用三级联动菜单数据加载地址、保存数据、动态获取数据、设置默认值

1. 地址管理基本页面

1.1 概述

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

1.2 流程

修改templates的跳转链接center.html

<ul>
    <li><a href="/userapp/address/">地址管理</a></li>
</ul>

templates

{% extends 'base.html' %}
{% block title %}用户中心{% endblock %}
{% load static %}

{% block headerjs %}
    <script src="{% static 'css/assets/js/jquery.min.js' %}" type="text/javascript"></script>
    <script src="{% static 'css/AmazeUI-2.4.2/assets/js/amazeui.js' %}"></script>
{% endblock %}

{% block headercss %}
    <link href="{% static 'css/assets/css/admin.css' %}" rel="stylesheet" type="text/css">
    <link href="{% static 'css/assets/css/amazeui.css' %}" rel="stylesheet" type="text/css">
    <link href="{% static 'css/assets/css/personal.css' %}" rel="stylesheet" type="text/css">
    <link href="{% static 'css/assets/css/addstyle.css' %}" rel="stylesheet" type="text/css">
{% endblock %}

{% block main %}
{% csrf_token %}
<div class="Bott">
    <div class="wrapper clearfix" style="margin: 0 auto">
        <div class="zuo fl" style="margin-left: 100px">
            <h3>
                <a href="http://127.0.0.1:8000/"><img src="{% static 'images/tx.png' %}"></a>
                <p class="clearfix"><span class="fl">[{{userInfo.uname}}]</span><span class="fr logout">[退出登录]</span>
                </p>
            </h3>
            <div>
                <ul>
                    <li><a href="http://127.0.0.1:8000/user/usercenter/#">我的订单</a></li>
                </ul>
                <ul>
                    <li><a href="/userapp/address/">地址管理</a></li>
                </ul>
                <ul>
                    <li><a href="http://127.0.0.1:8000/">回到首页</a></li>
                </ul>

            </div>
        </div>
        <div class="you fl main-wrap">
            <div class="user-address">
                <!--标题 -->
                <div class="am-cf am-padding">
                    <div class="am-fl am-cf"><strong class="am-text-danger am-text-lg">地址管理</strong> /
                        <small>Address&nbsp;list</small></div>
                </div>
                <hr>
                <ul class="am-avg-sm-1 am-avg-md-3 am-thumbnails">

                    <li class="user-addresslist defaultAddr">
                        <span class="new-option-r"><i class="am-icon-check-circle"></i>默认地址</span>
                        <p class="new-tit new-p-re">
                            <span class="new-txt">小叮当</span>
                            <span class="new-txt-rd2">159****1622</span>
                        </p>
                        <div class="new-mu_l2a new-p-re">
                            <p class="new-mu_l2cw">
                                <span class="title">地址:</span>
                                <span class="province">湖北</span><span class="city">武汉</span><span class="dist">洪山</span><span class="street">雄楚大道666号(中南财经政法大学)</span>
                            </p>
                        </div>
                        <div class="new-addr-btn">
                            <a href="#"><i class="am-icon-edit"></i>编辑</a>
                            <span class="new-addr-bar">|</span>
                            <a href="javascript:void(0);" onclick="delClick(this);"><i class="am-icon-trash"></i>删除</a>
                        </div>
                    </li>

                    <li class="user-addresslist">
                        <span class="new-option-r"><i class="am-icon-check-circle"></i>设为默认</span>
                        <p class="new-tit new-p-re">
                            <span class="new-txt">小叮当</span>
                            <span class="new-txt-rd2">159****1622</span>
                        </p>
                        <div class="new-mu_l2a new-p-re">
                            <p class="new-mu_l2cw">
                                <span class="title">地址:</span>
                                <span class="province">湖北</span><span class="city">武汉</span><span class="dist">洪山</span><span class="street">雄楚大道666号(中南财经政法大学)</span>
                            </p>
                        </div>
                        <div class="new-addr-btn">
                            <a href="#"><i class="am-icon-edit"></i>编辑</a>
                            <span class="new-addr-bar">|</span>
                            <a href="javascript:void(0);" onclick="delClick(this);"><i class="am-icon-trash"></i>删除</a>
                        </div>
                    </li>
                    <li class="user-addresslist">
                        <span class="new-option-r"><i class="am-icon-check-circle"></i>设为默认</span>
                        <p class="new-tit new-p-re">
                            <span class="new-txt">小叮当</span>
                            <span class="new-txt-rd2">159****1622</span>
                        </p>
                        <div class="new-mu_l2a new-p-re">
                            <p class="new-mu_l2cw">
                                <span class="title">地址:</span>
                                <span class="province">湖北</span><span class="city">武汉</span><span class="dist">洪山</span><span class="street">雄楚大道666号(中南财经政法大学)</span>
                            </p>
                        </div>
                        <div class="new-addr-btn">
                            <a href="#"><i class="am-icon-edit"></i>编辑</a>
                            <span class="new-addr-bar">|</span>
                            <a href="javascript:void(0);" onclick="delClick(this);"><i class="am-icon-trash"></i>删除</a>
                        </div>
                    </li>
                </ul>
                <div class="clear"></div>
                <a class="new-abtn-type" data-am-modal="{target: '#doc-modal-1', closeViaDimmer: 0}">添加新地址</a>
                <!--例子-->
                <div class="" id="doc-modal-1">

                    <div class="add-dress">

                        <!--标题 -->
                        <div class="am-cf am-padding">
                            <div class="am-fl am-cf"><strong class="am-text-danger am-text-lg">新增地址</strong> /
                                <small>Add&nbsp;address</small></div>
                        </div>
                        <hr>

                        <div class="am-u-md-12 am-u-lg-8" style="margin-top: 20px;">
                            <form class="am-form am-form-horizontal">

                                <div class="am-form-group">
                                    <label for="user-name" class="am-form-label">收货人</label>
                                    <div class="am-form-content">
                                        <input type="text" id="user-name" placeholder="收货人">
                                    </div>
                                </div>

                                <div class="am-form-group">
                                    <label for="user-phone" class="am-form-label">手机号码</label>
                                    <div class="am-form-content">
                                        <input id="user-phone" placeholder="手机号必填" type="email">
                                    </div>
                                </div>
                                <div class="am-form-group">
                                    <label for="user-address" class="am-form-label">所在地</label>
                                    <div class="am-form-content address">
                                        <select data-am-selected="" style="display: none;">
                                            <option value="a">浙江省</option>
                                            <option value="b" selected="">湖北省</option>
                                        </select>
                                        <div class="am-selected am-dropdown " id="am-selected-j6xr4"
                                            data-am-dropdown=""> <button type="button"
                                                class="am-selected-btn am-btn am-dropdown-toggle am-btn-default"> <span
                                                    class="am-selected-status am-fl">湖北省</span> <i
                                                    class="am-selected-icon am-icon-caret-down"></i> </button>
                                            <div class="am-selected-content am-dropdown-content">
                                                <h2 class="am-selected-header"><span
                                                        class="am-icon-chevron-left">返回</span></h2>
                                                <ul class="am-selected-list">
                                                    <li class="" data-index="0" data-group="0" data-value="a"> <span
                                                            class="am-selected-text">浙江省</span> <i
                                                            class="am-icon-check"></i></li>
                                                    <li class="am-checked" data-index="1" data-group="0" data-value="b">
                                                        <span class="am-selected-text">湖北省</span> <i
                                                            class="am-icon-check"></i></li>
                                                </ul>
                                                <div class="am-selected-hint"></div>
                                            </div>
                                        </div>
                                        <select data-am-selected="" style="display: none;">
                                            <option value="a">温州市</option>
                                            <option value="b" selected="">武汉市</option>
                                        </select>
                                        <div class="am-selected am-dropdown " id="am-selected-qmuwx"
                                            data-am-dropdown=""> <button type="button"
                                                class="am-selected-btn am-btn am-dropdown-toggle am-btn-default"> <span
                                                    class="am-selected-status am-fl">武汉市</span> <i
                                                    class="am-selected-icon am-icon-caret-down"></i> </button>
                                            <div class="am-selected-content am-dropdown-content">
                                                <h2 class="am-selected-header"><span
                                                        class="am-icon-chevron-left">返回</span></h2>
                                                <ul class="am-selected-list">
                                                    <li class="" data-index="0" data-group="0" data-value="a"> <span
                                                            class="am-selected-text">温州市</span> <i
                                                            class="am-icon-check"></i></li>
                                                    <li class="am-checked" data-index="1" data-group="0" data-value="b">
                                                        <span class="am-selected-text">武汉市</span> <i
                                                            class="am-icon-check"></i></li>
                                                </ul>
                                                <div class="am-selected-hint"></div>
                                            </div>
                                        </div>
                                        <select data-am-selected="" style="display: none;">
                                            <option value="a">瑞安区</option>
                                            <option value="b" selected="">洪山区</option>
                                        </select>
                                        <div class="am-selected am-dropdown " id="am-selected-pqsxb"
                                            data-am-dropdown=""> <button type="button"
                                                class="am-selected-btn am-btn am-dropdown-toggle am-btn-default"> <span
                                                    class="am-selected-status am-fl">洪山区</span> <i
                                                    class="am-selected-icon am-icon-caret-down"></i> </button>
                                            <div class="am-selected-content am-dropdown-content">
                                                <h2 class="am-selected-header"><span
                                                        class="am-icon-chevron-left">返回</span></h2>
                                                <ul class="am-selected-list">
                                                    <li class="" data-index="0" data-group="0" data-value="a"> <span
                                                            class="am-selected-text">瑞安区</span> <i
                                                            class="am-icon-check"></i></li>
                                                    <li class="am-checked" data-index="1" data-group="0" data-value="b">
                                                        <span class="am-selected-text">洪山区</span> <i
                                                            class="am-icon-check"></i></li>
                                                </ul>
                                                <div class="am-selected-hint"></div>
                                            </div>
                                        </div>
                                    </div>
                                </div>

                                <div class="am-form-group">
                                    <label for="user-intro" class="am-form-label">详细地址</label>
                                    <div class="am-form-content">
                                        <textarea class="" rows="3" id="user-intro" placeholder="输入详细地址"></textarea>
                                        <small>100字以内写出你的详细地址...</small>
                                    </div>
                                </div>

                                <div class="am-form-group">
                                    <div class="am-u-sm-9 am-u-sm-push-3">
                                        <a class="am-btn am-btn-danger">保存</a>
                                        <a href="javascript: void(0)" class="am-close am-btn am-btn-danger"
                                            data-am-modal-close="">取消</a>
                                    </div>
                                </div>
                            </form>
                        </div>

                    </div>

                </div>

            </div>

            <script type="text/javascript">
                $(document).ready(function () {
                    $(".new-option-r").click(function () {
                        $(this).parent('.user-addresslist').addClass("defaultAddr").siblings().removeClass("defaultAddr");
                    });

                    var $ww = $(window).width();
                    if ($ww > 640) {
                        $("#doc-modal-1").removeClass("am-modal am-modal-no-btn")
                    }

                })
            </script>

            <div class="clear"></div>

        </div>

    </div>
</div>

{% endblock %}

{% block footerjs %}
<script>
    $('.logout').click(function () {

        $.ajax({
            type: 'post',
            url: '/userapp/loginout/',
            data: 'csrfmiddlewaretoken=' + $('input[name="csrfmiddlewaretoken"]').val(),
            success: function (data) {
                window.location = '/userapp/login/'
            }
        })
    })
</script>
{% endblock %}

views.py

# 地址管理
class AddressView(View):
    def get(self,request):
        return render(request,'userapp/address.html')

2. 加载三级联动菜单数据(省市县的联动选择)

2.1 概述

后端:
在后端中,编写接口,根据id获取名称返回一个列表即可。
前端:
先删除原本代码中的展示数据,添加onChange函数修改为动态
给每一个函数添加调用下一个选择框,依次向下调用,前端发送请求给后端,获取到数据,使用循环遍历添加到标签

2.2 代码实现

views

# netshop\userapp\views.py
from django.shortcuts import render,HttpResponse,redirect
from django.http import JsonResponse
from django.views import View
from userapp.models import *
import jsonpickle
from utils.code import gene_text
from django.core import serializers
# 级联加载地址
def loadArea(request):
    pid = request.GET.get('pid',-1)
    # 根据pid查询数据
    areaList = Area.objects.filter(parentid=pid)
    # 返回响应(异步发送需要JsonResponse,Json格式,需要把列表序列化)
    return JsonResponse({'areaList':serializers.serialize('json',areaList)})

templates

<div class="am-form-group">
     <label for="user-address" class="am-form-label">所在地</label>
           <div class="am-form-content address">
                 <!-- 级联操作:当option1发生改变就调用option2获取数据 -->
                 <select id="province" onchange="loadCity()"></select>
                 <select id="city" onchange="loadTown()"></select>
                 <select id="town"></select>
           </div>
</div>
// 加载页面后加载地址级联:先把第一个选择框给加载了
    $(function(){
        loadProvince()
    })
    // 加载省
    function loadProvince() {
        loadArea(0,'province',loadCity)
    }

    // 加载市区
    function loadCity() {
        loadArea($('#province').val(),'city',loadTown)
    }

    // 加载县
    function loadTown() {
        loadArea($('#city').val(),'town')
    }

    function loadArea(pid, selectedId,nextLoad) {
        // 清空当前select框种的option
        $('#'+selectedId).empty()
        // 发送异步请求加载数据
        $.get('/userapp/loadArea/', {'pid':pid}, function(result){
            areaList = result.areaList
            areaList = JSON.parse(areaList)
            for(var i=0; i<areaList.length; i++){
                area = areaList[i]
                // 给每个选择框的标签中新增标签option
                $('#'+selectedId).append('<option value="'+area.pk+'">'+area.fields.areaname+'</option>')
            }
        })
        // 加载市
        if(nextLoad!=null){
            nextLoad();
        }
    }

3.保存地址

views.py

# 地址管理
class AddressView(View):
    def get(self,request):
        return render(request,'userapp/address.html')
    def post(self,request):
        # 获取表单数据
        aname = request.POST.get('aname','')
        aphone = request.POST.get('aphone','')
        addr = request.POST.get('addr','')
        # 从session中获取登录用户
        userinfo = request.session.get('user','')
        if userinfo:
            user = jsonpickle.loads(userinfo)
        # 设置是否是默认地址
        # 根据当前登录的用户获取地址,查看是否是第一个地址
        count = user.address_set.count() # 若没有地址的情况下,就设置为默认地址
        if count == 0:
            isdefault = True
        else:
            isdefault = False
        # 插入数据库
        Address.objects.create(aname=aname, aphone=aphone, addr=addr, userinfo=user, isdefault=isdefault)
        return redirect('/userapp/address/')

templates

<div class="am-u-md-12 am-u-lg-8" style="margin-top: 20px;">
                            <form id="frmid" class="am-form am-form-horizontal" action="/userapp/address/" method="post">
                                {% csrf_token %}
                                <div class="am-form-group">
                                    <label for="user-name" class="am-form-label">收货人</label>
                                    <div class="am-form-content">
                                        <input type="text" id="user-name" name='anme' placeholder="收货人">
                                    </div>
                                </div>

                                <div class="am-form-group">
                                    <label for="user-phone" class="am-form-label">手机号码</label>
                                    <div class="am-form-content">
                                        <input id="user-phone" placeholder="手机号必填" type="text" name="aphone">
                                    </div>
                                </div>
                                <div class="am-form-group">
                                    <label for="user-address" class="am-form-label">所在地</label>
                                    <div class="am-form-content address">
                                        <!-- 级联操作:当option1发生改变就调用option2获取数据 -->
                                        <select id="province" onchange="loadCity()"></select>
                                        <select id="city" onchange="loadTown()"></select>
                                        <select id="town"></select>
                                    </div>
                                </div>

                                <div class="am-form-group">
                                    <label for="user-intro" class="am-form-label">详细地址</label>
                                    <div class="am-form-content">
                                        <!-- 失去焦点时,获取数据 -->
                                        <textarea class="" rows="3" id="addr" onfocus="getAddressInfo()" name="addr" placeholder="输入详细地址"></textarea>
                                        <small>100字以内写出你的详细地址...</small>
                                    </div>
                                </div>

                                <div class="am-form-group">
                                    <div class="am-u-sm-9 am-u-sm-push-3">
                                        <a class="am-btn am-btn-danger" onclick="$('#frmid').submit();">保存</a>
                                        <a href="javascript: void(0)" class="am-close am-btn am-btn-danger"
                                            data-am-modal-close="">取消</a>
                                    </div>
                                </div>
                            </form>
                        </div>
function getAddressInfo(){
        // 获取选择的省市县
        var province = $('#province>option:selected').text()
        var city = $('#city>option:selected').text()
        var town = $('#town>option:selected').text()
        // 添加省市县到详细地址中,方便用户输入
        $('#addr').val(province+" "+city+" "+town)


    }

4.动态获取收货地址与设置默认地址

4.1 概述

动态获取收获地址
在原先的静态属性上,只保留一个属性。在后端中,我们先根据session获取到用户的基本信息。然后去数据库查询相关的收获地址返回一个对象给前端。前端进行循环遍历对象,得到单个对象后,再把原先的属性值改为动态的即可。
设置默认地址
在每个收获地址上,都有一个defaultAddr class属性,所以,我们要先判断是否为True。然后,我们根据数据模型,发现数据模型中存在一个默认值。在后端中,我们先获取到用户,获取其所有的地址,循环遍历,根据前端返回的数据,若是点击的就把默认值改为True,其余改成False。

4.2 代码展示

templates

<div class="user-address">
                <!--标题 -->
                <div class="am-cf am-padding">
                    <div class="am-fl am-cf"><strong class="am-text-danger am-text-lg">地址管理</strong> /
                        <small>Address&nbsp;list</small></div>
                </div>
                <hr>
                <ul class="am-avg-sm-1 am-avg-md-3 am-thumbnails">
                    {% for addr in addr_list %}
                        <li class="user-addresslist {% if addr.isdefault == True %} defaultAddr {% endif %}" onclick="updateDefaultAddr('{{addr.id}}')">
                            <span class="new-option-r"><i class="am-icon-check-circle"></i>默认地址</span>
                            <p class="new-tit new-p-re">
                                <span class="new-txt">{{addr.aname}}</span>
                                <span class="new-txt-rd2">{{addr.aphone}}</span>
                            </p>
                            <div class="new-mu_l2a new-p-re">
                                <p class="new-mu_l2cw">
                                    <span class="title">地址:</span>
                                    <span class="street">{{addr.addr}}</span>
                                </p>
                            </div>
                            <div class="new-addr-btn">
                                <a href="#"><i class="am-icon-edit"></i>编辑</a>
                                <span class="new-addr-bar">|</span>
                                <a href="javascript:void(0);" onclick="delClick(this);"><i class="am-icon-trash"></i>删除</a>
                            </div>
                        </li>
                    {% endfor %}

                </ul>

                <div class="clear"></div>
                <a class="new-abtn-type" data-am-modal="{target: '#doc-modal-1', closeViaDimmer: 0}">添加新地址</a>
                <!--例子-->
                <div class="" id="doc-modal-1">

                    <div class="add-dress">

                        <!--标题 -->
                        <div class="am-cf am-padding">
                            <div class="am-fl am-cf"><strong class="am-text-danger am-text-lg">新增地址</strong> /
                                <small>Add&nbsp;address</small></div>
                        </div>
                        <hr>

                        <div class="am-u-md-12 am-u-lg-8" style="margin-top: 20px;">
                            <form id="frmid" class="am-form am-form-horizontal" action="/userapp/address/" method="post">
                                {% csrf_token %}
                                <div class="am-form-group">
                                    <label for="user-name" class="am-form-label">收货人</label>
                                    <div class="am-form-content">
                                        <input type="text" id="user-name" name='anme' placeholder="收货人">
                                    </div>
                                </div>

                                <div class="am-form-group">
                                    <label for="user-phone" class="am-form-label">手机号码</label>
                                    <div class="am-form-content">
                                        <input id="user-phone" placeholder="手机号必填" type="text" name="aphone">
                                    </div>
                                </div>
                                <div class="am-form-group">
                                    <label for="user-address" class="am-form-label">所在地</label>
                                    <div class="am-form-content address">
                                        <!-- 级联操作:当option1发生改变就调用option2获取数据 -->
                                        <select id="province" onchange="loadCity()"></select>
                                        <select id="city" onchange="loadTown()"></select>
                                        <select id="town"></select>
                                    </div>
                                </div>

                                <div class="am-form-group">
                                    <label for="user-intro" class="am-form-label">详细地址</label>
                                    <div class="am-form-content">
                                        <!-- 失去焦点时,获取数据 -->
                                        <textarea class="" rows="3" id="addr" onfocus="getAddressInfo()" name="addr" placeholder="输入详细地址"></textarea>
                                        <small>100字以内写出你的详细地址...</small>
                                    </div>
                                </div>

                                <div class="am-form-group">
                                    <div class="am-u-sm-9 am-u-sm-push-3">
                                        <a class="am-btn am-btn-danger" onclick="$('#frmid').submit();">保存</a>
                                        <a href="javascript: void(0)" class="am-close am-btn am-btn-danger"
                                            data-am-modal-close="">取消</a>
                                    </div>
                                </div>
                            </form>
                        </div>

                    </div>

                </div>

            </div>
<script>
    function updateDefaultAddr(addrId){
        // 修改默认地址
        window.location.href = '/userapp/updateDefault/?addrId='+addrId
    }
</script>

views

# netshop\userapp\views.py
from django.shortcuts import render,HttpResponse,redirect
from django.http import JsonResponse
from django.views import View
from userapp.models import *
import jsonpickle
from utils.code import gene_text
from django.core import serializers
# 地址管理
class AddressView(View):
    def get(self,request):
        # 获取当前登录用户
        userinfo = request.session.get('user','')
        if userinfo:
            user = jsonpickle.loads(userinfo)
        # 获取当前登录用户关联的收获地址
        addr_list = user.address_set.all()
        return render(request,'userapp/address.html',{'addr_list':addr_list})
    def post(self,request):
        # 获取表单数据
        aname = request.POST.get('aname','')
        aphone = request.POST.get('aphone','')
        addr = request.POST.get('addr','')
        # 从session中获取登录用户
        userinfo = request.session.get('user','')
        if userinfo:
            user = jsonpickle.loads(userinfo)
        # 设置是否是默认地址
        # 根据当前登录的用户获取地址,查看是否是第一个地址
        count = user.address_set.count() # 若没有地址的情况下,就设置为默认地址
        if count == 0:
            isdefault = True
        else:
            isdefault = False
        # 插入数据库
        Address.objects.create(aname=aname, aphone=aphone, addr=addr, userinfo=user, isdefault=isdefault)
        return redirect('/userapp/address/')


# 级联加载地址
def loadArea(request):
    pid = request.GET.get('pid',-1)
    # 根据pid查询数据
    areaList = Area.objects.filter(parentid=pid)
    # 返回响应(异步发送需要JsonResponse,Json格式,需要把列表序列化)
    return JsonResponse({'areaList':serializers.serialize('json',areaList)})

def updateDefaultAddrView(request):
    # 获取请求参数addrId
    addrId = int(request.GET.get('addrId',-1))

    # 修改当前登录用户的默认地址
    # 从session中获取登录用户
    userinfo = request.session.get('user','')
    if userinfo:
        user = jsonpickle.loads(userinfo)
        # 获取当前登录用户的所有地址
        addressList = user.address_set.all()
        # 循环遍历地址列表
        for address in addressList:
            # 设置默认地址
            if address.id == addrId:
                address.isdefault = True
            else:
                address.isdefault = False
            address.save()
    return redirect('/userapp/address/')

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想成为数据分析师的开发工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值