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

16. ViewSet

from rest_framework.viewsets import ViewSet

ViewSet的源码

class ViewSet(ViewSetMixin, views.APIView):
    """
    The base ViewSet class does not provide any actions by default.
    """
    pass

继承APIView和ViewSetMixin;在ViewSet中,没有提供任何动作action方法,需要使用者自己实现action方法。

ViewSet视图集类不再限制视图方法名只允许get()、post()等这种情况了,而是实现允许开发者根据自己的需要定义自定义方法名,例如 list() 、create() 等,然后经过路由中使用http和这些视图方法名进行绑定调用。ViewSet 中实现了以下几个方法。

list  #get 请求 返回全部查询
create  #post 请求 处理表单提交数据
retrieve #get 请求 通过pk 查询单个信息
update  #patch 请求 通过pk 修改数据
destroy  #delete 请求 通过pk 删除数据

 通过路由指向,绑定视图类中对应的方法。

格式为

path(路由,绑定的试图类.as_view({请求方式:绑定的视图类中具体的方法}))

使用as_view()方法,定义好action与请求方法的对应关系,可以将action动作与具体的请求方法对应上。

例如

复制代码
urlpatterns = format_suffix_patterns([
    path('', IndexViewSet.as_view({'get': 'list'})),   
    path('<int:pk>/', XXXX.as_view({'get': 'retrieve'})),
    path('post/',XXXXX.as_view({'post': 'create'})),

    path('patch/<int:pk>/',XXXXX.as_view({'patch':'update'})),

    path('destroy/<int:pk>/', XXXXX.as_view({'delete':'destroy'}))

])
复制代码

 17. 几种ViewSet的继承关系

 说明

(1)GenericViewSet

GenericViewSet 继承自GenericAPIView 和 ViewSetMixin,作用让视图集的代码变得更加通用,抽离独特代码作为视图类的属性。

使用ViewSet通常并不方便,因为list、retrieve、create、update、destroy等方法都需要自己编写,而这些方法与Mixin扩展类提供的方法同名,所以我们可以通过继承Mixin扩展类来复用这些方法而无需自己编写。但是Mixin扩展类依赖于GenericAPIView,所以还需要继承GenericAPIView。

 

posted @   东山絮柳仔  阅读(146)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示