03 drf入门

入门

尽量去官网看文档 https://www.django-rest-framework.org/

1.安装

ip install djangorestframework
pip install markdown       # Markdown support for the browsable API.
pip install django-filter  # Filtering support

Add 'rest_framework' to your INSTALLED_APPS setting.

INSTALLED_APPS = (
    ...
    'rest_framework',
)

If you're intending to use the browsable API you'll probably also want to add REST framework's login and logout views. Add the following to your root urls.py file.

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

Any global settings for a REST framework API are kept in a single configuration dictionary named REST_FRAMEWORK. Start off by adding the following to your settings.py module:

REST_FRAMEWORK = {
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
    ]
}

开始

  1. 在goods下新建serializer.py文件
# _*_ coding: utf-8 _*_
__author__ = 'daxiahy'
__date__ = '2019/3/29 16:04'


from rest_framework import serializers


class GoodsSerializer(serializers.Serializer):
    name = serializers.CharField(required=True, max_length=100)
    click_num = serializers.IntegerField(default=0)
  1. 在views.py下书写
from .serializer import GoodsSerializer
from .models import Goods
from rest_framework.views import APIView
from rest_framework.response import Response


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. urls.py
from goods.views import GoodsListView

    # 商品列表页
    url(r'^goods/$', GoodsListView.as_view(), name="goods-list"),

增加数据的方法

在serializers.py的class中增加 create方法

# 添加内容
    def create(self, validated_data):
        return Goods.objects.create(**validated_data)

在views的class中增加post方法

from rest_framework import status

    # 添加商品的方法
    def post(self,request, format=None):
        serializer =GoodsSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

使用更为方便的ModelSerializer

# _*_ coding: utf-8 _*_
from rest_framework import serializers
from goods.models import Goods


class GoodsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Goods
        fields = ('name', 'click_num', 'goods_front_image', 'market_price', 'add_time')
        # 也可以用  "__all__"  取出全部

序列化的嵌套

# _*_ coding: utf-8 _*_
__author__ = 'daxiahy'
__date__ = '2019/3/29 16:04'


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 = CategorySerializer()  # 序列化的嵌套

    class Meta:
        model = Goods
        fields = "__all__"

使用mixins.ListModelMixin

from django.shortcuts import render

# Create your views here.
from .serializer import GoodsSerializer
from .models import Goods
from rest_framework import mixins
from rest_framework import generics


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)

更加简洁的写法 ListApiView

# _*_ coding: utf-8 _*_

from .serializer import GoodsSerializer
from .models import Goods
from rest_framework import generics


class GoodsListView(generics.ListAPIView):
    """
    商品列表页
    """
    queryset = Goods.objects.all()[:10]
    serializer_class = GoodsSerializer

当然也可以用generics 源码下的其他方法

  • CreateAPIView
  • DestroyAPIView
  • UpdateAPIView

等等之类的

分页

注;尽量把全局变量的分页配置删掉 在settings.py中加入配置

# django restframework 配置
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10,
}

在取数据时记得取所有

queryset = Goods.objects.all()

刷新就会发现已经分页成功

当然也可以重置PageNumberPagination
  1. 将settings.py的分页配置删掉
  2. 在views.py中写
# _*_ coding: utf-8 _*_

from .serializer import GoodsSerializer
from .models import Goods
from rest_framework import generics
from rest_framework.pagination import PageNumberPagination


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().order_by("id")  # 一定要排序 不然分页会出错
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination

使用viewset

通过viewsets来绑定,views.py书写方法如下

# _*_ coding: utf-8 _*_

from .serializer import GoodsSerializer
from .models import Goods
from rest_framework import generics
from rest_framework.pagination import PageNumberPagination
from rest_framework import viewsets
from rest_framework import mixins

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


class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    """
    商品列表页
    """
    queryset = Goods.objects.all().order_by("id")  # 一定要排序 不然分页会出错
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination

使用DefaultRouter更简洁的书写url

from django.contrib import admin

from django.urls import path
from django.conf.urls import url, include
from django.views.static import serve
from rest_framework.routers import DefaultRouter
from mx_shop.settings import MEDIA_ROOT
import xadmin

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

router = DefaultRouter()
# 商品列表页 配置goods的url
router.register(r'goods', GoodsListViewSet)


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

    # 商品列表页
    url(r'^', include(router.urls))


]

GoodsListViewSet的书写

class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    """
    商品列表页
    """
    queryset = Goods.objects.all().order_by("id")  # 一定要排序 不然分页会出错
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination

GoodsSerializer的书写

class GoodsSerializer(serializers.ModelSerializer):
    category = CategorySerializer()  # 序列化的嵌套

    class Meta:
        model = Goods
        fields = "__all__"