Vue+Django REST framework 打造生鮮電商項(xiàng)目(1)

3-1項(xiàng)目初始化

虛擬環(huán)境目錄

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

*設(shè)置數(shù)據(jù)庫

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后面第三方登錄要用.
運(yùn)行提示

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

需要安裝mysqlclient

坑1 運(yùn)行的時(shí)候會報(bào)錯(cuò)

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兼容版本網(wǎng)址
www.lfd.uci.edu/~gohlke/pythonlibs/

  • 把新建的目錄加入setting,可以直接form引用
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復(fù)制的extra_apps下.
setting添加app.

5-1 django的view方法實(shí)現(xiàn)商品列表

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序列化

  • 可以用這個(gè)代替會出錯(cuò),圖片不能序列化.
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方式實(shí)現(xiàn)商品列表頁-1

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

如果MarkupSafe出現(xiàn)錯(cuò)誤,就需要去虛擬環(huán)境把utf-8改成gbk.
evns/vueshop/lib/site-packages/pip/compat/__init這個(gè)文件75行.

** 配置setting.添加app.

INSTALLED_APPS = {
'rest_framework',
}
  • 配置urls路徑
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))![微信截圖_20171204213202.png](http://upload-images.jianshu.io/upload_images/1716830-74c71acdef9bc6ae.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

5-4自定義serializer

1.urls上節(jié)配置成功了.
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

點(diǎn)擊OPTIONS會變成:


微信截圖_20171204215844.png
serializers增加一個(gè)字段,瀏覽器請求的json就增加一個(gè)字段.
  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

目標(biāo): 使用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

目標(biāo):請求所有字段

from rest_framework import serializers

from goods.models import Goods

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

成果:


微信截圖_20171204223736.png

目標(biāo):解析goods類中的外鍵category

  • 在serializers中添加GoodsCategorySerializer
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
  • 繼續(xù)簡寫views.py
    因?yàn)?


    微信截圖_20171204231143.png
  • 所以views.py可以寫成:

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 目標(biāo):分頁
  1. setting配置.
    教程說僅僅添加'PAGE_SIZE'會無效并不會掛機(jī).
    但是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)您已經(jīng)指定了一個(gè)默認(rèn)的PAGE_SIZE分頁rest_framework設(shè)置,而沒有指定一個(gè)DEFAULT_PAGINATION_CLASS。
提示:DEFAULT_PAGINATION_CLASS的默認(rèn)值是None。 在以前的版本中,這是PageNumberPagination。 如果您希望全局定義PAGE_SIZE,同時(shí)在每個(gè)視圖上定義pagination_class,則可以使此檢查無效。

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

}

  • 成果:


    微信截圖_20171204233825.png

RUN-3 定制分頁

微信截圖_20171204234448.png
  • 不需要設(shè)置setting只需更改views
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

目標(biāo)是引入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 區(qū)段過濾
  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 查詢關(guān)鍵詞
  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 搜索
  • 只更改views很少的代碼
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 排序
  • views
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
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容