博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django的views使用
阅读量:6432 次
发布时间:2019-06-23

本文共 7188 字,大约阅读时间需要 23 分钟。

这里介绍一下Django中常用的类视图,主要说明在视图中如何接收和传递参数、返回到页面等。

注意,使用这些类视图时,在url中需要加上.as_view()。

我将介绍的内容分为三部分:django的View、rest_framework的APIView和rest_framework的一些generic views

View

View来自django.views,常常用于页面的视图,主要功能在于其中的两个方法: get和post。

from django.shortcuts import renderfrom django.views import Viewfrom django.http import HttpResponseclass EditPageView(View):    def get(self, request):        # 获取用户        user = request.user        # 获取参数        name = request.GET.get('name')        # 返回参数        context = {            'name': name,        }        # return HttpResponse("无权限编辑")        return render(request=request, template_name="task/edit.html", context=context)             def post(self, request):        # 获取参数        name = request.POST.get('name')        return render(request=request, template_name="user/login.html")

在上面的例子中展示了get和post方法如何获取参数和返回到页面。

注意,如果参数是在url中的话,就要把参数放在get或者post的参数列表中。像下面APIView中的一样。

返回时,除了返回到页面,也可以返回一个HttpResponse对象或者使用JsonResponse返回数据。

HttpResponse和JsonResponse相关内容参考:

APIView

APIView来自rest_framework.views,实际上是View的子类。它们之间的区别在于:

  • APIView的请求是rest_framework的Request,而不是Django的HttpRequest
  • APIView的返回可以是rest_framework的Response,不是HttpResponse。
  • 任何APIException异常将会被捕获并且调解到合适的返回中去
  • 请求在调度到相关的方法之前会作相应的auth和permission验证

我的另一篇博客介绍serializers的使用时,其中的编写view部分采用的就是APIView,地址:。这里列出tutorial上的例子,能更加详细地说明APIView的使用。

from snippets.models import Snippetfrom snippets.serializers import SnippetSerializerfrom django.http import Http404from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework import statusclass SnippetList(APIView):    """    List all snippets, or create a new snippet.    """    def get(self, request, format=None):        snippets = Snippet.objects.all()        serializer = SnippetSerializer(snippets, many=True)        return Response(serializer.data)    def post(self, request, format=None):        serializer = SnippetSerializer(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)class SnippetDetail(APIView):    """    Retrieve, update or delete a snippet instance.    """    def get_object(self, pk):        try:            return Snippet.objects.get(pk=pk)        except Snippet.DoesNotExist:            raise Http404    def get(self, request, pk, format=None):        snippet = self.get_object(pk)        serializer = SnippetSerializer(snippet)        return Response(serializer.data)    def put(self, request, pk, format=None):        snippet = self.get_object(pk)        serializer = SnippetSerializer(snippet, 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):        snippet = self.get_object(pk)        snippet.delete()        return Response(status=status.HTTP_204_NO_CONTENT)

1.SnippetList

  • get:获取数据列表
  • post:创建一条数据

2.SnippetDetail

其中的get、put和delete都是指请求的方式,url的参数放在对应方法的参数列表中,如url中的例子中的pk参数。

  • get_object:相当于Model.objects.get(),获取一条数据
  • get:get方法,获取一条数据
  • put:修改数据
  • delete:删除数据

generics views

generics的这些类使得编写views非常简单,基本上都可以使用下面代码,只有在特殊需求时要作一些调整和补充。

class StudentCreateView(generics.CreateAPIView):    """    创建学生api    """    queryset = Student.objects.all()    serializer_class = StudentSerializer    # 权限    permission_classes = (IsAuthenticated, )

各个不同的类都可以重写相应的方法来满足不同的需求,下面对一些类进行补充说明。

  • ListAPIView
    用于获取列表,可以对结果进行过滤和排序
class TaskListView(generics.ListAPIView):    """    任务列表api    """    queryset = Task.objects.all()    serializer_class = TaskListSerializer    # 不要分页    pagination_class = None     # 权限控制    permission_classes = (IsAuthenticated,)    # 根据关键词过滤    filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)    filter_fields = ('status', 'status_code')    # 搜索    search_fields = ('machine', 'code__code', 'description')    # 排序    ordering_fields = ('id', 'time_added', 'time_end', 'status_code')    ordering = ('status_code', 'id')    def list(self, request, *args, **kwargs):        if request.user.is_superuser:            self.serializer_class = TaskModeInfoSerializer        # 调用父类函数        return super().list(request, *args, **kwargs)    def get_queryset(self):        type_ = self.request.GET.get('type', 'start')        if type_ == 'all':            return Task.objects.all()        else:            return Task.objects.filter(status=type_)

