Python 学习笔记(十九)--Django REST Framework之GenericAPIView(二)
13 GenericAPIView中的get_object方法
get_object方法,目的是为了获取一条数据。
def get_object(self): """ Returns the object the view is displaying. You may want to override this if you need to provide non-standard queryset lookups. Eg if objects are referenced using multiple keyword arguments in the url conf. """ queryset = self.filter_queryset(self.get_queryset()) ###返回所有数据 # Perform the lookup filtering. lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field ###定义变量,lookup_url_kwarg就是pk,路由中有名分组分出来的pk values 值。 assert lookup_url_kwarg in self.kwargs, ( 'Expected view %s to be called with a URL keyword argument ' 'named "%s". Fix your URL conf, or set the `.lookup_field` ' 'attribute on the view correctly.' % (self.__class__.__name__, lookup_url_kwarg) ) filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]} ###构造出一个字典对象,{pk:有名分组分出来的values值}。
###self.kwargs[lokup_url_kwarg]对应的就是浏览器地址中要查询的pk值。 obj = get_object_or_404(queryset, **filter_kwargs) # May raise a permission denied self.check_object_permissions(self.request, obj) return obj
lookup_field 与 lookup_url_kwarg的说明。
# If you want to use object lookups other than pk, set 'lookup_field'.
# For more complex lookup requirements override `get_object()`.
lookup_field = 'pk'
lookup_url_kwarg = None
14其中调用到的方法get_object_or_404
def get_object_or_404(queryset, *filter_args, **filter_kwargs): """ Same as Django's standard shortcut, but make sure to also raise 404 if the filter_kwargs don't match the required types. """ try: return _get_object_or_404(queryset, *filter_args, **filter_kwargs) except (TypeError, ValueError, ValidationError): raise Http404
进一步调用_get_object_or_404
from django.shortcuts import get_object_or_404 as _get_object_or_404
源码如下:
def get_object_or_404(klass, *args, **kwargs): """ Use get() to return an object, or raise a Http404 exception if the object does not exist. klass may be a Model, Manager, or QuerySet object. All other passed arguments and keyword arguments are used in the get() query. Like with QuerySet.get(), MultipleObjectsReturned is raised if more than one object is found. """ queryset = _get_queryset(klass) if not hasattr(queryset, 'get'): klass__name = klass.__name__ if isinstance(klass, type) else klass.__class__.__name__ raise ValueError( "First argument to get_object_or_404() must be a Model, Manager, " "or QuerySet, not '%s'." % klass__name ) try: return queryset.get(*args, **kwargs) except queryset.model.DoesNotExist: raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
最核心的代码 queryset.get(*args, **kwargs)
15 自动生成路由
第一步,urls文件中导入routers
from rest_framework import routers
第二步,导入两个类:routers.DefaultRouter 和 routers.SimpleRouter
实例化等到对象
例如:
router = routers.SimpleRouter()
第三步,注册
router.register()
register 方法的源码,如下
def register(self, prefix, viewset, basename=None): ###至少传入两个参数 prefix--前缀 和 viewset---继承自ModelViesSet的视图类;注意所谓的前缀说的是url前缀,
###需要注意的是,这个前缀后面不要加'\'字符了.
###basename,就是常说的别名,反向解析使用。 if basename is None: basename = self.get_default_basename(viewset) self.registry.append((prefix, viewset, basename)) # invalidate the urls cache if hasattr(self, '_urls'): del self._urls
第四步,添加到路由中
router.urls ##这个对象就是自动生成的路由
所以,添加代码就是 urlpatterns += router.urls