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

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

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

View

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

  1. from django.shortcuts import render
  2. from django.views import View
  3. from django.http import HttpResponse
  4. class EditPageView(View):
  5. def get(self, request):
  6. # 获取用户
  7. user = request.user
  8. # 获取参数
  9. name = request.GET.get('name')
  10. # 返回参数
  11. context = {
  12. 'name': name,
  13. }
  14. # return HttpResponse("无权限编辑")
  15. return render(request=request, template_name="task/edit.html", context=context)
  16. def post(self, request):
  17. # 获取参数
  18. name = request.POST.get('name')
  19. return render(request=request, template_name="user/login.html")

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

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

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

HttpResponse和JsonResponse相关内容参考: Request and response objects

APIView

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

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

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

  1. from snippets.models import Snippet
  2. from snippets.serializers import SnippetSerializer
  3. from django.http import Http404
  4. from rest_framework.views import APIView
  5. from rest_framework.response import Response
  6. from rest_framework import status
  7. class SnippetList(APIView):
  8. """
  9. List all snippets, or create a new snippet.
  10. """
  11. def get(self, request, format=None):
  12. snippets = Snippet.objects.all()
  13. serializer = SnippetSerializer(snippets, many=True)
  14. return Response(serializer.data)
  15. def post(self, request, format=None):
  16. serializer = SnippetSerializer(data=request.data)
  17. if serializer.is_valid():
  18. serializer.save()
  19. return Response(serializer.data, status=status.HTTP_201_CREATED)
  20. return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
  21. class SnippetDetail(APIView):
  22. """
  23. Retrieve, update or delete a snippet instance.
  24. """
  25. def get_object(self, pk):
  26. try:
  27. return Snippet.objects.get(pk=pk)
  28. except Snippet.DoesNotExist:
  29. raise Http404
  30. def get(self, request, pk, format=None):
  31. snippet = self.get_object(pk)
  32. serializer = SnippetSerializer(snippet)
  33. return Response(serializer.data)
  34. def put(self, request, pk, format=None):
  35. snippet = self.get_object(pk)
  36. serializer = SnippetSerializer(snippet, data=request.data)
  37. if serializer.is_valid():
  38. serializer.save()
  39. return Response(serializer.data)
  40. return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
  41. def delete(self, request, pk, format=None):
  42. snippet = self.get_object(pk)
  43. snippet.delete()
  44. 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非常简单,基本上都可以使用下面代码,只有在特殊需求时要作一些调整和补充。

  1. class StudentCreateView(generics.CreateAPIView):
  2. """
  3. 创建学生api
  4. """
  5. queryset = Student.objects.all()
  6. serializer_class = StudentSerializer
  7. # 权限
  8. permission_classes = (IsAuthenticated, )

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

  • ListAPIView

    用于获取列表,可以对结果进行过滤和排序
  1. class TaskListView(generics.ListAPIView):
  2. """
  3. 任务列表api
  4. """
  5. queryset = Task.objects.all()
  6. serializer_class = TaskListSerializer
  7. # 不要分页
  8. pagination_class = None
  9. # 权限控制
  10. permission_classes = (IsAuthenticated,)
  11. # 根据关键词过滤
  12. filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
  13. filter_fields = ('status', 'status_code')
  14. # 搜索
  15. search_fields = ('machine', 'code__code', 'description')
  16. # 排序
  17. ordering_fields = ('id', 'time_added', 'time_end', 'status_code')
  18. ordering = ('status_code', 'id')
  19. def list(self, request, *args, **kwargs):
  20. if request.user.is_superuser:
  21. self.serializer_class = TaskModeInfoSerializer
  22. # 调用父类函数
  23. return super().list(request, *args, **kwargs)
  24. def get_queryset(self):
  25. type_ = self.request.GET.get('type', 'start')
  26. if type_ == 'all':
  27. return Task.objects.all()
  28. else:
  29. 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参数,如

http:127.0.0.1:8081/machine?ordering=-id

4.list:等价于get方法,查看源码可以知道其中包含了对get_queryset的获取的结果集的处理。

5.过滤功能参考: http://www.django-rest-framework.org/api-guide/filtering/

  • RetrieveUpdateDestroyAPIView

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

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

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

  1. class UserDetailView(generics.RetrieveUpdateDestroyAPIView):
  2. """
  3. 用户详情api
  4. """
  5. queryset = User.objects.all()
  6. serializer_class = UserDetailSerializer
  7. # 权限控制
  8. permission_classes = (IsSuperUserOrReadOnly,)
  9. def delete(self, request, *args, **kwargs):
  10. # 第1步:获取到用户
  11. user = self.get_object()
  12. if user == request.user:
  13. content = {
  14. "status": False,
  15. "message": "不可以删除自己"
  16. }
  17. return Response(content, status=400)
  18. # 第2步:对用户进行删除
  19. # 2-1:设置deleted和is_active
  20. user.deleted = True
  21. user.is_active = False
  22. user.save()
  23. # 第3步:返回响应
  24. response = Response(status=204)
  25. return response
  • UpdateAPIView

    当我们编写操作某条数据的视图时,需要在url中传递找到该条数据的参数,默认是使用pk。我们也可以指定其它字段来作为参数,比如我在url中指定的参数如下
  1. <int:code>

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

  1. lookup_field = 'task'
  • RetrieveAPIView

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

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

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

