Djangopython

Vue+Django REST framework 打造生鲜电商

2017-12-05  本文已影响273人  吕阳

3-1项目初始化

虚拟环境目录

C:\Users\Lv_Shine\Envs\VueShop\Scripts\python.exe

*设置数据库

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': "mxshop",
        'USER': 'root',
        'PASSWORD': "root",
        'HOST': "127.0.0.1",
        'PORT': '3306',
        'OPTIONS': {'init_command': 'SET storage_engine=INNODB;'},
    }
}

options后面第三方登录要用.
运行提示

ImproperlyConfigured: Error loading MySQLdb module: No module named 'MySQLdb'.
Did you install mysqlclient or MySQL-python?

需要安装mysqlclient

坑1 运行的时候会报错

django.db.utils.OperationalError: (1193, "Unknown system variable 'storage_engine'")

解决,名字改成default_storage_engine
I have found in the following links that indeed the variable "storage_engine" has been renamed to "default_storage_engine", which has caused some software to start getting issues with recent versions of MySql.

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': "mxshop",
        'USER': 'root',
        'PASSWORD': "root",
        'HOST': "127.0.0.1",
        'OPTIONS': { 'init_command': 'SET default_storage_engine=INNODB;' }
    }
}

用于下载各种库的win兼容版本网址
www.lfd.uci.edu/~gohlke/pythonlibs/

import os
import sys
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, BASE_DIR)
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
sys.path.insert(0, os.path.join(BASE_DIR, 'extra_apps'))
微信截图_20171201165209.png

3-2

3-7 xadmin

微信截图_20171202125759.png
微信截图_20171202130117.png

安装依赖包,xadmin复制的extra_apps下.
setting添加app.

5-1 django的view方法实现商品列表

views_base.py

class GoodsListView(View):
    def get(self,request):
        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)

        from django.http import HttpResponse
        import json
        return HttpResponse(json.dumps(json_list), content_type="application/json")
  1. url配置
url(r'goods/$', GoodsListView.as_view(), name="goods-list"),

5-2 django的serializer序列化

