04-商品列表页

一、前后端分离优缺点

优点:

  1、由于pc、app、pad多端适应  2SPA开发模式开始流行 3、前后端开发职责不清 4、开发效率问题,前后端相互等待 5、前端一直配合后端,能力有限 6、后台开发语言和模板高度耦合

缺点:

  1、前后端学习门槛增加 2、数据依赖,导致文档的重要性增加 3、前端工作量增加 4SEO的难度加大(搜索引擎优化) 5、后端模式迁移成本增加

restful api

  restful api是前后端分离目前来说是最佳实践,开发的标准规范,不是框架,是一种标准规范。优点就是轻量,直接通过http,不需要额外的协议,post/get/put/delete/patch/操作,同时还是面向资源,一目了然,具有解释性。第三就是数据描述简单,一般通过json或者xml做数据通信。每一个URI代表一种资源,客户端和服务器之间,传递这种资源的某种表现层,客户端通过五个HTTP动词,对服务器资源进行操作,实现表现层状态转化。

1、Django的View实现商品列表页

  为了更好的理解restful apiDjango原来的工作流程,我们在应用中新建一个views_base视图,然后写我们的逻辑。

Mxshop/urls.py

"""MxShop URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path(‘‘, views.home, name=‘home‘)
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path(‘‘, Home.as_view(), name=‘home‘)
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path(‘blog/‘, include(‘blog.urls‘))
"""
# from django.contrib import admin
from django.urls import path,re_path
#将设置里的media路径导入进来进行配置,还有用到静态文件的serve方法
from MxShop.settings import MEDIA_ROOT
from django.views.static import serve
import xadmin

from goods.views_base import GoodsListView

urlpatterns = [
    path(‘xadmin/‘, xadmin.site.urls),
    #用正则匹配media路径下的文件进行访问
    re_path(‘media/(?P<path>.*)$‘,serve,{"document_root":MEDIA_ROOT}),
    path(‘goods/‘,GoodsListView.as_view(),name="goods_list")
]

goods/views_base.py:

__author__ = "lishuntao"
__date__ = "2019/11/15 0015 12:26"

import json
from django.views.generic.base import View #CBV模式最常用也是最底层的View
# from django.views.generic import ListView  #和上面一样
from django.http import HttpResponse

from goods.models import Goods

class GoodsListView(View):
    def get(self,request):
        """
        通过Django的View实现商品列表页
        :param request:
        :return:返回一个json格式的数据
        """
        json_list = []
        goods = Goods.objects.all()[:10]
        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_list.append(json_dict)
        return HttpResponse(json.dumps(json_list),content_type="application/json")

然后启动项目,去浏览器中访问

  数据自动转换为开发者模式,这样是不是方便多了啊。但这样编写视图,每次查询列表页,每次都要将模型类的字段赋值,这样是不是很不方便,甚至多了繁杂还容易出错,那有没有什么办法,我们开发者不用写这些繁琐的简单代码,让一种工具自动帮我们转换为dict格式,django.forms.models import model_to_dict就可以帮我们完成这个繁琐工作。

改动后的代码

import json
from django.views.generic.base import View #CBV模式最常用也是最底层的View
# from django.views.generic import ListView  #和上面一样
from django.http import HttpResponse

from goods.models import Goods

class GoodsListView(View):
    def get(self,request):
        """
        通过Django的View实现商品列表页
        :param request:
        :return:返回一个json格式的数据
        """
        json_list = []
        goods = Goods.objects.all()[:10]
        # 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_list.append(json_dict)
        #这下面的Django提供的方法model_to_dict 就是将模型类的字段,转换为dict形式
        from django.forms.models import model_to_dict
        for good in goods:
            json_dict = model_to_dict(good)
            json_list.append(json_dict)
        return HttpResponse(json.dumps(json_list),content_type="application/json")

启动项目,访问发现图片不能被序列化,除此之外,时间类型字段也不能被序列化。

有一个django提供的可以将这些不能被序列化的字段序列化,django.core import serializers:

