代码有繁琐到精炼:
目录
3.Requests and Responses views.py及urls.py优化
7.1 添加字段operator 录入者 models.py
7.3 views.py 只有登录才可以查看 permissions
8.2 serializers.py 设置书籍的出版社为汉字 publisher=...
10.2 restproject APP的urls.py 修改
models.py
from django.db import models
# Create your models here.
class Books(models.Model):
name = models.CharField(max_length=32, verbose_name="书名")
publisher = models.ForeignKey("Publishers")
def __str__(self):
return self.name
class Meta:
verbose_name = "书籍"
verbose_name_plural = verbose_name
class Publishers(models.Model):
name = models.CharField(max_length=32, verbose_name="出版社名称")
address = models.CharField(max_length=128, verbose_name="出版社地址")
def __str__(self):
return self.name
class Meta:
verbose_name = "出版社"
verbose_name_plural = verbose_name
1.基础代码
views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.forms.models import model_to_dict
from django.core import serializers
from .models import Publishers, Books
from .serializers import PublishersSerializer
import json
# Create your views here.
def publisher_list(request):
queryset = Publishers.objects.all()
# data = []
# for i in queryset:
# temp = {
# 'name': i.name,
# 'address': i.address
# }
# data.append(temp)
# data = []
# model_to_dict 对于图片等字段无法转换
# for i in queryset:
# data.append(model_to_dict(i))
# serialize已经把data转换成json格式
# data = serializers.serialize("json", queryset)
# return HttpResponse(data, content_type="application/json")
s=PublishersSerializer(queryset,many=True)
return HttpResponse(json.dumps(s.data), content_type="application/json")
urls.py
from django.conf.urls import url, include
from django.contrib import admin
from app01.views import publisher_list
urlpatterns = [
url(r'^publishers/$', publisher_list),
url(r'^admin/', admin.site.urls),
]
serializers.py
# -*- coding: utf-8 -*-
from rest_framework import serializers
from .models import Books, Publishers
class PublishersSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
name = serializers.CharField(required=False, max_length=32)
address = serializers.CharField(required=False, max_length=128)
def create(self, validated_data):
return Publishers.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.name = validated_data.get('name', instance.name)
instance.address = validated_data.get('address', instance.address)
instance.save()
return instance
2.serializers.py优化
# -*- coding: utf-8 -*-
from rest_framework import serializers
from .models import Books, Publishers
class PublisherSerializer(serializers.ModelSerializer):
class Meta:
model = Publishers
fields = (
'id', 'name', 'address'
)
3.Requests and Responses views.py及urls.py优化
3.1 views.py @api_view 函数视图
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Publishers, Books
from .serializers import PublisherSerializer
@api_view(['GET', 'POST'])
def publisher_list(request):
"""
列出所有的出版社 或创建新的出版社
"""
if request.method == 'GET':
queryset = Publishers.objects.all()
s = PublisherSerializer(queryset, many=True)
return Response(s.data)
elif request.method == 'POST':
s = PublisherSerializer(data=request.data)
if s.is_valid():
s.save()
return Response(s.data, status=status.HTTP_201_CREATED)
return Response(s.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET', 'PUT', 'DELETE'])
def publisher_detail(request,pk):
try:
s = Publishers.objects.get(pk=pk)
except Publishers.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = PublisherSerializer(s)
return Response(serializer.data)
elif request.method == 'PUT':
serializer = PublisherSerializer(s, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'DELETE':
s.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
3.2 urls.py 接口文档
from rest_framework.documentation import include_docs_urls
from django.conf.urls import url, include
from django.contrib import admin
from app01.views import publisher_list, publisher_detail
urlpatterns = [
url(r'^docs/', include_docs_urls(title="图书管理系统")),
url(r'^publishers/$', publisher_list),
url(r'^publishers/(?P<pk>[0-9]+)$', publisher_detail),
url(r'^admin/', admin.site.urls),
]
4.Class-based Views
4.1views.py APIView
from django.http import Http404
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Publishers, Books
from .serializers import PublisherSerializer
class PublishersList(APIView):
"""
列出所有的出版社 或创建新的出版社
"""
def get(self, request, format=None):
queryset = Publishers.objects.all()
s = PublisherSerializer(queryset, many=True)
return Response(s.data)
def post(self, request, format=None):
s = PublisherSerializer(data=request.data)
if s.is_valid():
s.save()
return Response(s.data, status=status.HTTP_201_CREATED)
return Response(s.errors, status=status.HTTP_400_BAD_REQUEST)
class PublishersDetail(APIView):
"""
Retrieve, update or delete a snippet instance.
"""
def get_object(self, pk):
try:
return Publishers.objects.get(pk=pk)
except Publishers.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
publisher = self.get_object(pk)
s = PublisherSerializer(publisher)
return Response(s.data)
def put(self, request, pk, format=None):
publisher = self.get_object(pk)
s = PublisherSerializer(publisher, data=request.data)
if s.is_valid():
s.save()
return Response(s.data)
return Response(s.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
publisher = self.get_object(pk)
publisher.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
4.2 urls.py
from rest_framework.documentation import include_docs_urls
from django.conf.urls import url, include
from django.contrib import admin
from app01.views import PublishersList, PublishersDetail
urlpatterns = [
url(r'^docs/', include_docs_urls(title="图书管理系统")),
url(r'^publishers/$', PublishersList.as_view()),
url(r'^publishers/(?P<pk>[0-9]+)/$', PublishersDetail.as_view()),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^admin/', admin.site.urls),
]
5.视图使用 mixins
from rest_framework import mixins
from rest_framework import generics
from .models import Publishers, Books
from .serializers import PublisherSerializer
class PublisherList(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
queryset = Publishers.objects.all()
serializer_class = PublisherSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class PublisherDetail(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
generics.GenericAPIView):
queryset = Publishers.objects.all()
serializer_class = PublisherSerializer
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
6.views.py 使用基于类的通用视图
from rest_framework import generics
from .models import Publishers, Books
from .serializers import PublisherSerializer
class PublisherList(generics.ListCreateAPIView):
queryset = Publishers.objects.all()
serializer_class = PublisherSerializer
class PublisherDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Publishers.objects.all()
serializer_class = PublisherSerializer
7.认证和权限
7.1 添加字段operator 录入者 models.py
from django.db import models
# Create your models here.
class Books(models.Model):
name = models.CharField(max_length=32, verbose_name="书名")
publisher = models.ForeignKey("Publishers")
def __str__(self):
return self.name
class Meta:
verbose_name = "书籍"
verbose_name_plural = verbose_name
class Publishers(models.Model):
name = models.CharField(max_length=32, verbose_name="出版社名称")
address = models.CharField(max_length=128, verbose_name="出版社地址")
operator = models.ForeignKey("auth.User")
def __str__(self):
return self.name
class Meta:
verbose_name = "出版社"
verbose_name_plural = verbose_name
7.2 serializers.py 变动
# -*- coding: utf-8 -*-
from rest_framework import serializers
from .models import Books, Publishers
class PublisherSerializer(serializers.ModelSerializer):
operator = serializers.ReadOnlyField(source='operator.username')
class Meta:
model = Publishers
fields = (
'id', 'name', 'address', 'operator'
)
7.3 views.py 只有登录才可以查看 permissions
from rest_framework import generics, permissions
from .models import Publishers, Books
from .serializers import PublisherSerializer
class PublisherList(generics.ListCreateAPIView):
queryset = Publishers.objects.all()
serializer_class = PublisherSerializer
permission_classes = (permissions.IsAuthenticated,)
class PublisherDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Publishers.objects.all()
serializer_class = PublisherSerializer
permission_classes = (permissions.IsAuthenticated,)
7.4 views.py 只有创建该出版社的用户可以修改,其他用户只看查看
7.4.1permissions.py(新增)
# -*- coding: utf-8 -*-
from rest_framework import permissions
class IsOwnerOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.operator == request.user
7.4.2 views.py
from rest_framework import generics, permissions
from .models import Publishers, Books
from .serializers import PublisherSerializer
from .permissions import IsOwnerOrReadOnly
class PublisherList(generics.ListCreateAPIView):
queryset = Publishers.objects.all()
serializer_class = PublisherSerializer
permission_classes = (permissions.IsAuthenticated, IsOwnerOrReadOnly)
def perform_create(self, serializer):
serializer.save(operator=self.request.user)
class PublisherDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Publishers.objects.all()
serializer_class = PublisherSerializer
permission_classes = (permissions.IsAuthenticated, IsOwnerOrReadOnly)
8.两个关联model示例
8.1 views.py
from rest_framework import generics, permissions
from .models import Publishers, Books
from .serializers import PublisherSerializer, BookSerializer
from .permissions import IsOwnerOrReadOnly
class PublisherList(generics.ListCreateAPIView):
queryset = Publishers.objects.all()
serializer_class = PublisherSerializer
permission_classes = (permissions.IsAuthenticated, IsOwnerOrReadOnly)
def perform_create(self, serializer):
serializer.save(operator=self.request.user)
class PublisherDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Publishers.objects.all()
serializer_class = PublisherSerializer
permission_classes = (permissions.IsAuthenticated, IsOwnerOrReadOnly)
class BookList(generics.ListCreateAPIView):
queryset = Books.objects.all()
serializer_class = BookSerializer
permission_classes = (permissions.IsAuthenticated,)
class BookDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Books.objects.all()
serializer_class = BookSerializer
permission_classes = (permissions.IsAuthenticated,)
8.2 serializers.py 设置书籍的出版社为汉字 publisher=...
# -*- coding: utf-8 -*-
from rest_framework import serializers
from .models import Books, Publishers
class PublisherSerializer(serializers.ModelSerializer):
operator = serializers.ReadOnlyField(source='operator.username')
class Meta:
model = Publishers
fields = (
'id', 'name', 'address', 'operator'
)
class BookSerializer(serializers.ModelSerializer):
publisher=serializers.StringRelatedField(source="publisher.name")
class Meta:
model = Books
fields = "__all__"
8.3 urls.py
from rest_framework.documentation import include_docs_urls
from django.conf.urls import url, include
from django.contrib import admin
from app01.views import PublisherList, PublisherDetail, BookList, BookDetail
urlpatterns = [
url(r'^docs/', include_docs_urls(title="图书管理系统")),
url(r'^publishers/$', PublisherList.as_view()),
url(r'^publishers/(?P<pk>[0-9]+)/$', PublisherDetail.as_view()),
url(r'^books/$', BookList.as_view()),
url(r'^books/(?P<pk>[0-9]+)/$', BookDetail.as_view()),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^admin/', admin.site.urls),
]
9.关系和超链接API
9.1 serializers.py
# -*- coding: utf-8 -*-
from rest_framework import serializers
from .models import Books, Publishers
class PublisherSerializer(serializers.ModelSerializer):
operator = serializers.ReadOnlyField(source='operator.username')
class Meta:
model = Publishers
fields = (
'id', 'name', 'address', 'operator'
)
class BookSerializer(serializers.HyperlinkedModelSerializer):
publisher = serializers.HyperlinkedRelatedField(view_name='publisher-detail', read_only=True)
class Meta:
model = Books
fields = (
'id', 'name', 'publisher'
)
9.2 urls.py name=..
from rest_framework.documentation import include_docs_urls
from django.conf.urls import url, include
from django.contrib import admin
from app01.views import PublisherList, PublisherDetail, BookList, BookDetail
urlpatterns = [
url(r'^docs/', include_docs_urls(title="图书管理系统")),
url(r'^publishers/$', PublisherList.as_view(), name="publisher-list"),
url(r'^publishers/(?P<pk>[0-9]+)/$', PublisherDetail.as_view(), name="publisher-detail"),
url(r'^books/$', BookList.as_view(), name="book-list"),
url(r'^books/(?P<pk>[0-9]+)/$', BookDetail.as_view(), name="book-detail"),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^admin/', admin.site.urls),
]
10.为API的根创建端点及分页
10.1 在app01 APP中创建urls.py
from django.conf.urls import url, include
from app01.views import PublisherList, PublisherDetail, BookList, BookDetail, api_root
urlpatterns = [
url(r'^$', api_root),
url(r'^publishers/$', PublisherList.as_view(), name="publisher-list"),
url(r'^publishers/(?P<pk>[0-9]+)/$', PublisherDetail.as_view(), name="publisher-detail"),
url(r'^books/$', BookList.as_view(), name="book-list"),
url(r'^books/(?P<pk>[0-9]+)/$', BookDetail.as_view(), name="book-detail"),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]
10.2 restproject APP的urls.py 修改
from rest_framework.documentation import include_docs_urls
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^api/', include("app01.urls")),
url(r'^docs/', include_docs_urls(title="图书管理系统")),
url(r'^admin/', admin.site.urls),
]
10.3 views.py 新增代码段
@api_view(['GET'])
def api_root(request, format=None):
return Response({
'books': reverse('book-list', request=request, format=format),
'publishers': reverse('publisher-list', request=request, format=format)
})
10.4 settings.py新增代码段
STATIC_URL = '/static/'
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS':'rest_framework.pagination.PageNumberPagination',
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAdminUser'
],
'PAGE_SIZE': 1
}
11视图集和路由器
11.1 views.py
from rest_framework import viewsets, permissions
from .models import Publishers, Books
from .serializers import PublisherSerializer, BookSerializer
from .permissions import IsOwnerOrReadOnly
class PublisherViewSet(viewsets.ModelViewSet):
queryset = Publishers.objects.all()
serializer_class = PublisherSerializer
permission_classes = (permissions.IsAuthenticated, IsOwnerOrReadOnly)
class BookViewSet(viewsets.ModelViewSet):
queryset = Books.objects.all()
serializer_class = BookSerializer
permission_classes = (permissions.IsAuthenticated,)
11.2 serializers.py
# -*- coding: utf-8 -*-
from rest_framework import serializers
from .models import Books, Publishers
class PublisherSerializer(serializers.ModelSerializer):
operator = serializers.ReadOnlyField(source='operator.username')
class Meta:
model = Publishers
fields = (
'id', 'name', 'address', 'operator'
)
class BookSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Books
fields = (
'id', 'name', 'publisher'
)
11.3 app01的urls.py
from django.conf.urls import url, include
from rest_framework.routers import DefaultRouter
from app01.views import PublisherViewSet, BookViewSet
router = DefaultRouter()
router.register(r'publishers', PublisherViewSet)
router.register(r'books', BookViewSet)
urlpatterns = [
url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]
12.更改路径
12.1 restproject的路径
from rest_framework.documentation import include_docs_urls
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^restproject/', include("app01.urls")),
url(r'^docs/', include_docs_urls(title="图书管理系统")),
url(r'^admin/', admin.site.urls),
]
12.2app01的urls.py
from django.conf.urls import url, include
from rest_framework.routers import DefaultRouter
from rest_framework.schemas import get_schema_view
from app01.views import PublisherViewSet, BookViewSet
router = DefaultRouter()
router.register(r'publishers', PublisherViewSet)
router.register(r'books', BookViewSet)
schema_view = get_schema_view(title='Pastebin API')
urlpatterns = [
url(r'^', include(router.urls)),
url(r'^schema/$', schema_view),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]