- 【Vue+DRF生鲜电商】26.使用Pycharm远程代码调试服
- 【Vue+DRF生鲜电商】28.支付宝支付接口类解读,支付逻辑编
- 【Vue+DRF生鲜电商】29.线上服务支付宝接口和Vue联调,
- 【Vue+DRF生鲜电商】27.支付宝公钥,私钥,沙箱环境配置
- 【Vue+DRF生鲜电商】33.数据缓存、接口访问限速功能
- 【Vue+DRF生鲜电商】32.商品操作后计数更改,热搜榜关键字
- 【Vue+DRF生鲜电商】30.首页轮播图、新品展示功能
- 【Vue+DRF生鲜电商】31.首页商品按分类显示推荐功能
- 【Vue+DRF生鲜电商】25.商品添加购物车接口功能,Vue和
- 【Vue+DRF生鲜电商】26.订单接口功能,Vue和订单接口联
一、商品列表页
为了更好的区分Django Restful Framework和Django中的View,我们先使用Django的View来实现商品列表页json数据返回
Django
#goods/base_view.py
import json
from django.http import HttpResponse
from django.views.generic.base import View
from .models import Goods
#CBV方式编码
class GoodsListView(View):
def get(self,request):
"""
通过Django的View实现商品列表页
:param request:
:return:
"""
goods=Goods.objects.all()[:10]
json_data=[]
for good in goods:
json_dict={}
# 取出商品的每个字段,键值存储
json_dict['name']=good.name
json_dict['category']=good.category.name
json_dict['market_price']=good.market_price
json_data.append(json_dict)
# 返回json数据,一定要指定类型content_type='application/json'
return HttpResponse(json.dumps(json_data),content_type='application/json')
from apps.goods.base_view import GoodsListView
urlpatterns = [
#基于Django实现的商品列表页
url(r'goods/$',GoodsListView.as_view(),name='goods-list')
]
访问http://127.0.0.1:8000/goods/ 可以获取商品列表信息的json数据
-
django的serializer序列化
当字段比较多时,一个字段一个字段的提取很麻烦,可以使用model_to_dict,将model字段整个转化为dict
import json
from django.http import HttpResponse
from django.views.generic.base import View
from .models import Goods
#CBV方式编码
class GoodsListView(View):
def get(self,request):
"""
通过Django的View实现商品列表页
:param request:
:return:
"""
goods=Goods.objects.all()[:10]
json_data=[]
# for good in goods:
# json_dict={}
# # 取出商品的每个字段,键值存储
# json_dict['name']=good.name
# json_dict['category']=good.category.name
# json_dict['market_price']=good.market_price
# json_data.append(json_dict)
from django.forms.models import model_to_dict
for good in goods:
json_dict = model_to_dict(good)
json_data.append(json_dict)
#Object of type ImageFieldFile is not JSON serializable
# 返回json数据,一定要指定类型content_type='application/json'
return HttpResponse(json.dumps(json_data),content_type='application/json')
但是这里有个问题json.dums和loads方法不能将datetime和ImageFieldFile字段序列化成json数据
image.png
如何才能将所有字段序列化呢?就要用到django的serializers
import json
from django.http import HttpResponse,JsonResponse
from django.views.generic.base import View
from .models import Goods
#CBV方式编码
class GoodsListView(View):
def get(self,request):
"""
通过Django的View实现商品列表页
:param request:
:return:
"""
goods=Goods.objects.all()[:10]
json_data=[]
# for good in goods:
# json_dict={}
# # 取出商品的每个字段,键值存储
# json_dict['name']=good.name
# json_dict['category']=good.category.name
# json_dict['market_price']=good.market_price
# json_data.append(json_dict)
# from django.forms.models import model_to_dict
# for good in goods:
# json_dict = model_to_dict(good)
# json_data.append(json_dict)
#
# # Object of type ImageFieldFile is not JSON serializable
# # 返回json数据,一定要指定类型content_type='application/json'
# return HttpResponse(json.dumps(json_data), content_type='application/json')
from django.core import serializers
# serialize序列化成json
json_data=serializers.serialize('json',goods)
json_data=json.loads(json_data)
# In order to allow non-dict objects to be serialized set the safe parameter to False.
#JsonResponse类中定义了json.dumps()和content_type='application/json')
return JsonResponse(json_data,safe=False)
DRF
#GoShop\settings.py
INSTALLED_APPS = [
'rest_framework',
]
#GoShop\urls.py
from rest_framework.documentation import include_docs_urls
urlpatterns = [
url(r'^docs/',include_docs_urls(title='Django REST API Docs')),
url(r'^api-auth/', include('rest_framework.urls')),
url(r'goods/$',GoodsListView.as_view(),name='goods')
]
goods/serializers.py
from rest_framework import serializers
class GoodsSerializer(serializers.Serializer):
#手动添加字段
name=serializers.CharField(required=True,max_length=100)
click_num=serializers.IntegerField(default=0)
goods_front_image = serializers.ImageField()
goods/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Goods
from .serializers import GoodsSerializer
class GoodsListView(APIView):
"""
商品列表API
"""
def get(self, request, format=None):
goods = Goods.objects.all()[:10]
goods_serializer = GoodsSerializer(goods, many=True)
return Response(goods_serializer.data)
image.png
DRF的serializers会自动帮我们添加media到URL路径中,GoodsListView是APIView的子类,会识别请求类型生成可浏览的API接口。
- serializers类似Django中的form处理HTML,而serializers用来处理Json,我们使用ModelSerializer来添加字段将会更方便,直接用"all"方法可以全部序列化。
from rest_framework import serializers
from .models import Goods,GoodsCategory
#ModelSerializer实现商品列表数据序列化
class GoodsSerializer(serializers.ModelSerializer):
class Meta:
model=Goods
fields='__all__'
image.png
category是一张外键表,DRF的serializers序列化只显示了分类id,serializers还可以嵌套使用,像Django中的form一样,覆盖外键字段。
from rest_framework import serializers
from .models import Goods,GoodsCategory
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model=GoodsCategory
fields='__all__'
#ModelSerializer实现商品列表数据序列化
class GoodsSerializer(serializers.ModelSerializer):
# 嵌套使用 覆盖外键字段
category=CategorySerializer()
class Meta:
model=Goods
fields='__all__'
image.png
使用mixins和GenericAPIView实现商品列表页
generics.GenericAPIView继承APIView,封装了很多方法,比APIView的功能更加强大又方便。generics和mixins一起使用只需要配置
#GenericAPIView源码
class GenericAPIView(views.APIView):
"""
Base class for all other generic views.
"""
# You'll need to either set these attributes,
# or override `get_queryset()`/`get_serializer_class()`.
# If you are overriding a view method, it is important that you call
# `get_queryset()` instead of accessing the `queryset` property directly,
# as `queryset` will get evaluated only once, and those results are cached
# for all subsequent requests.
queryset = None
serializer_class = None
mixins.ListModelMixin类里面list方法帮我们做好了分页和序列化的逻辑,我们只需要在get方法中调用就可以。
class GoodsListView(mixins.ListModelMixin,generics.GenericAPIView):
"""
商品列表API
"""
#GenericAPIView使用配置queryset和serializer_class
queryset = Goods.objects.all()[:10]
serializer_class = GoodsSerializer
#重载get方法,调用ListModelMixin下的list方法做序列化、分页
def get(self,request,*args,**kwargs):
return self.list(request,*args,**kwargs)
上面的代码优化,mixins和generics还可以组合使用,可以直接继承ListAPIView,ListAPIView主要做了两件事:
- ListAPIView(mixins.ListModelMixin,GenericAPIView) 继承了这两个类
- 重载get方法
class GoodsListView(generics.ListAPIView):
"""
商品列表API
"""
queryset = Goods.objects.all()
serializer_class = GoodsSerializer
网友评论