__author__ = "lishuntao"
__date__ = "2019/11/15 0015 12:26"

import json
from django.views.generic.base import View #CBV模式最常用也是最底层的View
# from django.views.generic import ListView  #和上面一样
from django.http import HttpResponse

from goods.models import Goods

class GoodsListView(View):
    def get(self,request):
        """
        通过Django的View实现商品列表页
        :param request:
        :return:返回一个json格式的数据
        """
        json_list = []
        goods = Goods.objects.all()[:10]
        # 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_list.append(json_dict)
        #这下面的Django提供的方法model_to_dict 就是将模型类的字段,转换为dict形式
        from django.forms.models import model_to_dict
        for good in goods:
            json_dict = model_to_dict(good)
            json_list.append(json_dict)
        from django.core import serializers
        json_data = serializers.serialize("json",goods)
        json_data = json.loads(json_data)

        return HttpResponse(json_data,content_type="application/json")

可以发现,启动说的是在第一行解析错误,这是因为上面发送回客户端的数据必须,一定是json.dumps的数据,否则的话,就会解析错误。

__author__ = "lishuntao"
__date__ = "2019/11/15 0015 12:26"

import json
from django.views.generic.base import View #CBV模式最常用也是最底层的View
# from django.views.generic import ListView  #和上面一样
from django.http import HttpResponse

from goods.models import Goods

class GoodsListView(View):
    def get(self,request):
        """
        通过Django的View实现商品列表页
        :param request:
        :return:返回一个json格式的数据
        """
        json_list = []
        goods = Goods.objects.all()[:10]
        # 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_list.append(json_dict)
        #这下面的Django提供的方法model_to_dict 就是将模型类的字段,转换为dict形式
        from django.forms.models import model_to_dict
        for good in goods:
            json_dict = model_to_dict(good)
            json_list.append(json_dict)
        from django.core import serializers
        json_data = serializers.serialize("json",goods)
        json_data = json.loads(json_data)#序列化的数据一定是先反序列化后,发送回客户端在序列化发送

        return HttpResponse(json.dumps(json_data),content_type="application/json")

当然,被json_data = serializers.serialize("json",goods)的返回值json_data数据直接就可以返回客户端,因为他已经自动帮我们把数据json.dumps啦,还有一种就是这里将不再演示。

刚才报错的图片和时间,都能够正常解析啦。(下面的是第二种django.http提供了json格式的返回,更加方便,只需要数据是一个字典格式即可)

2、APIView的方式实现商品列表页的功能(需要用到DRF所以去官方文档查看)

APIView使用前的配置,首先到项目路由urls.py下配置,否则以后引用APIView报错:

"""MxShop URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path(‘‘, views.home, name=‘home‘)
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path(‘‘, Home.as_view(), name=‘home‘)
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path(‘blog/‘, include(‘blog.urls‘))
"""
# from django.contrib import admin
import xadmin
from django.urls import path,re_path
#将设置里的media路径导入进来进行配置,还有用到静态文件的serve方法
from MxShop.settings import MEDIA_ROOT
from django.views.static import serve
from rest_framework.documentation import include_docs_urls

from goods.views_base import GoodsListView

urlpatterns = [
    path(‘xadmin/‘, xadmin.site.urls),
    #用正则匹配media路径下的文件进行访问
    re_path(‘media/(?P<path>.*)$‘,serve,{"document_root":MEDIA_ROOT}),
    path(‘goods/‘,GoodsListView.as_view(),name="goods_list"),
    path(‘docs/‘,include_docs_urls(title="天天生鲜")),
]

APIView使用前配置

根据官方文档,让配置INSTALLED_APPS中注册rest_framework

第二步官方文档要求注册这个路由,根据django版本配置urls.py

"""MxShop URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path(‘‘, views.home, name=‘home‘)
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path(‘‘, Home.as_view(), name=‘home‘)
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path(‘blog/‘, include(‘blog.urls‘))
"""
# from django.contrib import admin
import xadmin
from django.urls import path,re_path,include
#将设置里的media路径导入进来进行配置,还有用到静态文件的serve方法
from MxShop.settings import MEDIA_ROOT
from django.views.static import serve
from rest_framework.documentation import include_docs_urls