1.get_queryset:自定义如何查询结果集

2.search_fields:定义搜索的字段,比如当url是http:127.0.0.1:8081/machine?search=100,即在定义的字段中搜索包含100的数据。注意当要搜索外键的某些字段时,采用双下划线指定外键的字段,如上的code__code。
3.ordering_fields: 定义排序的字段,和上面一样,在url中使用ordering参数,如
4.list:等价于get方法,查看源码可以知道其中包含了对get_queryset的获取的结果集的处理。
5.过滤功能参考:

  • RetrieveUpdateDestroyAPIView
    提供GET、PUT和DELETE方法,很多时候我们需要的删除是软删除,即不从数据库中删除数据,而改变某个标识的值,这时候就需要重写delete方法。下面展示了各个方法的重写
class GroupDetail(generics.RetrieveUpdateDestroyAPIView):    """    Group Detail    支持:GET、PUT、DELETE    """    queryset = Group.objects.all()    serializer_class = GroupSerializer    # 权限控制    permission_classes = (IsSuperUserOrReadOnly,)    def retrieve(self, request, *args, **kwargs):        self.serializer_class = GroupInfoSerializer        return super().retrieve(request, *args, **kwargs)    def update(self, request, *args, **kwargs):        self.serializer_class = GroupSerializer        # self.permission_classes = (IsSuperUser,)        return super().update(request, *args, **kwargs)    def destroy(self, request, *args, **kwargs):        # 如果Group中user_set不为空,就不让删除        group = get_object_or_404(Group, *args, **kwargs)        if group.user_set.count() > 0:            content = {"status": False, "message": "分组中还有用户,不可以删除"}            return Response(data=content)        else:            return super().destroy(request, *args, **kwargs)

实际上在各个视图中,以下几组方法是对等的:retrieve和get、update和put、destory和delete,list和get。

当然,我们也可以不返回父类的方法,比如要实行软删除时就不能调用父类的方法,如下删除用户的例子

class UserDetailView(generics.RetrieveUpdateDestroyAPIView):    """    用户详情api    """    queryset = User.objects.all()    serializer_class = UserDetailSerializer    # 权限控制    permission_classes = (IsSuperUserOrReadOnly,)    def delete(self, request, *args, **kwargs):        # 第1步:获取到用户        user = self.get_object()        if user == request.user:            content = {                "status": False,                "message": "不可以删除自己"            }            return Response(content, status=400)        # 第2步:对用户进行删除        # 2-1:设置deleted和is_active        user.deleted = True        user.is_active = False        user.save()        # 第3步:返回响应        response = Response(status=204)        return response
  • UpdateAPIView
    当我们编写操作某条数据的视图时,需要在url中传递找到该条数据的参数,默认是使用pk。我们也可以指定其它字段来作为参数,比如我在url中指定的参数如下

这时需要在视图中指定查找的字段

lookup_field = 'task'
  • RetrieveAPIView
    获取某条数据,有时候我们需要在找不到数据时创建数据,这时可以在类视图中重写get_object方法。
def get_object(self):    student = Student.objects.get_or_create(**self.kwargs)    return super().get_object()

在其它方法中如果我们要对该对象做一些操作,首先要获取该对象,就使用get_object方法

# instance = super().get_object()instance = self.get_object()

转载于:https://www.cnblogs.com/suraer/p/8521280.html

你可能感兴趣的文章
WTL中最简单的实现窗口拖动的方法(转)
查看>>
数据结构—队列
查看>>
BZOJ4241 : 历史研究
查看>>
(LeetCode)两个队列来实现一个栈
查看>>
jquery封装常用方法
查看>>
什么是ICE (Internet Communications Engine)
查看>>
移动web开发之屏幕三要素
查看>>
求按小时统计的语句,该怎么处理
查看>>
TRUNCATE,DORP,DELETE
查看>>
Chrome的开发必备小技巧
查看>>
can-i-win(好)
查看>>
Centos6.5下安装protobuf及简单使用
查看>>
[SharePoint] SharePoint 错误集 3
查看>>
高压光耦
查看>>
[转]DPM2012系列之六:在Win7上安装DPM远程管理控制台
查看>>
postgres函数
查看>>
Microsoft AJAX Library Cheat Sheet(5): Number和Error类型的扩展
查看>>
AfxGetMainWnd函数
查看>>
WebView增加一个水平Progress,位置、长相随意
查看>>
easyui messager alert 三秒后自动关闭提示
查看>>