您好,登錄后才能下訂單哦!
?
目錄
django.views.generic.TemplateView.. 1
django.views.generic.View.. 2
類的繼承和覆蓋:... 5
自定義LoginRequiredMixin:... 5
通用視圖:... 6
django.views.generic.ListView.. 6
django.views.generic.DetailView.. 8
django.views.generic.FormView:... 9
django.views.generic.CreateView:... 9
django.views.generic.UpdateView:... 9
?
?
?
cbv,class based view:
基于類的視圖,使編寫view更簡潔,有復雜的繼承關系;
?
CBV和FBV兩者各有優劣;
?
?
?
?
?
UML圖;
Mixin增強功能,提供一些方法,如TemplateResponseMixin提供了render_to_response()渲染模板,ContextMixin提供get_context_data();
View提供get,post訪問入口;
?
?
例,ver1:
def about(request):?? #ver1,FBV用法
??? return render(request, 'blog/about.html')
?
url(r'^about/', views.about, name='about'),
?
?
例,ver2:
from django.views.generic import TemplateView
?
app_name = 'blog'
?
urlpatterns = [
??? url(r'^$', views.index, name='index'),
??? url(r'^login/', views.auth_login, name='login'),
??? url(r'^logout/', views.auth_logout, name='logout'),
??? # url(r'^about/', views.about, name='about'),
??? url(r'^about/', TemplateView.as_view(template_name='blog/about.html')),?? #ver2,CBV用法1
]
?
?
例,ver3:
from django.views.generic import TemplateView
?
class AboutView(TemplateView):?? #ver3,CBV用法2
template_name = 'blog/about.html'
?
?
url(r'^about/', AboutView.as_view()),
?
?
?
View源碼:
該類在沒更改原來django邏輯的情況下,可用于編寫view,每個http請求會使用對應類的同名的方法進行處理;
class View(object):
??? """
??? Intentionally simple parent class for all views. Only implements
??? dispatch-by-method and simple sanity checking.
??? """
?
??? http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
?
??? def __init__(self, **kwargs):?? #檢查as_view()傳入的參數是否在類中定義
??????? """
??????? Constructor. Called in the URLconf; can contain helpful extra
??????? keyword arguments, and other things.
??????? """
??????? # Go through keyword arguments, and either save their values to our
??????? # instance, or raise an error.
??????? for key, value in six.iteritems(kwargs):
??????????? setattr(self, key, value)
?
@classonlymethod
??? def as_view(cls, **initkwargs):?? #返回的是一個函數對象(裝飾器);template_name=’blog/about.html’模板名作為參數傳,或在類屬性中定義,傳入的參數可覆蓋類中定義的屬性
??????? """
??????? Main entry point for a request-response process.
??????? """
??????? for key in initkwargs:
??????????? if key in cls.http_method_names:
??????????????? raise TypeError("You tried to pass in the %s method name as a "
??????????????????????????????? "keyword argument to %s(). Don't do that."
??????????????????????? ????????% (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)
??????????? if hasattr(self, 'get') and not hasattr(self, 'head'):
??????????????? self.head = self.get
??????????? self.request = request
??????????? self.args = args
??????????? self.kwargs = kwargs
??????????? 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
?
??? def dispatch(self, request, *args, **kwargs):?? #根據用戶的request method路由到get、post方法
??????? # Try to dispatch to the right method; if a method doesn't exist,
??????? # defer to the error handler. Also defer to the error handler if the
??????? # request method isn't on the approved list.
???? ???if request.method.lower() in self.http_method_names:
??????????? handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
??????? else:
??????????? handler = self.http_method_not_allowed
??????? return handler(request, *args, **kwargs)
?
??? def http_method_not_allowed(self, request, *args, **kwargs):
??????? logger.warning(
??????????? 'Method Not Allowed (%s): %s', request.method, request.path,
??????????? extra={'status_code': 405, 'request': request}
??????? )
??????? return http.HttpResponseNotAllowed(self._allowed_methods())
?
??? def options(self, request, *args, **kwargs):
??????? """
??????? Handles responding to requests for the OPTIONS HTTP verb.
??????? """
??????? response = http.HttpResponse()
??????? response['Allow'] = ', '.join(self._allowed_methods())
??????? response['Content-Length'] = '0'
??????? return response
?
??? def _allowed_methods(self):
??????? return [m.upper() for m in self.http_method_names if hasattr(self, m)]
?
?
例,ver1,FBV:
def my_view(request):
??? if request.method == 'GET':
??????? return HttpResponse('get it')
??? elif request.method == 'POST':
??????? return HttpResponse('post it')
??? elif request.method == 'HEAD':
??????? return HttpResponse('head it')
?
?
例,ver2,CBV,省去了if判斷:
?
from django.views.generic import View
?
class MyView(View):
?
??? def get(self, request):
??????? return HttpResponse('get it')
?
??? def post(self, request):
??????? return HttpResponse('post it')
?
??? def head(self, request):
??????? return HttpResponse('head it')
?
?
??? # url(r'^myview', views.my_view),
??? url(r'^myview', MyView.as_view()),
?
?
?
class GreetingView(View):
??? greeting = 'good day'
??? def get(self, request):
??????? return HttpResponse(self.greeting)
?
class MorningGreetingView(GreetingView):
??? greeting = 'morning to yo'
?
?
?
?
class LoginRequiredMixin:
??? @classmethod
??? def as_view(cls, **initkwargs):
??????? view = super(LoginRequiredMixin, cls).as_view(**initkwargs)
??????? return login_required(view)
???
class MyView(LoginRequiredMixin, View):
??? pass
?
?
裝飾類:
from django.utils.decorators import method_decorator
?
class ProtectedView(TemplateView):
??? template_name = 'blog/about.html'
???
??? @method_decorator(login_required)
??? def dispatch(self, *args, **kwargs):
??????? return super(ProtectedView, self).dispatch(*args, **kwargs)
?
?
?
?
generic class based view和class based view概念上不是一回事;
class based view是用類的方式寫view;
generic class based view是用class based view方式將常用的CRUD封裝成可擴展的類,使用時直接繼承,快速實現;
?
?
?
多對象;
默認提供的上下文是object_list,也可用context_object_name指定;
queryset、get_queryset、model;
可指定template_name;
?
?
例,ver1:
def publisher_list(request):
??? publishers = Publisher.objects.all()
??? return render(request, 'books/publishers.html', {'publishers': publishers})
?
例,ver2:
from django.views.generic import ListView
?
class PublisherList(ListView):?? #默認去找suffix為list的模板,即publisher_list.html;publisher_list.html模板;默認的context為object_list
??? model = Publisher?? #返回Publisher.object.all(),多對象
??? # template_name = 'books/publishers.html'?? #
???????? # context_object_name =??? #提供上下文
???????? # queryset = Publisher.objects.all()?? #model|queryset|get_queryset()三者關系
???????? # def get_queryset(self):
???????? #?????? return Publisher.objects.all()
?
?
<body>
??? <ul>
??????? {% for publisher in object_list %}
??????? <h4>{{ publisher }}</h4>
??????? {% endfor %}
??? </ul>
</body>
?
?
??? # url(r'^$', views.publisher_list, name='publishers'),
??? url(r'^$', PublisherList.as_view(), name='publisher'),
?
?
?
單個對象的詳情;
get_context_data();
context_object_name;
?
?
<body>
??? <ul>
??????? <h4>{{ publisher }}</h4>
??????? {% for book in book_list %}
??????? {{ book }}<br/>
??????? {{ book.publisher }}
??????? {% endfor %}
??? </ul>
</body>
?
?
from django.views.generic import DetailView
from .models import Book
?
class PublisherDetail(DetailView):
??? model = Publisher
??? context_object_name = 'publisher'
?
??? def get_context_data(self, **kwargs):
??????? context = super(PublisherDetail, self).get_context_data(**kwargs)
??????? context['book_list'] = Book.objects.all()
??????? return context
?
?
??? url(r'^$', PublisherList.as_view(), name='publisher'),
??? url(r'^(?P<pk>[0-9]+)/$', PublisherDetail.as_view()),
?
?
?
class PublisherForm(forms.Form):
??? name = forms.CharField(label=_('Your name'), max_length=30)
??? address = forms.CharField(max_length=50)
??? city = forms.CharField(max_length=60)
??? state_province = forms.CharField(max_length=30)
??? country = forms.CharField(max_length=20)
??? website = forms.CharField(max_length=50)
?
??? def send_mail(self):
??????? print('~~~~~~~~~~~send_mail()?? OK')
?
?
from django.views.generic import FormView
?
class PublisherView(FormView):
??? form_class = PublisherForm
??? template_name = 'books/books_add.html'
??? success_url = '/books/'
?
??? def form_valid(self, form):
??????? form.send_mail()
??????? return super(PublisherView, self).form_valid(form)
?
?
??? url(r'^$', PublisherList.as_view(), name='publisher'),
url(r'^add', PublisherView.as_view()),
?
?
?
根據model和fields動態構建form,另form_class = forms.AuthorForm等價于model和fields;
model + fields = form_class,另get_form_class、get_form;
template_name,不指定默認找suffix為_form.html;
success_url,get_success_url;
form_valid()、form_invalid(),注意重寫都要調用父類方法;
get_context_data;
success_message、get_success_message;
?
?
from django.views.generic import CreateView
from .models import Author
?
class AuthorCreate(CreateView):
??? model = Author
??? fields = ['first_name', 'last_name', 'email']
??? success_url = '/books/'
?
??? def form_valid(self, form):
??????? return super().form_valid(form)
?
??? def get_context_data(self, **kwargs):
??????? context = {'extra': 'some context'}
??????? kwargs.update(context)
??????? return super().get_context_data(**kwargs)
?
?
??? url(r'^author/', AuthorCreate.as_view()),
?
?
?
?
?
要有刪除確認頁面;
?
?
?
?
?
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。