class GoodsListView(View):
    def get(self,request):
        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)

        for good in goods:
            json_dict = model_to_dict(good)
            json_list.append(json_dict)
        from django.http import HttpResponse
        import json
        return HttpResponse(json.dumps(json_list), content_type="application/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_dict["add_time"] = good.add_time
        #     json_list.append(json_dict)

        # from django.forms.models import model_to_dict
        # for good in goods:
        #     json_dict = model_to_dict(good)
        #     json_list.append(json_dict)

        import json
        from django.core import serializers
        json_data = serializers.serialize('json', goods)
        json_data = json.loads(json_data)
        from django.http import HttpResponse, JsonResponse
        return JsonResponse(json_data, safe=False)


5-3 apiview方式实现商品列表页-1

微信截图_20171203110238.png
pip install django-guardian
pip install coreapi

如果MarkupSafe出现错误,就需要去虚拟环境把utf-8改成gbk.
evns/vueshop/lib/site-packages/pip/compat/__init这个文件75行.

** 配置setting.添加app.

INSTALLED_APPS = {
'rest_framework',
}
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))![微信截图_20171204213202.png](https://img.haomeiwen.com/i1716830/74c71acdef9bc6ae.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

5-4自定义serializer

1.urls上节配置成功了.
2.views

from rest_framework.response import Response

from rest_framework.views import APIView

from goods.models import Goods
from goods.serializers import GoodsSerializer


class GoodsListView(APIView):

    def get(self, request, format=None):
        goods = Goods.objects.all()[:10]
        goods_serializer = GoodsSerializer(goods, many=True)
        return Response(goods_serializer.data)
  1. serializers
from rest_framework import serializers

__author__ = 'lv'
__date__ = '2017/12/4 21:39'


class GoodsSerializer(serializers.Serializer):
    name = serializers.CharField(required=True, max_length=100)
    click_num = serializers.IntegerField(default=0)

成果:

微信截图_20171204214637.png

点击OPTIONS会变成:


微信截图_20171204215844.png
serializers增加一个字段,浏览器请求的json就增加一个字段.
  1. serializers
from rest_framework import serializers

__author__ = 'lv'
__date__ = '2017/12/4 21:39'


class GoodsSerializer(serializers.Serializer):
    name = serializers.CharField(required=True, max_length=100)
    click_num = serializers.IntegerField(default=0)
    goods_front_image = serializers.ImageField()

成果:


微信截图_20171204220221.png

目标: 使用serializers.ModelSerializer改写serializers

from rest_framework import serializers

from goods.models import Goods

__author__ = 'lv'
__date__ = '2017/12/4 21:39'


# class GoodsSerializer(serializers.Serializer):
#     name = serializers.CharField(required=True, max_length=100)
#     click_num = serializers.IntegerField(default=0)
#     goods_front_image = serializers.ImageField()

class GoodsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Goods
        fields = ('name', 'click_num', 'market_price', 'add_time')

成果:

微信截图_20171204223236.png

目标:请求所有字段

from rest_framework import serializers

from goods.models import Goods

class GoodsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Goods
        fields = "__all__"

成果:


微信截图_20171204223736.png

目标:解析goods类中的外键category

from rest_framework import serializers

from goods.models import Goods, GoodsCategory

__author__ = 'lv'
__date__ = '2017/12/4 21:39'

class GoodsCategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = GoodsCategory
        fields = "__all__"


class GoodsSerializer(serializers.ModelSerializer):
    category = GoodsCategorySerializer()
    class Meta:
        model = Goods
        # fields = ('name', 'click_num', 'market_price', 'add_time')
        fields = "__all__"


5-6

*RUN-1重写view-GoodsListView,继承mixins.ListModelMixin,generics.GenericAPIView

from django.shortcuts import render

# Create your views here.
from rest_framework import mixins, generics
from rest_framework.response import Response

from rest_framework.views import APIView

from goods.models import Goods
from goods.serializers import GoodsSerializer


# class GoodsListView(APIView):
#
#     def get(self, request, format=None):
#         goods = Goods.objects.all()[:10]
#         goods_serializer = GoodsSerializer(goods, many=True)
#         return Response(goods_serializer.data)

class GoodsListView(mixins.ListModelMixin, generics.GenericAPIView):

    queryset = Goods.objects.all()[:10]
    serializer_class = GoodsSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

成果:


微信截图_20171204230357.png 微信截图_20171204230639.png
from django.shortcuts import render

# Create your views here.
from rest_framework import mixins, generics
from rest_framework.response import Response

from rest_framework.views import APIView

from goods.models import Goods
from goods.serializers import GoodsSerializer


# class GoodsListView(APIView):
#       第一种
#     def get(self, request, format=None):
#         goods = Goods.objects.all()[:10]
#         goods_serializer = GoodsSerializer(goods, many=True)
#         return Response(goods_serializer.data)


# class GoodsListView(mixins.ListModelMixin, generics.GenericAPIView):
#       第二种
#     queryset = Goods.objects.all()[:10]
#     serializer_class = GoodsSerializer
#
#     def get(self, request, *args, **kwargs):
#         return self.list(request, *args, **kwargs)


class GoodsListView(generics.ListAPIView):
    queryset = Goods.objects.all()[:10]
    serializer_class = GoodsSerializer
RUN-2 目标:分页
  1. setting配置.
    教程说仅仅添加'PAGE_SIZE'会无效并不会挂机.
    但是pycharm会提示


    微信截图_20171204233505.png
WARNINGS:
?: (rest_framework.W001) You have specified a default PAGE_SIZE pagination rest_framework setting,without specifying also a DEFAULT_PAGINATION_CLASS.
    HINT: The default for DEFAULT_PAGINATION_CLASS is None. In previous versions this was PageNumberPagination. If you wish to define PAGE_SIZE globally whilst defining pagination_class on a per-view basis you may silence this check.

System check identified 1 issue (0 silenced).

警告:
?:(rest_framework.W001)您已经指定了一个默认的PAGE_SIZE分页rest_framework设置,而没有指定一个DEFAULT_PAGINATION_CLASS。
提示:DEFAULT_PAGINATION_CLASS的默认值是None。 在以前的版本中,这是PageNumberPagination。 如果您希望全局定义PAGE_SIZE,同时在每个视图上定义pagination_class,则可以使此检查无效。

REST_FRAMEWORK = {
    'PAGE_SIZE': 10
}
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 10,

}

RUN-3 定制分页

微信截图_20171204234448.png
class GoodsPagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = 'page_size'
    page_query_param = "p"
    max_page_size = 100


class GoodsListView(generics.ListAPIView):
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination
微信截图_20171204235344.png

5-7viewsets和router

目标是引入router
RUN-4
  1. 改写views.py
from django.shortcuts import render

# Create your views here.
from rest_framework import mixins, generics, viewsets
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response

from rest_framework.views import APIView

from goods.models import Goods
from goods.serializers import GoodsSerializer


class GoodsPagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = 'page_size'
    page_query_param = "p"
    max_page_size = 100