from goods.views_base import GoodsListView

urlpatterns = [
    path(‘xadmin/‘, xadmin.site.urls),
    path(‘api-auth/‘, include(‘rest_framework.urls‘)),
    #用正则匹配media路径下的文件进行访问
    re_path(‘media/(?P<path>.*)$‘,serve,{"document_root":MEDIA_ROOT}),
    path(‘goods/‘,GoodsListView.as_view(),name="goods_list"),
    path(‘docs/‘,include_docs_urls(title="天天生鲜")),
]

注册好路由之后,这样就可以使用DRF的功能啦,首先要实现的是商品列表页功能,在Goods下的views.py中实现代码

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response

from .models import Goods
from .serializers import GoodsSerializer

# Create your views here.

class GoodsList(APIView):
    """
    商品列表页
    """
    def get(self,request,format=None):
        goods = Goods.objects.all()[:10]
        #自定义的序列化器(goods.serializers中)
        goods_serializer = GoodsSerializer(goods,many=True)
        return Response(goods_serializer.data)

视图中的GoodsSerializer类是自定义的序列化器,继承了DRFserializers.Serializer。实现其中两个字段来理解他的功能,则serializers.py的代码为:

from rest_framework import serializers

class GoodsSerializer(serializers.Serializer):
    name = serializers.CharField(default="",max_length=20)
    click_num = serializers.IntegerField(default=0,)

配置路由(urls.py):

from goods.views import GoodsList

urlpatterns = [
    path(‘xadmin/‘, xadmin.site.urls),
    path(‘api-auth/‘, include(‘rest_framework.urls‘)),
    #用正则匹配media路径下的文件进行访问
    re_path(‘media/(?P<path>.*)$‘,serve,{"document_root":MEDIA_ROOT}),
    path(‘goods/‘,GoodsList.as_view(),name="goods_list"),
    path(‘docs/‘,include_docs_urls(title="天天生鲜")),
]

启动访问的结果:

继承Serializers.Serializer的类有create方法,重写这个方法,这是对模型类数据的创建:

    def create(self, validated_data):
        """
        创建一个Goods对象,
        :param validated_data:
        :return: 这个将数据保存到数据库
        """
        return Goods.objects.create(**validated_data)

然后到视图函数中保存:

    def post(self,request):
        """
        保存数据
        :param request:
        :return:
        """
        serializer = GoodsSerializer(data=request.data)
        if serializer.is_valid():
            #在GoodsSerializer中调用模型类的create方法,然后在这里逻辑保存
            serializer.save()
            return Response(serializer.data,status=status.HTTP_201_CREATED)
        return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)

  继承APIView的序列化器是不是和Django.forms很像,都是可以对数据进行验证,然后进行相关逻辑操作。forms.Model可以对数据模型类进行保存,序列化器也有modelserializer,将serializer的方法都实现了,这样用起来更简单,实现起来更方便。

ModelSerializer

一运行,浏览器访问,然后就能看见外键的详细数据,并且还能直接将原来复杂得直接简写,功能强大。

3、GenericView实现商品列表页和分页

第一去项目设置里面添加REST_FRAMEWORK设置:

REST_FRAMEWORK = {
    ‘PAGE_SIZE‘: 10,
}

自定义分类:

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework import mixins
from rest_framework import generics
from rest_framework.pagination import PageNumberPagination

from .models import Goods
from .serializers import GoodsSerializer

# Create your views here.

class GoodsSetPagination(PageNumberPagination):
    """
    定制分页设置
    """
    page_size = 1
    page_size_query_param = ‘page_size‘
    page_query_param = "p"
    max_page_size = 10000

