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

news/2024/9/22 20:29:27/

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"> <spanclass="am-selected-status am-fl">湖北省</span> <iclass="am-selected-icon am-icon-caret-down"></i> </button><div class="am-selected-content am-dropdown-content"><h2 class="am-selected-header"><spanclass="am-icon-chevron-left">返回</span></h2><ul class="am-selected-list"><li class="" data-index="0" data-group="0" data-value="a"> <spanclass="am-selected-text">浙江省</span> <iclass="am-icon-check"></i></li><li class="am-checked" data-index="1" data-group="0" data-value="b"><span class="am-selected-text">湖北省</span> <iclass="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"> <spanclass="am-selected-status am-fl">武汉市</span> <iclass="am-selected-icon am-icon-caret-down"></i> </button><div class="am-selected-content am-dropdown-content"><h2 class="am-selected-header"><spanclass="am-icon-chevron-left">返回</span></h2><ul class="am-selected-list"><li class="" data-index="0" data-group="0" data-value="a"> <spanclass="am-selected-text">温州市</span> <iclass="am-icon-check"></i></li><li class="am-checked" data-index="1" data-group="0" data-value="b"><span class="am-selected-text">武汉市</span> <iclass="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"> <spanclass="am-selected-status am-fl">洪山区</span> <iclass="am-selected-icon am-icon-caret-down"></i> </button><div class="am-selected-content am-dropdown-content"><h2 class="am-selected-header"><spanclass="am-icon-chevron-left">返回</span></h2><ul class="am-selected-list"><li class="" data-index="0" data-group="0" data-value="a"> <spanclass="am-selected-text">瑞安区</span> <iclass="am-icon-check"></i></li><li class="am-checked" data-index="1" data-group="0" data-value="b"><span class="am-selected-text">洪山区</span> <iclass="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.areaListareaList = 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 = Trueelse: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 = Trueelse: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):# 获取请求参数addrIdaddrId = 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 = Trueelse:address.isdefault = Falseaddress.save()return redirect('/userapp/address/')

在这里插入图片描述


http://www.ppmy.cn/news/4563.html

相关文章

多元宇宙算法求解电力系统多目标优化问题(Matlab实现)【电气期刊论文复现与算例创新】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f4dd;目前更新&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;电力系统相关知识&#xff0c;期刊论文&…

两台linux服务器rsync自动备份文件

检查rsycn是否安装 检查方法&#xff1a;rpm -qa rsync 出现rsync 包名就是安装了 安装rsycn rsync的安装可以使用yum直接安装&#xff1a;yum install rsync rsycn的服务端/文件接收端配置 1、先创建备份目录 mkdir /data/xsbak2、服务端需要开启rsyncd服务&#xff0c;添加…

css知识复习点

四种css使用方式&#xff1a;内嵌式、外链式、行内式、导入式 复合选择器 后代选择器 选择器之间需要用空格隔开&#xff0c;后代不一定是儿子 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>复合…

Win11+RTX3060+Anconda+CUDA11.3+cuDNN8.2+Pytorch1.10一条龙服务2

Win11RTX3060AncondaCUDA11.3cuDNN8.2Pytorch1.10一条龙服务 &#xff08;1&#xff09;查看安装了哪些包 conda list&#xff08;2)查看当前存在哪些虚拟环境 conda env list &#xff08;3&#xff09;创建虚拟环境&#xff0c;你可以创建好几个虚拟环境&#xff0c;虚拟环…

循环神经网络(RNN)

卷积神经网络和循环神经网络的区别 神经网络的基本原理是:一层中的所有神经元都接受一个输入,将其乘以一个权重,然后经过神经元的偏差进行调整,最后用激励函数把输出值标准化,得到一个神经元的输出。最后将一层中所有神经元的输出相加得到该层的输出。比如卷积神经网络,…

[附源码]Python计算机毕业设计华夏商场红酒管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等…

对数据库事务理解以及脏读、不可重复读以及幻读问题

引言 事务就是能够把多个SQL给打包在一起&#xff0c;变成一个整体。因为有些操作是需要作为一个整体来完成的&#xff0c;比如转账操作&#xff0c;A给B转账100&#xff0c;那么A的账户余额就会减100&#xff0c;B的账户余额就会加100。如果在A转账的过程中&#xff0c;因为某…

Dijkstra迪杰斯特拉算法

1.场景 用于计算一个节点到其他节点的最短路径&#xff0c;特点是由其实点位中心向外层扩展&#xff08;BFS思想&#xff09;&#xff0c;直至扩展到终点为止 2.认识 https://blog.csdn.net/weixin_57128596/article/details/126982769?ops_request_misc%257B%2522request%…