日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

Python Django CBV下的通用视图函数

發(fā)布時間:2025/5/22 python 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python Django CBV下的通用视图函数 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

ListView

TemplateView

DetailView

?

之前的代碼實例基本上都是基于FBV的模式來撰寫的,好處么,當(dāng)然就是簡單粗暴。。正如:

def index(request):return HttpResponse('hello world')

上面的寫法,基本接觸不到視圖函數(shù)里面的通用視圖。只是在介紹CBV的時候稍微介紹了下引用,大概用法。

?

導(dǎo)入

之前的導(dǎo)入一直用的是

from django.views import View

這里從view下鉆一下會發(fā)現(xiàn):

from django.views.generic.base import View__all__ = ['View']

對頭、view視圖函數(shù)基本都來自于generic里面,此篇blog具體講述的內(nèi)容也是generic內(nèi)部的幾個通用視圖:ListView、DetailView、TemplateView。

?

?

View

基礎(chǔ)類視圖:

from django.http import HttpResponse from django.views import Viewclass MyView(View):def get(self, request):return HttpResponse('ok') urlpatterns = [path('index/',views.MyView.as_view(), name='index'), ]

as_view()方法會返回一個函數(shù)來處理請求和響應(yīng),還可以將類視圖中定義的屬性作為該方法參數(shù),覆蓋類視圖中的屬性值。?

?

基本視圖

基本視圖包括三類:View、TemplateView和RedirectView。用戶可繼承基本類視圖來定義視圖,所有的通用視圖也都繼承與這三類基本視圖實現(xiàn),因此相比于通用視圖,基本視圖提供的功能較少。

View

View是所有類視圖的父類,可以直接從from django.views中導(dǎo)入,如:

from django.views import Viewclass MyView(View):def get(self,request):pass

http請求的方法

http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

as_view():該方法是一個類方法,被@classonlymethod修飾,是http請求和響應(yīng)的入口,用于url配置。在Http請求和響應(yīng)的過程中,會將request對象和其他參數(shù)作為參數(shù)傳入該方法,內(nèi)部調(diào)用dispatch()方法后返回一個Response對象。

?

TemplateView

繼承結(jié)構(gòu):

class TemplateView(TemplateResponseMixin, ContextMixin, View):

TemplateView視圖通過給定的模板進(jìn)行渲染。

實例

class StudentDetailTemplate(TemplateView): # 繼承TemplateViewtemplate_name = 'student_template.html' # 模版名稱def get_context_data(self, **kwargs):context = super().get_context_data(**kwargs) # 繼承父類里面的get_context_data,返回上下文數(shù)據(jù)context['name'] = 'dandy' # 添加新的數(shù)據(jù)context['data'] = {'age': 18, # 添加新的字典'flag': 'aaa'}context['data1'] = models.Student.objects.all() # 添加新的querysetreturn context # 返回更新過的上下文文數(shù)據(jù)

url:

path('templateview/', views.StudentDetailTemplate.as_view(), name='student_template'),

?

其他為涉及到的屬性或方法:

get_template_names()

除了使用template_name指定模板文件,也可通過該方法指定模板文件:

def get_template_names(self):return "student_template.html"

extra_content

除了在get_context_data()中添加上下文信息外,也可以在url配置時在as_view()方法中指定extra_context屬性來添加上下文信息,如:

path('templateview/', views.StudentDetailTemplate.as_view(extra_context={"extra": "。。。。"}), name='student_template'),

CBV正常是需要在下面定義一個get或之類的方法,用來匹配method,但是此處是不需要的,因為查看TemplateView內(nèi)部時會發(fā)現(xiàn):

class TemplateView(TemplateResponseMixin, ContextMixin, View):"""Render a template. Pass keyword arguments from the URLconf to the context."""def get(self, request, *args, **kwargs):context = self.get_context_data(**kwargs)return self.render_to_response(context)

內(nèi)部已經(jīng)寫好了這個get方法,一方面TemplateView的基礎(chǔ)需求其實就是返回模版給瀏覽器的。當(dāng)然了,因為繼承了TemplateView,這里還是可以重寫這個get方法,進(jìn)行自定義數(shù)據(jù)。

def get(self, request, *args, **kwargs):context = self.get_context_data(**kwargs)context['end'] = 'ending'new_data ={'a': 'b'}context.update(new_data)return self.render_to_response(context)

?

RedirectView

用來進(jìn)行跳轉(zhuǎn), 默認(rèn)是永久重定向(301),可以直接在urls.py中使用,非常方便:

path('', views.IndexPage.as_view(), name='baidu'), class ArticleCounterRedirectView(RedirectView):url = ' # 要跳轉(zhuǎn)的網(wǎng)址,# url 可以不給,用 pattern_name 和 get_redirect_url() 函數(shù) 來解析到要跳轉(zhuǎn)的網(wǎng)址 permanent = False #是否為永久重定向, 默認(rèn)為 Falsequery_string = True # 是否傳遞GET的參數(shù)到跳轉(zhuǎn)網(wǎng)址,True時會傳遞,默認(rèn)為 Falsepattern_name = 'article-detail' # 用來跳轉(zhuǎn)的 URL, 看下面的 get_redirect_url() 函數(shù)# 如果url沒有設(shè)定,此函數(shù)就會嘗試用pattern_name和從網(wǎng)址中捕捉的參數(shù)來獲取對應(yīng)網(wǎng)址# 即 reverse(pattern_name, args) 得到相應(yīng)的網(wǎng)址,def get_redirect_url(self, *args, **kwargs):article = get_object_or_404(Article, pk=kwargs['pk'])article.update_counter() # 更新文章點(diǎn)擊數(shù),在models.py中實現(xiàn)return super(ArticleCounterRedirectView, self).get_redirect_url(*args, **kwargs)

