做一個Django項目(2.3、視圖集實現個人地址的增刪改查)

  1. 創建個人收貨地址模型類以及用戶模型添加默認地址
    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']

     

  2. 創建視圖重寫視圖函數邏輯實現額外功能並添加額外視圖函數
    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)

     

  3. 實現序列化器
    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']
    

     

  4. 添加路由
    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

     

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章