序列化03

小练习

  1. 新建一个django项目,定义一个Car类,有name字符串属性,color整型选择属性(0:银色,1:黑色,2:红色,3:灰色),price全精度小数类型,image图片文件类型,brand品牌字符串类型;

  2. 基于ModelSerializer类,完成Car资源的单查,群查,单增接口;

  3. 序列化:显示车名,车的颜色,车的价格,车的海报,车的品牌;

  4. 反序列化:必须提供车名,车的价格,车的品牌(车的匹配需要二次确认re_brand),车的颜色默认为银色(可以提供),车的海报不需要提供(默认为空);

# api>urls.py

urlpatterns = [
    # ModelSerializer 序列化
    url(r'^v3/cars/$',views.CarV3View.as_view()),
    url(r'^v3/cars/(?P<pk>\d+)/$',views.CarV3View.as_view()),
]

# views.py
class CarV3View(APIView):
    # 单查群查
    def get(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        if pk:
            # 单查
            car_obj = models.Car.objects.filter(pk=pk, is_delete=False).first()
            if not car_obj:
                return Response({'status': 1, 'msg': 'geterror'}, status=400)
            car_dict = serializers.CarModelSerializer(car_obj, many=False).data
            return Response({'status': 0, 'msg': 'ok', 'results': car_dict})
        else:
            # 群查
            car_query = models.Car.objects.filter(is_delete=False).all()
            car_dict = serializers.CarModelSerializer(car_query, many=True).data
            return Response({'status': 0, 'msg': 'ok', 'results': car_dict})

    def post(self, request, *args, **kwargs):
        car_obj = serializers.CarModelSerializer(data=request.data)
        if car_obj.is_valid():
            # 入库
            car_obj = car_obj.save()
            print(car_obj)
            return Response({'status': 0, 'msg': 'ok', 'results': serializers.CarModelSerializer(car_obj).data})
        else:
            return Response({'status': 1, 'msg': car_obj.errors})

# api>serializers.py        
class CarModelSerializer(serializers.ModelSerializer):
    re_brand = serializers.CharField(min_length=3,max_length=8,write_only=True)
    class Meta:
        model = models.Car
        fields = ('name','car_car','img','price','brand','re_brand')
        extra_kwargs = {
            'name':{
                'min_length':3,
                'max_length':8,
                'error_messages':{
                    'min_length':'太短',
                    'max_length':'太长'
                }
            },
            'car_car':{'read_only':True,'required':False},
            'img':{'read_only':True},
        }

    def validated_username(self,value):
        if 'SB' in value.lower():
            raise serializers.ValidationError('名字中不能含有SB')
        return value

    def validate(self, attrs):
        brand = attrs.get('brand')
        re_brand = attrs.pop('re_brand')
        if re_brand != brand:
            raise serializers.ValidationError({'re_brand':'两次输入不一致'})
        return attrs

# models.py
class Car(models.Model):
    COLOR_CHOICE = (
        (0, '银色'),
        (1, '黑色'),
        (2, '红色'),
        (3, '灰色')
    )
    name = models.CharField(max_length=64, verbose_name='名字', blank=True)
    color = models.IntegerField(choices=COLOR_CHOICE, default=0, verbose_name='颜色')
    price = models.DecimalField(max_digits=8, decimal_places=2, verbose_name='价格')
    image = models.ImageField(upload_to='car', default='car/default.png', verbose_name='图片')
    brand = models.CharField(max_length=64, verbose_name='厂商')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    is_delete = models.BooleanField(default=False, verbose_name='是否删除')

    class Meta:
        verbose_name_plural = '汽车表'

    def __str__(self):
        return self.name

    # 自定义序列化字段(插拔式,官方提倡使用)
    @property
    def car_car(self):
        return self.get_color_display()

    @property
    def img(self):
        from django.conf import settings
        return '%s%s%s' % (settings.BASE_URL, settings.MEDIA_URL, self.image)
    
# 
posted on 2019-12-29 22:00  jueyuanfengsheng  阅读(130)  评论(0编辑  收藏  举报