# class GoodsListView(APIView):
#       第一种
#     def get(self, request, format=None):
#         goods = Goods.objects.all()[:10]
#         goods_serializer = GoodsSerializer(goods, many=True)
#         return Response(goods_serializer.data)


# class GoodsListView(mixins.ListModelMixin, generics.GenericAPIView):
#       第二种
#     queryset = Goods.objects.all()[:10]
#     serializer_class = GoodsSerializer
#
#     def get(self, request, *args, **kwargs):
#         return self.list(request, *args, **kwargs)


# class GoodsListView(generics.ListAPIView):
#     queryset = Goods.objects.all()
#     serializer_class = GoodsSerializer
#     pagination_class = GoodsPagination


class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    """
    引入router
    商品列表页
    """
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination
  1. urls
good_list = GoodsListViewSet.as_view(
    {
        'get': 'list',
        
    }
)
             ``````
url(r'goods/$', good_list, name="goods-list"),
            ``````

RUN-5 router改写urls
  1. urls
"""MxShop URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url, include
from django.contrib import admin
from django.db import router
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 GoodsListView, GoodsListViewSet

# good_list = GoodsListViewSet.as_view(
#     {
#         'get': 'list',
#
#     }
# )

router = DefaultRouter()

router.register(r'goods', GoodsListViewSet),




urlpatterns = [
    url(r'^xadmin/', xadmin.site.urls),
    url(r'^media/(?P<path>.*)$',serve,{"document_root": MEDIA_ROOT}),

    # url(r'goods/$', good_list, name="goods-list"),
    url(r'^', include(router.urls)),

    url(r'docs/', include_docs_urls(title="慕雪生鲜")),

    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]

5-8

微信截图_20171205084100.png
  1. generic 通用
  2. retrieve 取回
微信截图_20171205090912.png

5-10 过滤

微信截图_20171205091625.png
RUN-6 过滤
  1. 添加APPS到setting
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'DjangoUeditor',
    'users.apps.UsersConfig',
    'goods.apps.GoodsConfig',
    'trade.apps.TradeConfig',
    'user_operation.apps.UserOperationConfig',
    'crispy_forms',
    'django_filters',
    'xadmin',
    'rest_framework',
   

]

  1. views
class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    """
    引入router
    商品列表页
    """
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination

    filter_backends = (DjangoFilterBackend,)
    filter_fields = ('name', 'shop_price')

成果:


微信截图_20171205092611.png
RUN-7 区段过滤
  1. filters.py
# _*_ coding: utf-8 _*_
import django_filters

from goods.models import Goods

__author__ = 'lv'
__date__ = '2017/12/5 10:17'


class GoodsFilter(django_filters.rest_framework.FilterSet):

    price_min = django_filters.NumberFilter(name='shop_price', lookup_expr='gte')
    price_max = django_filters.NumberFilter(name='shop_price', lookup_expr='lte')

    class Meta:
        model = Goods
        fields = ['price_min', 'price_max']
  1. views
class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    """
    引入router
    商品列表页
    """
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination

    filter_backends = (DjangoFilterBackend,)
    filter_class = GoodsFilter


成果:


微信截图_20171205102909.png
RUN-8 查询关键词
  1. view
# _*_ coding: utf-8 _*_
import django_filters

from goods.models import Goods

__author__ = 'lv'
__date__ = '2017/12/5 10:17'


class GoodsFilter(django_filters.rest_framework.FilterSet):

    price_min = django_filters.NumberFilter(name='shop_price', lookup_expr='gte')
    price_max = django_filters.NumberFilter(name='shop_price', lookup_expr='lte')
    name = django_filters.CharFilter(name='name', lookup_expr='icontains')

    class Meta:
        model = Goods
        fields = ['price_min', 'price_max', 'name']
微信截图_20171205103749.png
RUN-9 搜索
from rest_framework import filters

class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    """
    引入router
    商品列表页
    """
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination

    filter_backends = (DjangoFilterBackend, filters.SearchFilter)
    filter_class = GoodsFilter
    search_fields = ('name', 'goods_brief', 'goods_desc')

成果:


微信截图_20171205104454.png

searche 字段可以匹配正则.

RUN-10 排序
class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    """
    引入router
    商品列表页
    """
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination

    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = GoodsFilter
    search_fields = ('name', 'goods_brief', 'goods_desc')
    ordering_fields = ('sold_num', 'add_time')

成果:

微信截图_20171205110557.png
上一篇下一篇

猜你喜欢

热点阅读