- 创建个人收货地址模型类以及用户模型添加默认地址
class User(AbstractUser):
"""用户模型类"""
default_address = models.ForeignKey('Address', related_name='users', null=True, blank=True,on_delete=models.SET_NULL, verbose_name='默认地址')
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']
- 创建视图重写视图函数逻辑实现额外功能并添加额外视图函数
from rest_framework.decorators import action
from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet
from . models import User, Address
from .serializers import CreateUserSerializer
from .serializers import UserDetailSerializer, UserAddressSerialize, AddressTitleSerializer
from . import constants
class AddressViewSet(mixins.CreateModelMixin,mixins.UpdateModelMixin, GenericViewSet):
serializer_class = UserAddressSerialize
# permission_classes = [IsAuthenticated]
def get_object(self):
# return User.objects.get(id=4)
return self.request.user
def create(self, request, *args, **kwargs):
count = request.user.addresses.count()
“”“
在count.py中添加
设置用户收货地址上线
USER_ADDRESS_COUNTS_LIMIT = 20
”“”
if count > constants.USER_ADDRESS_COUNTS_LIMIT:
return Response({'message': '超出上线'})
# super.create()
return super().create(request, *args, **kwargs)
def get_queryset(self):
# return User.objects.get(id=4).addresses.filter(is_deleted=False)
return self.request.user.addresses.filter(is_deleted=False)
def list(self, request, *args, **kwargs):
queryset = self.get_queryset()
serializer = self.get_serializer(queryset, many=True)
user = self.request.user
# user = User.objects.get(id=4)
return Response({
'user_id': user.id,
'default_address_id': user.default_address_id,
'limit': constants.USER_ADDRESS_COUNTS_LIMIT,
'addresses': serializer.data,
})
# 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 = AddressTitleSerializer(instance=address, data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)
- 实现序列化器
from .models import User, Address
class UserAddressSerialize(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):
user = self.context['request'].user
validated_data['user'] = user
address = Address.objects.create(**validated_data)
return address
class AddressTitleSerializer(serializers.ModelSerializer):
class Meta:
model = Address
fields = ['title']
- 添加路由
from rest_framework import routers
# 添加路由使用视图内部方法之间向路由urlpatterns中自动添加路由
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