用户地址管理代码
后端
在users/views.py中添加视图
class AddressViewSet(mixins.CreateModelMixin, mixins.UpdateModelMixin, GenericViewSet):
"""
用户地址新增与修改
"""
serializer_class = serializers.UserAddressSerializer
permissions = [IsAuthenticated]
def get_queryset(self):
return self.request.user.addresses.filter(is_deleted=False)
# GET /addresses/
def list(self, request, *args, **kwargs):
"""
用户地址列表数据
"""
queryset = self.get_queryset()
serializer = self.get_serializer(queryset, many=True)
user = self.request.user
return Response({
'user_id': user.id,
'default_address_id': user.default_address_id,
'limit': constants.USER_ADDRESS_COUNTS_LIMIT,
'addresses': serializer.data,
})
# POST /addresses/
def create(self, request, *args, **kwargs):
"""
保存用户地址数据
"""
# 检查用户地址数据数目不能超过上限
count = request.user.addresses.count()
if count >= constants.USER_ADDRESS_COUNTS_LIMIT:
return Response({'message': '保存地址数据已达到上限'}, status=status.HTTP_400_BAD_REQUEST)
return super().create(request, *args, **kwargs)
# delete /addresses/<pk>/
def destroy(self, request, *args, **kwargs):
"""
处理删除
"""
address = self.get_object()
# 进行逻辑删除
address.is_deleted = True
address.save()
return Response(status=status.HTTP_204_NO_CONTENT)
# put /addresses/pk/status/
@action(methods=['put'], detail=True)
def status(self, request, pk=None):
"""
设置默认地址
"""
address = self.get_object()
request.user.default_address = address
request.user.save()
return Response({'message': 'OK'}, status=status.HTTP_200_OK)
# put /addresses/pk/title/
# 需要请求体参数 title
@action(methods=['put'], detail=True)
def title(self, request, pk=None):
"""
修改标题
"""
address = self.get_object()
serializer = serializers.AddressTitleSerializer(instance=address, data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)
在users/serializers.py中添加序列化器
class UserAddressSerializer(serializers.ModelSerializer):
"""
用户地址序列化器
"""
province = serializers.StringRelatedField(read_only=True)
city = serializers.StringRelatedField(read_only=True)
district = serializers.StringRelatedField(read_only=True)
province_id = serializers.IntegerField(label='省ID', required=True)
city_id = serializers.IntegerField(label='市ID', required=True)
district_id = serializers.IntegerField(label='区ID', required=True)
class Meta:
model = Address
exclude = ('user', 'is_deleted', 'create_time', 'update_time')
def validate_mobile(self, value):
"""
验证手机号
"""
if not re.match(r'^1[3-9]\d{9}$', value):
raise serializers.ValidationError('手机号格式错误')
return value
def create(self, validated_data):
"""
保存
"""
validated_data['user'] = self.context['request'].user
return super().create(validated_data)
class AddressTitleSerializer(serializers.ModelSerializer):
"""
地址标题
"""
class Meta:
model = Address
fields = ('title',)
在users/urls.py中添加路由
router = routers.DefaultRouter()
router.register(r'addresses', views.AddressViewSet, base_name='addresses')
urlpatterns += router.urls
# POST /addresses/ 新建 -> create
# PUT /addresses/<pk>/ 修改 -> update
# GET /addresses/ 查询 -> list
# DELETE /addresses/<pk>/ 删除 -> destroy
# PUT /addresses/<pk>/status/ 设置默认 -> status
# PUT /addresses/<pk>/title/ 设置标题 -> title
前端
修改user_center_site.js的mounted
mounted: function(){
...
// 补充获取地址数据的请求
axios.get(this.host + '/addresses/', {
headers: {
'Authorization': 'JWT ' + this.token
},
responseType: 'json'
})
.then(response => {
this.addresses = response.data.addresses;
this.limit = response.data.limit;
this.default_address_id = response.data.default_address_id;
})
.catch(error => {
status = error.response.status;
if (status == 401 || status == 403) {
location.href = 'login.html?next=/user_center_site.html';
} else {
alert(error.response.data.detail);
}
})
},
修改user_center_site.js的methods
// 保存地址
save_address: function(){
if (this.error_receiver || this.error_place || this.error_mobile || this.error_email || !this.form_address.province_id || !this.form_address.city_id || !this.form_address.district_id ) {
alert('信息填写有误!');
} else {
this.form_address.title = this.form_address.receiver;
if (this.editing_address_index === '') {
// 新增地址
axios.post(this.host + '/addresses/', this.form_address, {
headers: {
'Authorization': 'JWT ' + this.token
},
responseType: 'json'
})
.then(response => {
// 将新地址添加大数组头部
this.addresses.splice(0, 0, response.data);
this.is_show_edit = false;
})
.catch(error => {
console.log(error.response.data);
})
} else {
// 修改地址
axios.put(this.host + '/addresses/' + this.addresses[this.editing_address_index].id + '/', this.form_address, {
headers: {
'Authorization': 'JWT ' + this.token
},
responseType: 'json'
})
.then(response => {
this.addresses[this.editing_address_index] = response.data;
this.is_show_edit = false;
})
.catch(error => {
alert(error.response.data.detail || error.response.data.message);
})
}
}
},
// 删除地址
del_address: function(index){
axios.delete(this.host + '/addresses/' + this.addresses[index].id + '/', {
headers: {
'Authorization': 'JWT ' + this.token
},
responseType: 'json'
})
.then(response => {
// 从数组中移除地址
this.addresses.splice(index, 1);
})
.catch(error => {
console.log(error.response.data);
})
},
// 设置默认地址
set_default: function(index){
axios.put(this.host + '/addresses/' + this.addresses[index].id + '/status/', {}, {
headers: {
'Authorization': 'JWT ' + this.token
},
responseType: 'json'
})
.then(response => {
this.default_address_id = this.addresses[index].id;
})
.catch(error => {
console.log(error.response.data);
})
},
// 展示编辑标题
show_edit_title: function(index){
this.input_title = this.addresses[index].title;
for(var i=0; i<index; i++) {
this.is_set_title.push(false);
}
this.is_set_title.push(true);
} ,
// 保存地址标题
save_title: function(index){
if (!this.input_title) {
alert("请填写标题后再保存!");
} else {
axios.put(this.host + '/addresses/' + this.addresses[index].id + '/title/', {
title: this.input_title
}, {
headers: {
'Authorization': 'JWT ' + token
},
responseType: 'json'
})
.then(response => {
this.addresses[index].title = this.input_title;
this.is_set_title = [];
})
.catch(error => {
console.log(error.response.data);
})
}
},
// 取消保存地址
cancel_title: function(index){
this.is_set_title = [];
}