#GenericAPIView,对APIView进行一层封装,APIView是对View进行一层封装
class GoodsList(generics.ListAPIView):
    """
    商品列表页,继承第一个是为了列表页,还要必须继承一个视图类
    ListAPIView已经将下面的代码完成
    """
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsSetPagination

 4、viewsets和router完成商品列表页(所有的API基本上都会用Viewset完成)

views.py:

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework import mixins
from rest_framework import generics
from rest_framework.pagination import PageNumberPagination
from rest_framework import viewsets

from .models import Goods
from .serializers import GoodsSerializer

# Create your views here.

class GoodsSetPagination(PageNumberPagination):
    """
    定制分页设置
    """
    page_size = 1
    page_size_query_param = ‘page_size‘
    page_query_param = "p"
    max_page_size = 10000

#GenericAPIView,对APIView进行一层封装,APIView是对View进行一层封装
class GoodsListViewSet(mixins.ListModelMixin,viewsets.GenericViewSet):
    """
    商品列表页
    """
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsSetPagination

urls.py:

"""MxShop URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path(‘‘, views.home, name=‘home‘)
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path(‘‘, Home.as_view(), name=‘home‘)
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path(‘blog/‘, include(‘blog.urls‘))
"""
# from django.contrib import admin
import xadmin
from django.urls import path,re_path,include
#将设置里的media路径导入进来进行配置,还有用到静态文件的serve方法
from MxShop.settings import MEDIA_ROOT
from django.views.static import serve
from rest_framework.documentation import include_docs_urls
from rest_framework.routers import DefaultRouter

from goods.views_base import GoodsListView
from goods.views import GoodsListViewSet

router = DefaultRouter()

#配置goods的url
router.register(r"goods",GoodsListViewSet)

# goods_list = GoodsListViewSet.as_view({
#     "get":"list",
#     #DRF提供了router来配置这个路由
# })

urlpatterns = [
    path(‘xadmin/‘, xadmin.site.urls),
    path(‘api-auth/‘, include(‘rest_framework.urls‘)),
    #用正则匹配media路径下的文件进行访问
    re_path(‘media/(?P<path>.*)$‘,serve,{"document_root":MEDIA_ROOT}),
    # path(‘goods/‘,goods_list,name="goods_list"),
    re_path(‘^‘,include(router.urls)),
    path(‘docs/‘,include_docs_urls(title="天天生鲜")),
]

urls.py

 5、DRF的过滤

在应用下新建自定义的过滤,可以实现模糊查询等。

import django_filters
from .models import Goods

class GoodsFilter(django_filters.rest_framework.FilterSet):
    """
    商品过滤器
    """
    price_min = django_filters.NumberFilter(field_name="shop_price",lookup_expr="gte")
    price_max = django_filters.NumberFilter(field_name="shop_price", lookup_expr="lte")
    name = django_filters.CharFilter(field_name="name", lookup_expr="icontains")

    class Meta:
        model = Goods
        fields = ["price_min","price_max","name"]

goods/filters.py

在设置里面添加django_filtersDjango中也可以自定义过滤

INSTALLED_APPS = [
    ‘django.contrib.auth‘,
    ‘django.contrib.admin‘,
    ‘django.contrib.contenttypes‘,
    ‘django.contrib.sessions‘,
    ‘django.contrib.messages‘,
    ‘django.contrib.staticfiles‘,
    ‘users.apps.UsersConfig‘,
    ‘goods.apps.GoodsConfig‘,
    ‘trade.apps.TradeConfig‘,
    ‘user_operation.apps.UserOperationConfig‘,
    ‘DjangoUeditor‘,
    ‘xadmin‘,
    ‘crispy_forms‘,#这个是xadmin需要使用的
    ‘rest_framework‘,
    ‘django_filters‘,
]

seetings.py

在视图中的代码逻辑为

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework import mixins
from rest_framework import generics
from rest_framework.pagination import PageNumberPagination
from rest_framework import viewsets
from django_filters.rest_framework import DjangoFilterBackend

from .models import Goods
from .serializers import GoodsSerializer
from .filters import GoodsFilter

# Create your views here.

