3.商品列表页
1. django的view实现商品列表页
urls.py
1 from django.conf.urls import url, include 2 from django.contrib import admin 3 4 urlpatterns = [ 5 url(r'^goods/', include('goods.urls'), name='goods'), 6 url(r'^admin/', admin.site.urls), 7 ]
goods/urls.py
1 from django.conf.urls import url 2 from goods.views_base import GoodListView 3 4 urlpatterns = [ 5 url(r'^list/$', GoodListView.as_view(), name='goods_list') 6 ]
goods/views.py
1 import json 2 from django.views.generic.base import View 3 from django.http import HttpResponse 4 from goods.models import Goods 5 6 class GoodListView(View): 7 def get(self, request): 8 goods = Goods.objects.all()[:10] 9 json_list = [] 10 for good in goods: 11 json_dic = {} 12 json_dic['name'] = good.name 13 json_dic['market_price'] = good.market_price 14 json_list.append(json_dic) 15 return HttpResponse(json.dumps(json_list), content_type='application/json')
chome jsonview安装 浏览器结构化显示json格式数据
https://www.cnblogs.com/whycxb/p/7126116.html
2.django的serializer序列化model
之前没发现这个用法,以前都是直接遍历,重新赋值,做了一堆无用功。
1 import json 2 from django.views.generic.base import View 3 from django.http import JsonResponse 4 from django.core import serializers 5 from goods.models import Goods 6 7 class GoodListView(View): 8 def get(self, request): 9 goods = Goods.objects.all()[:10] 10 11 # json.dumps: dict转成str 12 # json.loads: str转成dict 13 json_list = json.loads(serializers.serialize('json', goods)) 14 return JsonResponse(json_list, safe=False)
3.apiview方式实现商品列表页
安装DRF(参考:http://www.django-rest-framework.org/)
1 pip install djangorestframework 2 pip install markdown # Markdown support for the browsable API. 3 pip install django-filter # Filtering support 4 pip install django-guardian 5 pip install coreapi
配置urls.py与goods/urls.py
1 from django.conf.urls import url, include 2 from django.contrib import admin 3 from rest_framework.documentation import include_docs_urls 4 5 urlpatterns = [ 6 url(r'^goods/', include('goods.urls'), name='goods'), 7 url(r'^admin/', admin.site.urls), 8 url(r'docs/', include_docs_urls(title='接口说明')) 9 ]
1 from django.conf.urls import url 2 from goods.views_base import GoodListView 3 from goods.views import GoodsList as GoodsListDRF 4 5 urlpatterns = [ 6 url(r'^list/$', GoodListView.as_view(), name='goods_list'), 7 url(r'^list_drf/$', GoodsListDRF.as_view(), name='goods_list_drf'), 8 ]
编写:views.py 和 goods/serializers.py
1 from rest_framework.views import APIView 2 from rest_framework.response import Response 3 4 from .models import Goods 5 from .serializers import GoodsSerializer 6 7 class GoodsList(APIView): 8 """ 9 接口描述 10 List all goods. 11 """ 12 def get(self, request, format=None): 13 goods = Goods.objects.all() 14 serializer = GoodsSerializer(goods, many=True) 15 return Response(serializer.data)
1 from rest_framework import serializers 2 from .models import Goods 3 4 class GoodsSerializer(serializers.Serializer): 5 id = serializers.IntegerField() 6 name = serializers.CharField(max_length=100, required=True) 7 goods_front_image = serializers.ImageField()
创建数据接口(直接参考官方文档,这里并没有测试它,所以就不列出例子了)、ModelSerializers使用
1 from rest_framework import serializers 2 from .models import Goods, GoodsCategory 3 4 class GoodsCategorySerializer(serializers.ModelSerializer): 5 class Meta: 6 model = GoodsCategory 7 fields = "__all__" 8 9 class GoodsSerializer(serializers.ModelSerializer): 10 # 覆盖原有字段内容 11 category = GoodsCategorySerializer() 12 class Meta: 13 model = Goods 14 # 定义显示那些字段 15 # fields = ('id', 'title', 'code', 'linenos', 'language', 'style') 16 # 显示所有字段 17 fields = "__all__"
GenericAPIView 的使用(views.py)
1 from rest_framework import mixins 2 from rest_framework import generics 3 4 from .models import Goods 5 from .serializers import GoodsSerializer 6 7 class GoodsList(mixins.ListModelMixin, generics.GenericAPIView): 8 """ 9 商品列表页 10 """ 11 queryset = Goods.objects.all() 12 serializer_class = GoodsSerializer 13 14 def get(self, request, *args, **kwargs): 15 return self.list(request, *args, **kwargs)
ListAPIView的使用(views.py):
1 from rest_framework.generics import ListAPIView 2 3 from .models import Goods 4 from .serializers import GoodsSerializer 5 6 class GoodsList(ListAPIView): 7 """ 8 商品列表页(ListAPIView) 9 """ 10 queryset = Goods.objects.all() 11 serializer_class = GoodsSerializer
添加分页功能(settings.py)设置:
1 REST_FRAMEWORK = { 2 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', 3 'PAGE_SIZE': 2 4 }
深度分页功能:
1 from rest_framework.generics import ListAPIView 2 from rest_framework.pagination import PageNumberPagination 3 4 from .models import Goods 5 from .serializers import GoodsSerializer 6 7 class GoodsPagination(PageNumberPagination): 8 page_size = 10 9 page_size_query_param = 'page_size' 10 max_page_size = 10000 11 12 class GoodsList(ListAPIView): 13 """ 14 商品列表页(ListAPIView) 15 """ 16 queryset = Goods.objects.all() 17 serializer_class = GoodsSerializer 18 pagination_class = GoodsPagination
使用viewsets重构代码:
1 from rest_framework.pagination import PageNumberPagination 2 from rest_framework import viewsets, mixins 3 4 from .models import Goods 5 from .serializers import GoodsSerializer 6 7 class GoodsPagination(PageNumberPagination): 8 page_size = 10 9 page_size_query_param = 'page_size' 10 page_query_param = "p" 11 max_page_size = 10000 12 13 class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): 14 """ 15 商品列表页(ListAPIView) 16 """ 17 queryset = Goods.objects.all() 18 serializer_class = GoodsSerializer 19 pagination_class = GoodsPagination
显示绑定URL和viewsets:
1 from django.conf.urls import url 2 from goods.views_base import GoodListView 3 from goods.views import GoodsListViewSet 4 5 goods_list = GoodsListViewSet.as_view({ 6 'get': 'list', 7 }) 8 9 urlpatterns = [ 10 url(r'^list/$', GoodListView.as_view(), name='goods_list'), 11 url(r'^list_drf/$', goods_list, name='goods_list_drf'), 12 ]
使用routers:
1 from django.conf.urls import url, include 2 from django.contrib import admin 3 from rest_framework.documentation import include_docs_urls 4 from rest_framework.routers import DefaultRouter 5 6 from goods.views import GoodsListViewSet 7 8 router = DefaultRouter() 9 router.register(r"goods", GoodsListViewSet) 10 11 urlpatterns = [ 12 # url(r'^goods/', include('goods.urls'), name='goods'), 13 url('^', include(router.urls)), 14 url(r'^admin/', admin.site.urls), 15 url(r'^api-auth/', include('rest_framework.urls')), 16 url(r'docs/', include_docs_urls(title='接口说明')) 17 ]
4.drf的Apiview、GenericView、Viewset和router的原理分析
结构:
1 GenericViewSet() --drf 2 GenericAPIView --drf 3 APIView --drf 4 View --django 5 6 mixins 7 CreateModelMixin 8 ListModelMixin 9 RetrieveModelMixin 10 UpdateModelMixin 11 DestroyModelMixin
为什么router直接能映射到相应的view中并返回数据?
routers/SimpleRouter
1 class SimpleRouter(BaseRouter): 2 3 routes = [ 4 # List route. 5 Route( 6 url=r'^{prefix}{trailing_slash}$', 7 mapping={ 8 'get': 'list', 9 'post': 'create' 10 }, 11 ......
minixs/ListModelMixin:
1 class ListModelMixin(object): 2 """ 3 List a queryset. 4 """ 5 def list(self, request, *args, **kwargs): 6 queryset = self.filter_queryset(self.get_queryset()) 7 8 page = self.paginate_queryset(queryset) 9 if page is not None: 10 serializer = self.get_serializer(page, many=True) 11 return self.get_paginated_response(serializer.data) 12 13 serializer = self.get_serializer(queryset, many=True) 14 return Response(serializer.data)
viewset/ViewsetMixin:
class ViewSetMixin(object): """ This is the magic. Overrides `.as_view()` so that it takes an `actions` keyword that performs the binding of HTTP methods to actions on the Resource. For example, to create a concrete view binding the 'GET' and 'POST' methods to the 'list' and 'create' actions... view = MyViewSet.as_view({'get': 'list', 'post': 'create'}) """ @classonlymethod def as_view(cls, actions=None, **initkwargs): ......
5.drf的request和response
可参考官方文档:
http://www.django-rest-framework.org/api-guide/requests/
http://www.django-rest-framework.org/api-guide/responses/
中文版:
https://darkcooking.gitbooks.io/django-rest-framework-cn/content/chapter2.html
http://www.chenxm.cc/post/290.html
6.drf的过滤功能
(1)自己写的过滤器
1 class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): 2 """ 3 商品列表页(ListAPIView) 4 """ 5 queryset = Goods.objects.all() 6 serializer_class = GoodsSerializer 7 pagination_class = GoodsPagination 8 9 def get_queryset(self): 10 queryset = Goods.objects.all() 11 price_min = self.request.query_params.get('price_min', 0) 12 if price_min: 13 queryset = queryset.filter(shop_price__gt = int(price_min)) 14 15 return queryset
(2)django-filter普通应用
1 # 安装django-filter 2 pip install django-filter 3 # 添加进INSTALLED_APPS 4 INSTALLED_APPS = [ 5 ... 6 'django_filters', 7 ] 8 # views.py中应用 9 ... 10 from django_filters.rest_framework import DjangoFilterBackend 11 ... 12 class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): 13 ... 14 filter_backends = (DjangoFilterBackend,) 15 filter_fields = ('name', 'shop_price')
(3)django-filter区间搜索
filters.py
1 import django_filters 2 from .models import Goods 3 4 class GoodsFilter(django_filters.FilterSet): 5 ''' 6 商品过滤类 7 ''' 8 price_min = django_filters.NumberFilter(name='shop_price', lookup_expr='gte') 9 price_max = django_filters.NumberFilter(name='shop_price', lookup_expr='lte') 10 # 模糊查询 11 name = django_filters.CharFilter(name='name', lookup_expr="icontains") 12 13 class Meta: 14 model = Goods 15 fields = ['price_min', 'price_max', 'name']
views.py
1 from rest_framework.pagination import PageNumberPagination 2 from rest_framework import viewsets, mixins 3 from django_filters.rest_framework import DjangoFilterBackend 4 5 from .models import Goods 6 from .serializers import GoodsSerializer 7 from .filters import GoodsFilter 8 9 class GoodsPagination(PageNumberPagination): 10 page_size = 10 11 page_size_query_param = 'page_size' 12 page_query_param = "p" 13 max_page_size = 10000 14 15 class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): 16 """ 17 商品列表页(ListAPIView) 18 """ 19 queryset = Goods.objects.all() 20 serializer_class = GoodsSerializer 21 pagination_class = GoodsPagination 22 filter_backends = (DjangoFilterBackend,) 23 filter_class = GoodsFilter
对应的官方文档:https://django-filter.readthedocs.io/en/master/guide/rest_framework.html
7.drf的搜索和排序
1 from rest_framework.pagination import PageNumberPagination 2 from rest_framework import viewsets, mixins, filters 3 from django_filters.rest_framework import DjangoFilterBackend 4 5 from .models import Goods 6 from .serializers import GoodsSerializer 7 from .filters import GoodsFilter 8 9 class GoodsPagination(PageNumberPagination): 10 page_size = 10 11 page_size_query_param = 'page_size' 12 page_query_param = "p" 13 max_page_size = 10000 14 15 class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): 16 """ 17 商品列表页(ListAPIView) 18 """ 19 queryset = Goods.objects.all() 20 serializer_class = GoodsSerializer 21 pagination_class = GoodsPagination 22 filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter) 23 filter_class = GoodsFilter 24 25 search_fields = ('name', '^goods_desc') 26 ordering_fields = ('sold_num', 'add_time')

浙公网安备 33010602011771号