drf笔记。接口开发?一天就能学会。

写在前面:

官方文档为主,博客为辅。博主建议新人连同官方文档一起看,更有助于理解。看完觉得有收获,记得点赞。

drf是什么?

Django REST framework (官方文档地址)
是在前后端分离的开发模式中,基于Django的RestFul API开发框架。

drf怎么使用

正如django中类视图比函数视图简洁一般,drf很多地方也是有多种编写方式,下文直接使用简洁的一种。

第一步:定义序列化器。

在django项目中,创建serializers.py文件。
引入模型,定义序列化器:

from rest_framework import serializers
from .models import Books   # 引入自己的模型。替换掉相关字段即可。
class BooksSerializer(serializers.ModelSerializer):
    class Meta:
        model = Books
        fields = ['title', 'created_by', 'subject',
                  'country', 'created_time', 'content']

    def create(self, validated_data):
        
        return Books.objects.create(**validated_data)

    def update(self, instance, validated_data):
       
        instance.title = validated_data.get('title', instance.title)
        instance.created_by = validated_data.get(
            'created_by', instance.created_by)
        instance.subject = validated_data.get('subject', instance.subject)
        instance.country = validated_data.get('country', instance.country)
        instance.created_time = validated_data.get(
            'created_time', instance.created_time)
        instance.content = validated_data.get('content', instance.content)
        instance.save()
        return instance

*Django REST framework 官网已经有写好的代码。一般情况下复制上面代码,引入自己的模型。替换掉相关字段即可。

第二步:配置settings。

分页:

分页允许您控制每页返回多少个对象。
settings里添加代码:

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

添加app

settings中添加app处加入:rest_framework。

INSTALLED_APPS = [
    ...
    'rest_framework',
]

注意:这条配置,如果还没完成身份验证这一块的代码,先注释掉,不然会报错。


# drf配置
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'
    ]
}

第三步:编写视图。

直接使用通用类视图:

from .models import Books
from rest_framework import generics



class BookstList(generics.ListCreateAPIView):
    queryset = Books.objects.all()
    serializer_class = BooksSerializer


class BooksDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Books.objects.all()
    serializer_class = BooksSerializer

代码少吧?
可以对比下不使用通用视图的情况:
detail视图

from rest_framework import mixins
from rest_framework import generics
from .models import Books
from .serializers import BooksSerializer
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class BookstDetail(APIView):

    def get_object(self, pk):
        try:
            return Books.objects.get(pk=pk)
        except Books.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        book = self.get_object(pk)
        serializer = BooksSerializer(book)
        return Response(serializer.data)
    

    def put(self, request, pk, format=None):
        book = self.get_object(pk)
        serializer = BooksSerializer(book, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        book = self.get_object(pk)
        book.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

list视图:


class BooksListView(APIView):

    def get(self, request, format=None):
        books = Books.objects.all()
        serializer = BooksSerializer(books, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = BooksSerializer(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)

第四步:urls。

和django的urls文件都是一样的。

from django.urls import path
from . import views

from rest_framework.urlpatterns import format_suffix_patterns

urlpatterns = [
   
    path('detail/<int:pk>/', views.BooksDetail.as_view(), name='detail'),
    path('books_list/', views.BookstList.as_view(), name='books_list'),
]
urlpatterns = format_suffix_patterns(urlpatterns)

————————————————————— 可以休息一下线 —————————————————————

用户认证

用户认证无非就是两个问题:是否登录,是否有权限操作。当然,别忘了创建了用户。

from rest_framework import permissions
from .permissions import IsOwnerOrReadOnly

 class BookstList(generics.ListCreateAPIView):
     queryset = Books.objects.all()
     serializer_class = BooksSerializer
     permission_classes = [permissions.IsAuthenticatedOrReadOnly,
                           IsOwnerOrReadOnly]


 class BooksDetail(generics.RetrieveUpdateDestroyAPIView):
     queryset = Books.objects.all()
     serializer_class = BooksSerializer
     permission_classes = [permissions.IsAuthenticatedOrReadOnly,IsOwnerOrReadOnly]

通用视图添加一行代码就可以了。IsAuthenticatedOrReadOnly IsOwnerOrReadOnly两个权限即可满足大多数要求。
IsOwnerOrReadOnly权限需要手动编写:
创建permissions.py

from rest_framework import permissions


class IsOwnerOrReadOnly(permissions.BasePermission):

    def has_object_permission(self, request, view, obj):
        # Read permissions are allowed to any request,
        # so we'll always allow GET, HEAD or OPTIONS requests.
        if request.method in permissions.SAFE_METHODS:
            return True

        # Write permissions are only allowed to the owner of the snippet.
        return obj.created_by == request.user

也可以添加一个登录和注销的视图。不需要做更多操作。

urlpatterns += [
    path('api-auth/', include('rest_framework.urls')),
]

————————————————————— 可以休息一下线 —————————————————————

视图集和路由器

优点:

代码量更少了,专注于API提供的交互和表示形式。

缺点:

在使用基于类的视图而不是基于函数的视图时,与单独构建视图相比,使用视图集不那么明确。

views更改部分:

原先代码:
from rest_framework import generics


class BookstList(generics.ListCreateAPIView):
    queryset = Books.objects.all()
    serializer_class = BooksSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly,
                          IsOwnerOrReadOnly]


class BooksDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Books.objects.all()
    serializer_class = BooksSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly,IsOwnerOrReadOnly]

现在代码:
from rest_framework import viewsets # 不要忘了引入


class BooksViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Books.objects.all()
    serializer_class = BooksSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly,
                          IsOwnerOrReadOnly]

    def perform_create(self, serializer):
        serializer.save(created_by=self.request.user)

urls更改:

from rest_framework.routers import DefaultRouter
from .views import BooksViewSet
from django.urls import include # 其中一种方法需要引入

router = DefaultRouter()
router.register(r'', BooksViewSet) # 注册路由器

# 加入路由方法一
urlpatterns = [
	path('', include(router.urls)),
    '···'
]
# 加入路由方法二
urlpatterns += router.urls 

# 将viewset绑定到url
books_list = BooksViewSet.as_view({
    'get': 'list',
    'post': 'create'
})
books_detail = BooksViewSet.as_view({
    'get': 'retrieve',
    'put': 'update',
    'patch': 'partial_update',
    'delete': 'destroy'
})
现在拆解一下上面代码:

第一步,引入相关模块。
第二步,注册路由器。
第三步,添加路由数据。此处有两种方式,但是方法一报错,我选择了方法二。典型的打不过就跑,不丢人。
第四步,将viewset绑定到url。

对,这就结束了。官方文档为主,博客为辅。记得点赞。 这次一定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值