class GoodsSetPagination(PageNumberPagination):
    """
    定制分页设置
    """
    page_size = 10
    page_size_query_param = ‘page_size‘
    page_query_param = "p"
    max_page_size = 10000

#GenericAPIView,对APIView进行一层封装,APIView是对View进行一层封装
class GoodsListViewSet(mixins.ListModelMixin,viewsets.GenericViewSet):
    """
    商品列表页
    """
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsSetPagination
    filter_backends = [DjangoFilterBackend]
    #这是精确搜索过滤,我们需要的是模糊搜索
    # filterset_fields = [‘name‘, ‘shop_price‘]
    filter_class = GoodsFilter

views.py

运行结果是:

 6、DRF的搜索和排序

views.py中的逻辑代码(搜索):

from rest_framework import filters

class GoodsSetPagination(PageNumberPagination):
    """
    定制分页设置
    """
    page_size = 10
    page_size_query_param = ‘page_size‘
    page_query_param = "p"
    max_page_size = 10000

#GenericAPIView,对APIView进行一层封装,APIView是对View进行一层封装
class GoodsListViewSet(mixins.ListModelMixin,viewsets.GenericViewSet):
    """
    商品列表页
    """
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsSetPagination
    filter_backends = [DjangoFilterBackend,filters.SearchFilter]
    #这是精确搜索过滤,我们需要的是模糊搜索
    # filterset_fields = [‘name‘, ‘shop_price‘]
    filter_class = GoodsFilter
    search_fields = ("name","goods_brief","goods_desc")

排序:

class GoodsSetPagination(PageNumberPagination):
    """
    定制分页设置
    """
    page_size = 10
    page_size_query_param = ‘page_size‘
    page_query_param = "p"
    max_page_size = 10000

#GenericAPIView,对APIView进行一层封装,APIView是对View进行一层封装
class GoodsListViewSet(mixins.ListModelMixin,viewsets.GenericViewSet):
    """
    商品列表页 分页 搜索 过滤 排序
    """
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsSetPagination
    filter_backends = [DjangoFilterBackend,filters.SearchFilter,filters.OrderingFilter]
    #这是精确搜索过滤,我们需要的是模糊搜索
    # filterset_fields = [‘name‘, ‘shop_price‘]
    filter_class = GoodsFilter
    search_fields = ("name","goods_brief","goods_desc")
    ordering_fields = ("shop_price","sold_num","add_time")

排序

  总结DRF:首先我们通过创建views_base.py里面用Django的View来实现商品列表页,刚开始是自己序列化,然后通过介绍Django提供的方法model_to_dict,最后到使用Django原生的serializers以及使用它的JsonResponse的序列化,通过这些繁琐的工作,引出了DRF功能,首先通过APIView来完成,然后通过generics中的genericAPIView来实现了商品列表页,一直到最后使用ViewSets的东西来完成我们的商品列表页

原文地址:https://www.cnblogs.com/lishuntao/p/11867127.html

时间: 2024-10-03 22:41:49

04-商品列表页的相关文章

ecshop实现商品列表页属性筛选区品牌筛选以LOGO形式展示

很多时候ecshop分类页的品牌都是以名称的形式显示的,下面ECSHOP开发中心的技术和大家说说ecshop 如何实现商品列表页属性筛选区品牌筛选以LOGO形式展示 1.修改 category.php 文件,将(大概220行) 找到 1 $sql = "SELECT b.brand_id, b.brand_name, COUNT(*) AS goods_num ". 替换成 1 $sql = "SELECT b.brand_id,b.brand_logo, b.brand_n

ecshop模板将商品列表页属性筛选区的品牌以LOGO形式显示

ecshop模板将商品列表页属性筛选区的品牌以LOGO形式显示 商品列表页属性筛选区品牌以LOGO形式显示1.修改 category.php 文件将(大概215行) $sql = "SELECT b.brand_id, b.brand_name, COUNT(*) AS goods_num ". 修改为 $sql = "SELECT b.brand_id,b.brand_logo, b.brand_name, COUNT(*) AS goods_num ". 把商品

