Django的views使用
这里介绍一下Django中常用的类视图,主要说明在视图中如何接收和传递参数、返回到页面等。
注意,使用这些类视图时,在url中需要加上.as_view()。
我将介绍的内容分为三部分:django的View
、rest_framework的APIView
和rest_framework的一些generic views
。
View
View来自django.views,常常用于页面的视图,主要功能在于其中的两个方法: get和post。
from django.shortcuts import render
from django.views import View
from django.http import HttpResponse
class 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相关内容参考: 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的使用。
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class 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参数,如
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方法。下面展示了各个方法的重写
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中指定的参数如下
<int:code>
这时需要在视图中指定查找的字段
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()
Django的views使用的更多相关文章
- Python Django 之 Views HttpRequest HttpReponse
一.Python Django 之 Views 数据交互 http请求中产生两个人核心对象: http请求:HttpRequest对象 http响应:HttpReponse对象 所在位置django. ...
- [Django笔记] views.py 深入学习
views.py 是django MTV 中的主要逻辑层,相当于MVC中的 Controller 以下的实例都基于这样一个路由表: urlpatterns = [ url(r'^(index)?$', ...
- Django之views系统
Django的View(视图)简介 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错 ...
- Django Class Views
一.Base views View class django.views.generic.base.View 主要的基于类的基本视图.所有其他基于类的视图都从这个基类继承而来.它不是一个通用的视图,因 ...
- Django中views笔记
reverse反解析 #路由中定义namespace.name,reverse可将其转换为url url = reverse('namespace:name') return redirect(url ...
- django中views中方法的request参数
知其然亦要知其所以然 views每个方法的参数都是request,那么问题来了,request为何物? 首先,几乎每个方法都是取数据(无论是从数据库,还是从第三方接口),然后进行一定的处理,之后传给前 ...
- Django之views
一 URL补充 二 Views试图函数 一 URL补充 1 MTV模型 2 django建立流程(用命令版) (1)django-admin startproject projectname (2) ...
- Django之views视图函数
views视图函数属于MTV中逻辑处理的部分视图函数包含着两个对象,HttpRequest对象和HttpResponse对象 一.HttpRequest对象 HttpRequest对象在Django中 ...
- 关于django Class-based views的理解
django是mvt模式,其中v就是这个显示逻辑部分,简单来讲,view函数可以说是接收request,然后处理,返回response的主体函数. 对于一些简单的逻辑关系,可以用直接用函数模式来进行处 ...
- Django的views视图系统
老师的博客:http://www.cnblogs.com/liwenzhou/articles/8305104.html 以看老师的博客为主 一个视图函数(类),简称视图,是一个简单的Python 函 ...
随机推荐
- 条款14:在资源管理类中小型coping的行为
首先假设对于一个mutex互斥器对象,有lock以及unlock两个函数可用: void lock(Mutex * pm); void unlock(Mutex * pm); 那么为了防止资源忘记被释 ...
- Android 中的BroadCastReceiver
BroadCastReceiver 简介 (末尾有源码) BroadCastReceiver 源码位于: framework/base/core/java/android.content.Broadc ...
- Mac os x 下配置Intellij IDEA + Tomcat 出现权限问题的解决办法
出现的错误提示如下: 下午9:11:27 All files are up-to-date下午9:11:27 All files are up-to-date下午9:11:27 Error runni ...
- Flask的配置文件
Flask的配置文件 与 session 配置文件 flask中的配置文件是一个flask.config.Config对象(继承字典) 默认配置为: { 'DEBUG': get_debug_flag ...
- ubuntu android 开始git安装
ubuntu android 开始git安装 git安装: http://source.android.com/source/initializing.html网站提示到以下网址下载: http: ...
- C++使用初始化列表的方式来初始化字段
几个月之前,接触Android recovery源代码的时候,看ScreenRecoveryUI类的时候,那时候C++基础还不是特别好,一直不明白以下的初始化方式: 下面这个是Recovery的一个构 ...
- java网络编程TCP传输—流操作—拿到源后的写入动作
在网络编程中的TCP传输里,拿到Socket的源后,应该怎么进行读写操作呢,下面我列举了两种方法,希望大家帮忙补充···· 1.利用byte数组作为一个缓冲区进行读写 客户端上传 //获取socket ...
- Java [Leetcode 347]Top K Frequent Elements
题目描述: Given a non-empty array of integers, return the k most frequent elements. For example,Given [1 ...
- hexo搭建个人主页托管于github
之前学习了 如何利用Github免费搭建个人主页,今天利用hexo来快速生成个人网页托管于github上. hexo系列教程:(一)hexo介绍 什么是hexo hexo是一个基于Node.js的静态 ...
- 【ecmall】解决无法上传店铺logo和banner照片问题 (转)
问题描述:在ecmall个人用户登录,点击用户中心-店铺设置-更换店标,上传一个jpg图像(图像符合规范)后,不能预览,而且在页面底部点击提交后没有上传成功.banner店铺条幅也是一样的情况,还有下 ...