zoukankan      html  css  js  c++  java
  • 【Vue+DRF 生鲜电商】商品列表页(三)

    1. APIView 实现商品列表页

    安装依赖:

    pip install coreapi    # drf的文档支持
    pip install django-guardian   #  drf对象级别的权限支持
    

    1、MxShop/urls.py

    from django.urls import path, include, re_path
    from django.views.static import serve
    from rest_framework.documentation import include_docs_urls
    
    urlpatterns = [
        # path('admin/', admin.site.urls),
    
        path('xadmin/', xadmin.site.urls),
        path('ueditor/', include('DjangoUeditor.urls')),
        path('media/<path:path>', serve, {'document_root': MEDIA_ROOT}),
    
        # drf 文档
        path('docs', include_docs_urls(title='hubery')),
        path('api-auth/', include('rest_framework.urls')),
    ]
    

    2、新建 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()
    
    # 也可以使用
    # class CategorySerializer(serializers.ModelSerializer):
    #     """
    #     分类
    #     """
    
    #     class Meta:
    #         model = GoodsCategory     # 指定模型
    #         fields = '__all__'    # 所以字段
    

    serializers.ModelSerializer 类似于 Django ModelForm 可以指定模型。

    2、goods/views.py

    from rest_framework.response import Response
    from rest_framework.views import APIView
    
    
    class GoodsListView(APIView):
        """
        商品列表
        """
    
        def get(self, request, format=None):
            goods = Goods.objects.all()
            goods_serilizer = GoodsSerializer(goods, many=True)
            return Response(goods_serilizer.data)
    

    APIView 需要自己实现 get、post 方法来处理请求。

    3、MxShop/urls.py 配置商品列表路由:

    from django.urls import path, include, re_path
    from django.views.static import serve
    
    from goods.views import GoodsListView
    
    urlpatterns = [
    
        path('goods/', GoodsListView.as_view(), name='goods'),
    ]
    

    运行项目,访问:http://127.0.0.1:8000/goods 查看商品列表页数据。

    1.1 处理外键字段

    通过上述方式处理,查询到的商品数据,分类 category 外键字段的数据是商品类别表的字段 ID,若想能够全部显示相关分类的所有信息,需要重写方法,覆盖对应的外键字段:

    1、goods/serializers.py

    from rest_framework import serializers
    from goods.models import Goods, GoodsCategory
    
    
    class CategorySerializer(serializers.ModelSerializer):
        """
        分类
        """
    
        class Meta:
            model = GoodsCategory
            fields = '__all__'
    
    
    class GoodsSerializer(serializers.ModelSerializer):
        """
        商品
        """
        # 覆盖外键字段 category
        category = CategorySerializer()
        class Meta:
            model = Goods
            fields = '__all__'
    

    2. GenericView 实现商品列表页

    GenericView 继承 APIView,比 APIView 功能更强大, 使用的时候需要指定:queryset、serializer_class

    ListModelMixinlist 方法实现了分页和序列化,视图继承它可以省略自己实现分页和序列化。

    ListModelMixin 源码:

    class ListModelMixin:
        """
        List a queryset.    # 列出查询集
        """
        def list(self, request, *args, **kwargs):
            queryset = self.filter_queryset(self.get_queryset())
    
            page = self.paginate_queryset(queryset)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)
    
            serializer = self.get_serializer(queryset, many=True)
            return Response(serializer.data)
    

    goods/views.py

    from rest_framework import mixins, viewsets
    from rest_framework import generics
    
    from goods.serializers import GoodsSerializer
    from .models import Goods
    
    class GoodsListView(mixins.ListModelMixin, generics.GenericAPIView):
        """
        商品列表
        """
        queryset = Goods.objects.all()
        serializer_class = GoodsSerializer
    

    3. 分页

    3.1 全局分页

    配置全局分页只需配置 MxShop/Settings.py 即可:

    REST_FRAMEWORK = {
        #分页
        'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
        #每页显示的个数
        'PAGE_SIZE': 10,
    }
    

    3.2 自定义分页

    自定义分页需要重写分页类,继承 PageNumberPagination,可以自定义:

    • 每页条数
    • 最大页数
    • 获取页码的参数等

    goods/views.py

    from rest_framework.pagination import PageNumberPagination
    from rest_framework import mixins, viewsets
    from rest_framework import generics
    from django_filters.rest_framework import DjangoFilterBackend
    from rest_framework import filters
    
    from goods.filters import GoodsFilter
    from goods.serializers import GoodsSerializer
    from .models import Goods
    
    class GoodsPagination(PageNumberPagination):
        """
        自定义商品列表分页
        """
        page_size = 10  # 每页显示个数
        page_size_query_param = 'page_size'  # 可以动态改变每页显示的个数
        page_query_param = 'page'  # 页码参数
        max_page_size = 100  # 最多能显示多少页
    
    class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
        """
        商品列表页
        """
        # 分页
        pagination_class = GoodsPagination
        # 这里必须要定义一个默认的排序,否则会报错
        queryset = Goods.objects.all().order_by('id')
        serializer_class = GoodsSerializer
    

    使用:http://127.0.0.1:8000/goods/?page=2&page_size=20

    注意:将全局分页功能注释

    4. viewsets 和 router 配置商品列表路由

    1、MxShop/urls.py

    from django.urls import path, include, re_path
    from django.views.static import serve
    from rest_framework.documentation import include_docs_urls
    from rest_framework.routers import DefaultRouter
    
    import xadmin
    from MxShop.settings import MEDIA_ROOT
    from goods.views import GoodsListViewSet
    
    router = DefaultRouter()
    
    router.register(r'goods', GoodsListViewSet, basename='goods')
    
    urlpatterns = [
        # path('admin/', admin.site.urls),
    
        path('xadmin/', xadmin.site.urls),
        path('ueditor/', include('DjangoUeditor.urls')),
        path('media/<path:path>', serve, {'document_root': MEDIA_ROOT}),
    
        # drf 文档
        path('docs', include_docs_urls(title='hubery')),
        path('api-auth/', include('rest_framework.urls')),
    
        # 商品
        # path('goods/', GoodsListView.as_view(), name='goods-list'),
    
        re_path('^', include(router.urls)),
    ]
    

    2、goods/views.py

    queryset 要定义一个默认的排序,否则会报错:

    from rest_framework.pagination import PageNumberPagination
    from rest_framework import mixins, viewsets
    from rest_framework import generics
    from django_filters.rest_framework import DjangoFilterBackend
    from rest_framework import filters
    
    from goods.filters import GoodsFilter
    from goods.serializers import GoodsSerializer
    from .models import Goods
    
    class GoodsPagination(PageNumberPagination):
        """
        自定义商品列表分页
        """
        page_size = 10  # 每页显示个数
        page_size_query_param = 'page_size'  # 可以动态改变每页显示的个数
        page_query_param = 'page'  # 页码参数
        max_page_size = 100  # 最多能显示多少页
    
    class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
        """
        商品列表页
        """
        # 分页
        pagination_class = GoodsPagination
        # 这里必须要定义一个默认的排序,否则会报错
        queryset = Goods.objects.all().order_by('id')
        serializer_class = GoodsSerializer
    

    5. 商品过滤和搜索

    5.1 过滤

    drffilter 用法:http://www.django-rest-framework.org/api-guide/filtering/

    1、MxShop/settings.py

    INSTALLED_APPS = [
        'django_filters',
    ]
    

    2、新建 goods/filters.py 用于过滤:

    import django_filters
    
    from .models import Goods
    
    
    class GoodsFilter(django_filters.rest_framework.FilterSet):
        """
        商品过滤
        """
        # field_name 为要过滤的字段,lte 为执行的行为,这里为小于等于本店价格
        price_min = django_filters.NumberFilter(field_name='shop_price', lookup_expr='gte')
        price_max = django_filters.NumberFilter(field_name='shop_price', lookup_expr='lte')
    
        class Meta:
            model = Goods
            fields = ['price_min', 'price_max']
    

    在这里对商品进行过滤,查找 [price_min, price_max] 范围的商品。

    3、goods/views.py

    from django_filters.rest_framework import DjangoFilterBackend
    
    class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
        """
        商品列表页
        """
        # 分页
        pagination_class = GoodsPagination
        # 这里必须要定义一个默认的排序,否则会报错
        queryset = Goods.objects.all().order_by('id')
        serializer_class = GoodsSerializer
    
        # 过滤
        filter_backends = (DjangoFilterBackend, )
    
        # 设置 filter 的类为自定义的类
        filter_class = GoodsFilter
    

    使用:http://127.0.0.1:8000/goods/?price_min=20&price_max=30

    5.2 搜索

    goods/views.py

    from django_filters.rest_framework import DjangoFilterBackend
    
    class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
        """
        商品列表页
        """
        # 分页
        pagination_class = GoodsPagination
        # 这里必须要定义一个默认的排序,否则会报错
        queryset = Goods.objects.all().order_by('id')
        serializer_class = GoodsSerializer
    
        # 过滤
        filter_backends = (DjangoFilterBackend, filters.SearchFilter,)
    
        # 设置 filter 的类为自定义的类
        filter_class = GoodsFilter
    
        # 搜索,=name 为精确搜索,也可以使用正则
        search_fields = ('=name', 'goods_brief')
    

    使用:http://127.0.0.1:8000/goods/?search=水果

    5.3 排序

    goods/views.py

    from django_filters.rest_framework import DjangoFilterBackend
    
    class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
        """
        商品列表页
        """
        # 分页
        pagination_class = GoodsPagination
        # 这里必须要定义一个默认的排序,否则会报错
        queryset = Goods.objects.all().order_by('id')
        serializer_class = GoodsSerializer
    
        # 过滤
        filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    
        # 设置 filter 的类为自定义的类
        filter_class = GoodsFilter
    
        # 搜索,=name 为精确搜索,也可以使用正则
        search_fields = ('=name', 'goods_brief')
    
        # 排序
        ordering_fields = ('sold_num', 'add_time')
    

    使用:http://127.0.0.1:8000/goods/?ordering=sold_num&

  • 相关阅读:
    Balanced Binary Tree
    Convert Sorted List to Binary Search Tree
    Convert Sorted Array to Binary Search Tree
    Binary Tree Zigzag Level Order Traversal
    Validate Binary Search Tree
    Binary Tree Level Order Traversal II
    Binary Tree Level Order Traversal
    Maximum Depth of Binary Tree
    如何把U盘的两个盘或者多个盘合成一个
    bugku 想蹭网先解开密码
  • 原文地址:https://www.cnblogs.com/midworld/p/13629680.html
Copyright © 2011-2022 走看看