让ECSHOP商品列表页和商品详细页分类树跟首页一样

如何让商品列表页或商品详情页的分类树都跟首页一样,也是显示全部所有的分类呢?修改方法:1.商品列表页修改方法:打开category.php 文件将$smarty->assign('categories',       get_categories_tree($cat_id));修改为$smarty->assign('categories',       get_categories_tree());2.商品详情页修改方法:将$smarty->assign('categories',   

(生鲜项目)07. api view实现商品列表页

第一步: 环境配置 1. DRF官网: https://www.django-rest-framework.org/ 仔细查看自己当前的python版本以及django版本是否支持DRF, 然后就看看哪些支持的模块还没有下载, 由于之前安装过xadmin了, 所以这里正常情况下还有coreapi, pygments, django-guardian没有安装, 在虚拟环境中去安装就行了 注: 如果在安装coreapi的时候报错, 并且提示utf-8 decode错误, 那么就去修改pip的编码格式

(生鲜项目)08. ModelSerializer 实现商品列表页, 使用Mixin来实现返回, 以及更加方便的ListAPIView, 以及分页的设置

第一步: 学会使用ModelSerializer, 并且会使用ModelSerializer相互嵌套功能 1. goods.serializers.py from rest_framework import serializers from goods.models import Goods, GoodsCategory # 让goods的category字段全量显示 class CategorySerializer(serializers.ModelSerializer): class Met

在ECSHOP商品列表页和搜索页面,最后出现空商品的解决办法

有客户购买了我们的ecshop模板后,自己做了大量的修改和改动,后来出现了商品列表页面和搜索页面出现了多一个商品的问题.没有商品数据,但是多显示了一个商品的样式.下面就由我们68ecshop为大家解决一下这个问题吧!解决的方法如下:<!– {if $goods.goods_id} –> <!– {/if} –>代码框起来即可解决.

【vue】饿了么项目-goods商品列表页开发

1.flex 属性是 flex-grow.flex-shrink 和 flex-basis 属性的简写属性. flex-grow 一个数字,规定项目将相对于其他灵活的项目进行扩展的量. flex-shrink 一个数字,规定项目将相对于其他灵活的项目进行收缩的量. flex-basis 项目的长度.合法值:"auto"."inherit" 或一个后跟 "%"."px"."em" 或任何其他长度单位的数字.

商品列表页一次添加多个规格

可能题目的表述不是特别清晰,具体有一下截图看这会比较明显 页面上的功能描述1. 当页面加载完成后,需要根据不同规格的商品刷新出对应规格商品的价格,2.重置默认数量,这个功能在input标签中设置默认的value值即可,或者添加一个js函数,重置对应class集合中的值,这个不多说,比较简单,3.点击添加购物车,需要把例如上图中的不同规格中的商品能全部添加到购物车 解题思路,要求1,这个任务比较简单,由于这种方式,后台里的商品规格选项必须用单选按钮来做,否则页面效果不容易实现具体要实现什么样式自己

5.goods商品列表页开发

goods组件显示的区域是固定的,也没有滚动条,所以是采用绝对布局的,左右分为menu栏和foods栏,左边固定布局,右边自适应布局,采用flex布局. 写CSS样式的时候,尽量用class,少用tag,因为class的查找效率优于tag,尤其是嵌套层级比较多的时候.左边的menu栏有些是一行有些是多行,要做到不管单行还是多行都是垂直是居中,可以用display:table,table布局是实现垂直居中的有效布局.menu-item设置display:table,text设置display:ta

ecshop商品列表页,循环显示当前分类的二级分类以及分类下的商品

1.includes\lib_goods.php,在最末尾添加几个function /** * 获得指定分类下的子分类 * * @access public * @param integer $cat_id 分类编号 * @return array */ function get_children_tree($cat_id) { if ($cat_id >0 ) { $sql = 'SELECT count(*) FROM ' . $GLOBALS['ecs']->table('categor