Open mahsiaoko opened 5 years ago
django:Form<-->ModelForm drf:serializer<-->ModelSerializer ModelSerializer实现商品列表页
在views.py中:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Goods
class GoodsListView(APIView):
"""
List all goods
"""
def get(self, request, format=None):
goods = Goods.objects.all()[:10]
# 此处many=True表示可能是一个列表,是一个querySetDict,如果是单个good的话,不用写
# many=True,会序列化为一个数组对象
goods_serializer = GoodsSerializer(goods, many=True)
return Response(goods_serializer.data)
# 接收前端传递来的数据,保存到数据库中
def post(self, request, format=None):
# drf会把数据取出来放到data中
serializer = GoodsSerializer(data=request.data)
if serializer.is_valid():
# serializer.save()会调用GoodsSerializer中的create方法
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
在serializers.py中,针对Goods,有如下操作:
from rest_framework import serializers
from .models import Goods
# 新建一个model来映射字段
class GoodsSerializer(serializers.Serializer):
name = serializers.CharField(required=True, max_length=100)
click_num = serializers.IntegerField(default=0)
goods_front_image = serializers.ImageField()
# 往数据库中保存
# validated_data保存有上面定义的字段
def create(self, validated_data):
"""
Create and return a new `Good` instance, given the validated data.
"""
return Goods.objects.create(**validated_data)
在serializers.py中,针对Goods,有如下操作:
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = GoodsCategory
fields = "__all__"
class GoodsSerializer(serializers.ModelSerializer):
# category是外键,如果想获得详细信息,需要以下方式
# 覆盖默认的category,实例化CategorySerializer,
# category = CategorySerializer()
class Meta:
model = Goods
# fields = ("name", "click_num","goods_sn", "sold_num", "fav_num", "goods_num", "market_price",
# "shop_price", "goods_brief", "goods_desc", "is_new", "is_hot", "add_time")
# 直接取出所有字段使用 __all__
fields = "__all__"
使用ModelSerializer可以省略字段的定义,直接实现model的序列化,此处外键会直接显示为id,想显示外键内容,可以按照上面的所示。 在views.py中直接使用之前的,无需改变。
from rest_framework.response import Response
from rest_framework import mixins
from rest_framework import generics
from .serializers import GoodsSerializer
class GoodsListView(mixins.ListModelMixin,mixins.CreateModelMixin, generics.GenericAPIView):
"""
使用mixins.ListModelMixin实现商品列表页;
使用generics.GenericAPIView继承了APIView
"""
queryset = Goods.objects.all()[:10]
serializer_class = GoodsSerializer
# 重写get函数,不写的话get方法就默认不允许
# self.list的list在mixins.ListModelMixin中
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
# 重写post方法,默认不允许
# post的话,使用的是mixins.CreateModelMixin
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
上面的代码可以进一步的简化,在generics中,有一个ListAPIView,其详细代码为:
class ListAPIView(mixins.ListModelMixin,
GenericAPIView):
"""
Concrete view for listing a queryset.
"""
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
可以看出, ListAPIView继承了mixins.ListModelMixin和GenericAPIView,而且覆写了get,所以可以直接在代码中继承ListAPIView,如下:
class GoodsListView(generics.ListAPIView):
"""
使用mixins.ListModelMixin实现商品列表页;
使用generics.GenericAPIView继承了APIView
"""
queryset = Goods.objects.all()
serializer_class = GoodsSerializer
分页,针对特定的app来定制分页功能
from rest_framework.pagination import PageNumberPagination
class GoodsPagination(PageNumberPagination):
page_size = 20
page_size_query_param = 'page_size'
page_query_param = 'p'
max_page_size = 100
class GoodsListView(generics.ListAPIView):
"""
使用mixins.ListModelMixin实现商品列表页;
使用generics.GenericAPIView继承了APIView
"""
queryset = Goods.objects.all()
serializer_class = GoodsSerializer
pagination_class = GoodsPagination
使用django的View
json.dumps()将字典形式的数据转为字符串。 很方便的实现了列表返回,但是存在这样的问题,
django本身的model_to_dict:
报错:Object of type ImageFieldFile is not JSON serializable
django的serializer序列化model
此时序列化不会出现问题,当然返回的Response还可以表述为:
json.loads()用于将字符串形式的数据转化为字典 虽然django本身就可以实现序列化,但是功能单一,很多无法实现。