首页 > 解决方案 > Django 方法是如何调用的?

问题描述

我是 Django 的初学者。而且我不明白如何调用 Django 的内置方法。假设我们有这样的观点:

class HomeNews(MyMixin, ListView):
    model = News
    template_name = 'news/home_news_list.html'
    context_object_name = 'news'
    paginate_by = 2

    def get_queryset(self):
        return News.objects.filter(is_published=True).select_related('category')

    def my_method1(self, id):
        value = id + 123
        return = value     

请问这些方法是如何在我的app中调用的?我没有明确地称呼这些。这些会自动调用吗?

例如不是 django 代码,我会像 a.method() 一样调用,但在这里我们不调用,但这些仍然有效。请解释一下,我没有找到任何有关此的信息。

标签: djangodjango-modelsdjango-views

解决方案


请问这些方法是如何在我的app中调用的?我没有明确地称呼这些。

因为ListView有一个实现get,最终会调用get_queryset. 实际上,它ListView被实现为 [GitHub]

class ListView(MultipleObjectTemplateResponseMixin, BaseListView):
     "…"

并在BaseListView定义方法.get(…)[GitHub]中:

class BaseListView(MultipleObjectMixin, View):
    """A base view for displaying a list of objects."""
    def get(self, request, *args, **kwargs):
        self.object_list = self.get_queryset()
        allow_empty = self.get_allow_empty()

        if not allow_empty:
            # When pagination is enabled and object_list is a queryset,
            # it's better to do a cheap query than to load the unpaginated
            # queryset in memory.
            if self.get_paginate_by(self.object_list) is not None and hasattr(self.object_list, 'exists'):
                is_empty = not self.object_list.exists()
            else:
                is_empty = not self.object_list
            if is_empty:
                raise Http404(_('Empty list and “%(class_name)s.allow_empty” is False.') % {
                    'class_name': self.__class__.__name__,
                })
        context = self.get_context_data()
        return self.render_to_response(context)

因此,该.get(…)方法将调用.get_queryset(…)您的类中有覆盖的方法,然后它将检查是否允许空查询集,必要时对查询集进行分页等,并最终.render_to_response(…)使用它生成的上下文调用该方法以返回一个HTTP 响应。

.get(…)方法不是直接触发的。您通常传入.as_view(…)URL 模式,这意味着结果也是一个函数,如果它是一个 GET 请求,.as_view(…)它将执行调度和调用该方法,这在类 [GitHub]中实现:.get(…)View

    @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(
                    'The method name %s is not accepted as a keyword argument '
                    'to %s().' % (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)
            self.setup(request, *args, **kwargs)
            if not hasattr(self, 'request'):
                raise AttributeError(
                    "%s instance has no 'request' attribute. Did you override "
                    "setup() and forget to call super()?" % cls.__name__
                )
            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

因此,该.dispatch(…)方法将查看请求的 HTTP 方法是什么,并.get(…)在 GET 请求.post(…)的情况下调用,在 POST 请求的情况下等等,并且.http_method_not_allowed(…)在没有定义post// get… 方法的情况下调用。


推荐阅读