簡體   English   中英

什么時候在 Django 中使用 get、get_queryset、get_context_data?

[英]When to use get, get_queryset, get_context_data in Django?

我最近了解到,當您特別想要執行默認視圖以外的其他操作時,您應該覆蓋 get 方法:

class ExampleView(generic.ListView):
    template_name = 'ppm/ppm.html'

    def get(self, request):
        manager = request.GET.get('manager', None)
        if manager:
            profiles_set = EmployeeProfile.objects.filter(manager=manager)
        else:
            profiles_set = EmployeeProfile.objects.all()
            context = {
                'profiles_set': profiles_set,
                'title': 'Employee Profiles'
            }

這很簡單,但是我什么時候應該使用get_querysetget_context_data不是get 對我來說,他們似乎基本上做同樣的事情,還是我只是錯過了什么? 我可以一起使用它們嗎? 這對我來說是一個主要的困惑來源。

所以重申:在什么情況下我會使用get_querysetget_context_data ,反之亦然?

他們確實做不同的事情。

get()

這是一個頂級方法,每個 HTTP 動詞都有一個 - get()post()patch()等。當您想在視圖處理請求之前執行某些操作時,您可以覆蓋它,或者之后。 但這僅在第一次加載表單視圖時調用,而不是在提交表單時調用。 文檔中的基本示例 默認情況下,它只會呈現配置的模板並返回 HTML。

class MyView(TemplateView):
    # ... other methods

    def get(self, *args, **kwargs):
        print('Processing GET request')
        resp = super().get(*args, **kwargs)
        print('Finished processing GET request')
        return resp

get_queryset()

ListView使用 - 它確定要顯示的對象列表。 默認情況下,它只會為您指定的模型提供所有信息。 通過覆蓋此方法,您可以擴展或完全替換此邏輯。 有關該主題的 Django 文檔

class FilteredAuthorView(ListView):
    template_name = 'authors.html'
    model = Author

    def get_queryset(self):
        # original qs
        qs = super().get_queryset() 
        # filter by a variable captured from url, for example
        return qs.filter(name__startswith=self.kwargs['name'])

get_context_data()

此方法用於填充字典以用作模板上下文。 例如, ListView將在上面的示例author_list get_queryset()的結果填充為author_list 您可能最常覆蓋此方法以添加要在模板中顯示的內容。

def get_context_data(self, **kwargs):
    data = super().get_context_data(**kwargs)
    data['page_title'] = 'Authors'
    return data

然后在您的模板中,您可以引用這些變量。

<h1>{{ page_title }}</h1>

<ul>
{% for author in author_list %}
    <li>{{ author.name }}</li>
{% endfor %}
</ul>

現在回答你的主要問題,你有這么多方法的原因是讓你輕松地以精確的方式粘貼自定義邏輯。 它不僅使您的代碼更具可讀性和模塊化,而且更易於測試。

文檔應該解釋一切。 如果仍然不夠,您可能會發現這些來源也很有幫助。 你會看到一切都是如何用 mixin 實現的,因為一切都是分開的。

我們來看一下ListView的get方法的默認實現:

https://github.com/django/django/blob/92053acbb9160862c3e743a99ed8ccff8d4f8fd6/django/views/generic/list.py#L158

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 = len(self.object_list) == 0
            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_queryset在第一行中被調用。 如果您只想在應用一些過濾/排序等后返回模型的查詢集,您可以簡單地覆蓋它。

您不需要為此覆蓋整個get方法,因為您將缺少所有這些提供的功能,即分頁、404 檢查等。

get_context_data將結果查詢集與上下文數據(如用於分頁的查詢字符串參數等)合並在一起。

我的建議是每隔一段時間檢查一下 django 的源代碼,並嘗試對其進行一些了解,以便您可以識別出可以覆蓋/替換的最合適的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM