您当前的位置: 首页 > 

IT之一小佬

暂无认证

  • 0浏览

    0关注

    1192博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

美多商城之用户中心(收货地址2)

IT之一小佬 发布时间:2021-07-03 18:09:30 ,浏览量:0

三、收货地址 3.2 新增地址前后端逻辑 1. 定义用户地址模型类

1.用户地址模型类

from meiduo_mall.utils.models import BaseModel


class Address(BaseModel):
    """用户地址"""
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='addresses', verbose_name='用户')
    title = models.CharField(max_length=20, verbose_name='地址名称')
    receiver = models.CharField(max_length=20, verbose_name='收货人')
    province = models.ForeignKey('areas.Area', on_delete=models.PROTECT, related_name='province_addresses', verbose_name='省')
    city = models.ForeignKey('areas.Area', on_delete=models.PROTECT, related_name='city_addresses', verbose_name='市')
    district = models.ForeignKey('areas.Area', on_delete=models.PROTECT, related_name='district_addresses', verbose_name='区')
    place = models.CharField(max_length=50, verbose_name='地址')
    mobile = models.CharField(max_length=11, verbose_name='手机')
    tel = models.CharField(max_length=20, null=True, blank=True, default='', verbose_name='固定电话')
    email = models.CharField(max_length=30, null=True, blank=True, default='', verbose_name='电子邮箱')
    is_deleted = models.BooleanField(default=False, verbose_name='逻辑删除')

    class Meta:
        db_table = 'tb_address'
        verbose_name = '用户地址'
        verbose_name_plural = verbose_name
        ordering = ['-update_time']

2.Address模型类说明

  • Address模型类中的外键指向areas/models里面的Area。指明外键时,可以使用应用名.模型类名来定义。
  • ordering 表示在进行Address查询时,默认使用的排序方式。
    • ordering = ['-update_time'] : 根据更新的时间倒叙。

3.补充用户模型默认地址字段

class User(AbstractUser):
    """自定义用户模型类"""
    mobile = models.CharField(max_length=11, unique=True, verbose_name='手机号')
    email_active = models.BooleanField(default=False, verbose_name='邮箱验证状态')
    default_address = models.ForeignKey('Address', related_name='users', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='默认地址')

    class Meta:
        db_table = 'tb_users'
        verbose_name = '用户'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.username

数据库迁移:

2. 新增地址接口设计和定义

1.请求方式

选项方案请求方法POST请求地址/addresses/create/

2.请求参数:JSON    【用户收货地址都是以局部刷新的形式来做的】

参数名类型是否必传说明receiverstring是收货人province_idstring是省份IDcity_idstring是城市IDdistrict_idstring是区县IDplacestring是收货地址mobilestring是手机号telstring否固定电话emailstring否邮箱

3.响应结果:JSON

字段说明code状态码errmsg错误信息id地址IDreceiver收货人province省份名称city城市名称district区县名称place收货地址mobile手机号tel固定电话email邮箱 3. 新增地址后端逻辑实现

提示:

  • 用户地址数量有上限,最多20个,超过地址数量上限就返回错误信息
from . import constants
from .models import Address


class CreateAddressView(LoginRequiredMixin, View):
    """新增地址"""

    def post(self, request):
        """实现新增地址逻辑"""
        # 判断是否超过地址上限:最多20个
        # Address.objects.filter(user=request.user).count()
        count = request.user.addresses.count()
        if count >= constants.USER_ADDRESS_COUNTS_LIMIT:
            return http.JsonResponse({'code': RETCODE.THROTTLINGERR, 'errmsg': '超过地址数量上限'})

        # 接收参数
        json_dict = json.loads(request.body.decode())
        receiver = json_dict.get('receiver')
        province_id = json_dict.get('province_id')
        city_id = json_dict.get('city_id')
        district_id = json_dict.get('district_id')
        place = json_dict.get('place')
        mobile = json_dict.get('mobile')
        tel = json_dict.get('tel')
        email = json_dict.get('email')

        # 校验参数
        if not all([receiver, province_id, city_id, district_id, place, mobile]):
            return http.HttpResponseForbidden('缺少必传参数')
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('参数mobile有误')
        if tel:
            if not re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel):
                return http.HttpResponseForbidden('参数tel有误')
        if email:
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return http.HttpResponseForbidden('参数email有误')

        # 保存地址信息
        try:
            address = Address.objects.create(  # create方法中封装了save()方法
                user=request.user,
                title = receiver,  # 标题默认就是收货人
                receiver = receiver,
                province_id = province_id,
                city_id = city_id,
                district_id = district_id,
                place = place,
                mobile = mobile,
                tel = tel,
                email = email
            )

            # 设置默认地址
            if not request.user.default_address:
                request.user.default_address = address
                request.user.save()
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '新增地址失败'})

        # 新增地址成功,将新增的地址响应给前端实现局部刷新
        address_dict = {
            "id": address.id,
            "title": address.title,
            "receiver": address.receiver,
            "province": address.province.name,
            "city": address.city.name,
            "district": address.district.name,
            "place": address.place,
            "mobile": address.mobile,
            "tel": address.tel,
            "email": address.email
        }

        # 响应保存结果
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '新增地址成功', 'address': address_dict})

4. 新增地址前端逻辑实现
save_address(){
    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 {
        // 新增地址
        let url = '/addresses/create/';
        axios.post(url, this.form_address, {
            headers: {
                'X-CSRFToken':getCookie('csrftoken')
            },
            responseType: 'json'
        })
            .then(response => {
                if (response.data.code == '0') {
                    // 局部刷新界面:展示所有地址信息

                } else if (response.data.code == '4101') {
                    location.href = '/login/?next=/addresses/';
                } else {
                    alert(response.data.errmsg);
                }
            })
            .catch(error => {
                console.log(error.response);
            })
    }
},

3.3 展示地址前后端逻辑 1. 展示地址接口设计和定义

1.请求方式

选项方案请求方法GET请求地址/addresses/

2.请求参数

3.响应结果:HTML

user_center_site.html
2. 展示地址后端逻辑实现
class AddressView(LoginRequiredMixin, View):
    """用户收货地址"""

    def get(self, request):
        """提供收货地址界面"""
        # 获取用户地址列表
        login_user = request.user
        addresses = Address.objects.filter(user=login_user, is_deleted=False)

        address_dict_list = []
        for address in addresses:
            address_dict = {
                "id": address.id,
                "title": address.title,
                "receiver": address.receiver,
                "province": address.province.name,
                "city": address.city.name,
                "district": address.district.name,
                "place": address.place,
                "mobile": address.mobile,
                "tel": address.tel,
                "email": address.email
            }
            address_dict_list.append(address_dict)

        context = {
            'default_address_id': login_user.default_address_id,
            'addresses': address_dict_list,
        }

        return render(request, 'user_center_site.html', context)
3. 展示地址前端逻辑实现

1.将后端模板数据传递到Vue.js


    let addresses = {{ addresses | safe }};
    let default_address_id = "{{ default_address_id }}";

data: {
    addresses: JSON.parse(JSON.stringify(addresses)),
    default_address_id: default_address_id,
},

2.user_center_site.html中渲染地址信息

新增收货地址 你已创建了[[ addresses.length ]]个收货地址,最多可创建20个
[[ address.title ]] 默认地址 ×
  • 收货人:[[ address.receiver ]]
  • 所在地区:[[ address.province ]] [[address.city]] [[ address.district ]]
  • 地址:[[ address.place ]]
  • 手机:[[ address.mobile ]]
  • 固定电话:[[ address.tel ]]
  • 电子邮箱:[[ address.email ]]
设为默认 编辑

3.完善user_center_site.js中成功新增地址后的局部刷新

if (response.data.code == '0') {
    // 局部刷新界面:展示所有地址信息,将新的地址添加到头部
    this.addresses.splice(0, 0, response.data.address);
    this.is_show_edit = false;
}

关注
打赏
1665675218
查看更多评论
立即登录/注册

微信扫码登录

0.0408s