[django] View類視圖

View——所有類視圖的父類

View是所有類視圖的父類,包括在之後使用的最重要的DjangoRESTframework中的所有view,都是繼承於它。View可以直接從from django.views中導入:

from django.views import View

class MyView(View):
      def get(self,request):
          pass

由於Python支持多繼承,因此,通用顯示視圖繼承於包括基礎視圖的多個類,用於顯示數據,有兩類:ListView和DetailView。

ListView

ListView,用於顯示一個對象列表的視圖,包含一個屬性值object_list,表示對象的列表。因此在模板文件中可以通過遍歷該屬性來顯示model的所有數據,如:

from django.views.generic import ListView

class StudentList(ListView):
    model = Student
    template_name = "student_list.html"

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data(**kwargs)
        context['number'] = random.randrange(1, 100)
        return context

常用屬性、方法總結如下:

model
該屬性用來指定要顯示的model。在該例中,model = Student相當於:

querySet = Student.objects.all()

表示將會把所有model中的記錄提供給模板顯示,因此,如果要顯示滿足條件的記錄,可以通過如下方式提供指定數據,並存儲在queryset屬性中,比如要顯示model中姓名爲‘zhangsan’的人,而不是所有人,可以將model = Student修改爲:

queryset = Student.objects.filter(name='zhangsan')

queryset
該屬性表示該視圖顯示項的集合,可以通過get_queryset()方法來進行定義。

get_queryset()
該方法得到一個該視圖顯示項的集合,在方法內部實際上是對queryset的操作,返回值必須是可迭代的,或者是QuerySet,比如:

from django.shortcuts import get_object_or_404

    def get_queryset(self):
        stulist = []
        stulist.append(get_object_or_404(Student, name='Zhangsan'))
        return stulist

由於Student不可迭代,因此返回一個可迭代的list集合,相當於:

queryset = Student.objects.filter(name='zhangsan')

template_name
template_name表示要使用的模板,如果不指定模板,則對於ListView來說,會自動推斷模板名, 使用名爲/_list.html的默認模板,不存在則出現TemplateDoesNotExist。

object_list
指定模板後,再來看看模板文件中如何顯示通用視圖中的數據:

{% block content %}
    <h2>Student</h2>
    <ul>
        {% for student in object_list %}
        <li>
             {{student.name }}
        </li>
        {% endfor %}
        <li>
            {{number}}
        </li>
    </ul>

{% endblock %}

在剛開始已經說過了,ListView中的object_list屬性中,存放了model中要顯示的記錄(或者說model對象),因此可以通過遍歷object_list屬性直接獲取即可顯示。

context_object_name
在模板中使用object_list是一個不太友好的方法,因爲不知道object_list具體指的是哪個模板的數據,因此在通用視圖中還提供了一個屬性:context_object_name來制定一個上下文,如:

class showStu(ListView):
    ...
    context_object_name = "student"

在模板文件中,就可使用student來替換object_list,當然object_list依舊是可用的。
通常使用model的小寫字母來賦值context_object_name。

DetailView

DetailView用於顯示一個特定類型對象的詳細信息。DetailView的大部分屬性和方法和ListView相同。不同的是該視圖沒有object_list屬性,因爲該視圖負責顯示一個特定對象的詳細信息,因此有一個object屬性,表示model的一個對象(或一條記錄)。

get_context_data()
該方法返回視圖的上下文,在ListView中,即返回的是object_list,在DetailViewView,則返回object對象。如果要使用該視圖顯示model中的所有對象(或記錄),則可以通過get_context_data()方法返回上下文,將所有對象信息添加到上下文中,也可以添加其他信息到上下文中,如:

from django.views.generic import DetailView

class ShowStuDetail(DetailView):
    model = Student
    template_name = "show_stu_detail.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
    # 添加一個上下文信息
        context["number"] = random.randrange(10)
        return context

object
在模板中,可以通過object來獲取詳細信息,如:

<h2>name:{{object.name}}</h2>
<h2>age:{{object.age}}</h2>

get_object()
該方法返回要顯示的對象,即object,如果提供了queryset,則queryset將作爲該方法返回值。因此,如果需要修改要顯示對象的信息,可以通過該方法,如:

 def get_object(self):
        # Call the superclass
        object = super().get_object()
        # 修改屬性值
        object.last_accessed = timezone.now()
        object.save()
        # Return the object
        return object

在配置URL時,DetailView 期望從URL中捕獲名爲 “pk” 的主鍵值,所以DetailView的url配置一般爲這種形式:

path('<int:pk>/', views.QuestionDetailView.as_view(), name='detail'),

總結:

以上雖然只對View、ListView、DetailView進行了總結,但還是有不少廢話。其實,只需要通過View瞭解下類視圖長啥樣就行了,爲什麼?因爲以後用不到其他的類視圖,因爲現在web開發前後端分離是趨勢,不會使用Django中的模板進行前端的開發。所以應該將主要精力放在Django REST 框架中的View中,這也是之後要學習的重點。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章