RedirectView源碼:

class RedirectView(View):"""Provide a redirect on any GET request."""permanent = Falseurl = Nonepattern_name = Nonequery_string = Falsedef get_redirect_url(self, *args, **kwargs):"""Return the URL redirect to. Keyword arguments from the URL patternmatch generating the redirect request are provided as kwargs to thismethod."""if self.url:url = self.url % kwargselif self.pattern_name:url = reverse(self.pattern_name, args=args, kwargs=kwargs)else:return Noneargs = self.request.META.get('QUERY_STRING', '')if args and self.query_string:url = "%s?%s" % (url, args)return urldef get(self, request, *args, **kwargs):url = self.get_redirect_url(*args, **kwargs)if url:if self.permanent:return HttpResponsePermanentRedirect(url)else:return HttpResponseRedirect(url)else:logger.warning('Gone: %s', request.path,extra={'status_code': 410, 'request': request})return HttpResponseGone()def head(self, request, *args, **kwargs):return self.get(request, *args, **kwargs)def post(self, request, *args, **kwargs):return self.get(request, *args, **kwargs)def options(self, request, *args, **kwargs):return self.get(request, *args, **kwargs)def delete(self, request, *args, **kwargs):return self.get(request, *args, **kwargs)def put(self, request, *args, **kwargs):return self.get(request, *args, **kwargs)def patch(self, request, *args, **kwargs):return self.get(request, *args, **kwargs) View Code

看完應(yīng)該就會一目了然。

path('', RedirectView.as_view(pattern_name='backend:index')),

?

?

通用顯示視圖

ListView

繼承關(guān)系:

?

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

class StudentList(ListView):model = models.Student # orm的modeltemplate_name = 'student_list.html' # 要返回的模版文件context_object_name = 'student_obj' # orm數(shù)據(jù)實例化對象,前端調(diào)用的名稱extra_context = {'name': 'dandy'} # 額外的上下文數(shù)據(jù)信息def get(self, request, *args, **kwargs): # 重寫get方法response = super().get(request, *args, **kwargs)return responsedef get_context_data(self, *, object_list=None, **kwargs): # 重寫get_context_data方法context = super().get_context_data(**kwargs) # 拿到返回值context并更新或者擴(kuò)充context['num'] = 11return contextdef get_queryset(self):# query_set = super().get_queryset()# query_set = super().get_queryset()[:1]self.kwargs['name'] = 'dandy'cate = get_object_or_404(models.Student, name=self.kwargs.get('name'))return super().get_queryset().filter(name=cate)

上面有一個參數(shù)沒有設(shè)計到:

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

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

所以上面的這一句篩選跟上面的get_queryset自定義的篩選,其實差不多。

context_object_name

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

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

看一下模版內(nèi):

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body><h3>{{ name }}</h3><table><thead><td>姓名</td><td>年齡</td></thead><tbody>{% for student in student_obj %}<tr><td>{{ student.name }}</td><td>{{ student.age }}</td></tr>{% endfor %}</tbody></table><br><h2>{{ num }}</h2> </body> </html> View Code

?

?

DetailView

繼承關(guān)系:

?

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

class StudentDetailView(DetailView):model = models.Student # orm的modeltemplate_name = 'student_detail.html' # 調(diào)用的模版文件context_object_name = 'aaa' # 模版文件里面對應(yīng)的orm數(shù)據(jù)對象的名稱def get(self, request, *args, **kwargs):response = super().get(request, *args, **kwargs) # 同樣的重寫的方法可以做一些自定義,比如訪問量+1等等的return responsedef get_object(self):obj = super().get_object()return obj # 這里的obj其實已經(jīng)是指向一條數(shù)據(jù)了;比如一篇文章,可以進(jìn)行一些修改之類的操作,obj.aa = 'dandy', obj.save()def get_context_data(self, **kwargs):context = super().get_context_data(**kwargs) # 重寫,獲取返回數(shù)據(jù)classes = self.object.classes_set.all() # 反向獲取所有關(guān)聯(lián)數(shù)據(jù)context.update({ # 添加新的上下文信息'classes': classes,'test_name': 'dandy'})return context

這里需要注意的是url,因為明確表面了這個通用視圖的目的,所以url固定的指向了某個具體的事物的id

path('detailview/<int:pk>/', views.StudentDetailView.as_view(), name='student_detail'),

?

內(nèi)部形成處理。

默認(rèn)情況下,DetailView 使用<appname>/<model name>_detail.html的模板,如果沒有該模板,則應(yīng)該通過”template_name”指定一個模板。

?

轉(zhuǎn)載于:https://www.cnblogs.com/wuzdandz/p/9448310.html

總結(jié)

以上是生活随笔為你收集整理的Python Django CBV下的通用视图函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。