一、使用
1.settings设置
INSTALLED_APPS = {
'rest_framework',
}
2.urls.py中使用类函数
from views import Hello
urlpatterns = [
url(r'^Hello/$', Hello.as_view(), name='hello')
]
3.views.py中使用APIView
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class Hello(APIView):
def get(self, request):
return Response({"valley_id": serializer.data['valley_id']},
status=status.HTTP_200_OK)
def post(self, request):
data = request.data
return Response({"valley_id": serializer.data['valley_id']},
status=status.HTTP_201_CREATED)
def put(self, request):
data = request.data
return Response({"valley_id": serializer.data['valley_id']},
status=status.HTTP_200_OK)
二、部分源码分析
1.rest_framework_jwt.views源码
class APIView(View):
# Allow dependency injection of other settings to make testing easier.
settings = api_settings
@classmethod
def as_view(cls, **initkwargs):
"""
Store the original class on the view function.
This allows us to discover information about the view when we do URL
reverse lookups. Used for breadcrumb generation.
"""
if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet):
def force_evaluation():
raise RuntimeError(
'Do not evaluate the `.queryset` attribute directly, '
'as the result will be cached and reused between requests. '
'Use `.all()` or call `.get_queryset()` instead.'
)
cls.queryset._fetch_all = force_evaluation
#调用父类的as_view函数
view = super(APIView, cls).as_view(**initkwargs)
view.cls = cls
view.initkwargs = initkwargs
# Note: session based authentication is explicitly CSRF validated,
# all other authentication is CSRF exempt.
return csrf_exempt(view)
def dispatch(self, request, *args, **kwargs):
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args
self.kwargs = kwargs
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate?
try:
self.initial(request, *args, **kwargs)
# Get the appropriate handler method
if request.method.lower() in self.http_method_names:
#根据request的请求方法获取类的相应方法
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
response = handler(request, *args, **kwargs)
except Exception as exc:
response = self.handle_exception(exc)
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
2.django.views.generic.base.py中View类的源码
class View:
"""
Intentionally simple parent class for all views. Only implements
dispatch-by-method and simple sanity checking.
"""
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
@classonlymethod
def as_view(cls, **initkwargs):
"""Main entry point for a request-response process."""
for key in initkwargs:
if key in cls.http_method_names:
raise TypeError("You tried to pass in the %s method name as a "
"keyword argument to %s(). Don't do that."
% (key, cls.__name__))
if not hasattr(cls, key):
raise TypeError("%s() received an invalid keyword %r. as_view "
"only accepts arguments that are already "
"attributes of the class." % (cls.__name__, key))
def view(request, *args, **kwargs):
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
#调用dispatch函数,此时调用的是子类已被重写的dispatch函数
return self.dispatch(request, *args, **kwargs)
view.view_class = cls
view.view_initkwargs = initkwargs
# take name and docstring from class
update_wrapper(view, cls, updated=())
# and possible attributes set by decorators
# like csrf_exempt from dispatch
update_wrapper(view, cls.dispatch, assigned=())
return view
三、总结
有关函数视图与类视图的区别,可到Django中类视图与函数视图中了解
本文由是博主根据资料总结及自己的理解编写而成。还有未涉及的,会不定期更新,有错误请指正。
如果有不懂的可以留言,大家一起讨论、沟通,一起学习,一起进步。