Django的views使用的更多相关文章

  1. Python Django 之 Views HttpRequest HttpReponse

    一.Python Django 之 Views 数据交互 http请求中产生两个人核心对象: http请求:HttpRequest对象 http响应:HttpReponse对象 所在位置django. ...

  2. [Django笔记] views.py 深入学习

    views.py 是django MTV 中的主要逻辑层,相当于MVC中的 Controller 以下的实例都基于这样一个路由表: urlpatterns = [ url(r'^(index)?$', ...

  3. Django之views系统

    Django的View(视图)简介 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错 ...

  4. Django Class Views

    一.Base views View class django.views.generic.base.View 主要的基于类的基本视图.所有其他基于类的视图都从这个基类继承而来.它不是一个通用的视图,因 ...

  5. Django中views笔记

    reverse反解析 #路由中定义namespace.name,reverse可将其转换为url url = reverse('namespace:name') return redirect(url ...

  6. django中views中方法的request参数

    知其然亦要知其所以然 views每个方法的参数都是request,那么问题来了,request为何物? 首先,几乎每个方法都是取数据(无论是从数据库,还是从第三方接口),然后进行一定的处理,之后传给前 ...

  7. Django之views

    一 URL补充 二 Views试图函数 一 URL补充 1 MTV模型 2  django建立流程(用命令版) (1)django-admin startproject projectname (2) ...

  8. Django之views视图函数

    views视图函数属于MTV中逻辑处理的部分视图函数包含着两个对象,HttpRequest对象和HttpResponse对象 一.HttpRequest对象 HttpRequest对象在Django中 ...

  9. 关于django Class-based views的理解

    django是mvt模式,其中v就是这个显示逻辑部分,简单来讲,view函数可以说是接收request,然后处理,返回response的主体函数. 对于一些简单的逻辑关系,可以用直接用函数模式来进行处 ...

  10. Django的views视图系统

    老师的博客:http://www.cnblogs.com/liwenzhou/articles/8305104.html 以看老师的博客为主 一个视图函数(类),简称视图,是一个简单的Python 函 ...

随机推荐

  1. jquery 中多条件选择器,相对选择器,层次选择器的区别

    一.Jquery常用的过滤选择器如下所示: 1.:first,选取第一个元素,比如$("div:first")选取第一个div元素 2.:last,选取最后一个元素,比如$(&qu ...

  2. Kotlin For Gank.io (干货集中营Kotlin实现)

    介绍 Kotlin,现在如火如荼,所以花了一点时间把之前的项目用Kotlin重构一下 原项目地址:https://github.com/onlyloveyd/GankIOClient 对应Kotlin ...

  3. pgrep 和 pkill 使用小记

    在停止指定进程时,经常使用如下命令: kill `ps aux | grep -w program_name | grep -v grep | awk '{print $2}'` 使用 pgrep 和 ...

  4. (三十六)类数组对象arguments

    类数组对象:arguments 在函数调用时,我们总能见到arguments这个对象,它具体是用来干什么的呢?感觉逼格非常高呢 函数在使用时,我们总会位函数传入各种参数,arguments会将参数储存 ...

  5. C# chart控件运用

    为了弄一个实时数据显示的窗口,最近一周时间都耗在这个控件上了,属性有点多(下面列的是一些常用的) 后来干脆写代码把他们封装起来,各个chart直接来调用它,省得到属性里面去设置. chart内的一些元 ...

  6. PING分组网间探测 ICMP协议

      1.Ping的基础知识 Ping是潜水艇人员的专用术语,表示回应的声纳脉冲,在网络中Ping 是一个十分好用的TCP/IP工具.它主要的功能是用来检测网络的连通情况和分析网络速度.是ICMP的一个 ...

  7. WCF日志跟踪SvcTraceViewer.exe

    参考: https://msdn.microsoft.com/zh-cn/library/ms732023.aspx https://msdn.microsoft.com/zh-cn/library/ ...

  8. ASP.NET 2.0缓存

    MSDN上缓存概述: http://msdn2.microsoft.com/zh-cn/library/726btaeh(VS.80).aspx 一.页输出缓存 1.设置 ASP.NET 页缓存的两种 ...

  9. centos6.x 配置bond

    centos6.x 配置bond centos6.x 配置bond1 物理网卡配置2 bond0网卡配置3 查看bond0网卡状态 摘要: centos6.x下使用双网卡配置bond0, centos ...

  10. Ambari的资源池管理

    操作: YARN→Config→Advanced→Schedule capacity-scheduler=null yarn.scheduler.capacity.default.minimum-us ...