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 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 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 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 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/')