Template View
doc: base.py
- View: Intentionally simple parent class for all views. Only implements dispatch-by-method and simple sanity checking.
- TemplateView: Render a template. Pass keyword arguments from the URL conf to the context
- TemplateResponseMixin: A mixin that can be used to render a template
- ContextMixin: A default context mixin that passes the keyword arguments received by get_context_data() as the template context
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# views.py from django.views.generic import View from django.views.generic.base import TemplateView, TemplateResponseMixin, ContextMixin class TempView(TemplateView): template_name = 'template.html' def get_context_data(self, **kwargs): context = super(TempView, self).get_context_data(**kwargs) context['title'] = 'THIS IS A TEMPLATE VIEW.' return context class AnotherTempView(ContextMixin, TemplateResponseMixin, View): def get(self, *args, **kwargs): context = self.get_context_data(**kwargs) context['title'] = 'THIS IS ANOTHER TEMPLATE VIEW.' return self.render_to_response(context) # urls.py from .views import TempView, AnotherTempView urlpatterns = [ url(r'^temp1/$', TempView.as_view(), name='temp1'), url(r'^temp2/$', AnotherTempView.as_view(template_name='template.html'), name='temp2') ] |
Custom Mixin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# Solution A class AnotherTempView(ContextMixin, TemplateResponseMixin, View): template_name = 'cbv/template.html' def get(self, *args, **kwargs): context = self.get_context_data(**kwargs) context['title'] = 'THIS IS ANOTHER TEMPLATE VIEW.' return self.render_to_response(context) def post(self): pass """當服務端使用cbv模式的時候,使用者發給服務端的請求包含url和method,這兩個資訊都是字串型別,服務端通過 路由對映表匹配成功後會自動去找dispatch方法,然後Django會通過dispatch反射的方式找到類中對應的方法並執行 類中的方法執行完畢之後,會把客戶端想要的資料返回給dispatch方法,由dispatch方法把資料返回經客戶端 """ @method_decorator(login_required) def dispatch(self, request, *args, **kwargs): return super(AnotherTempView, self).dispatch(request, *args, **kwargs) # Solution B class LoginRequiredMixin(object): @classmethod def as_view(cls, **kwargs): view = super(LoginRequiredMixin, cls).as_view(**kwargs) return login_required(view) class AnotherTempView(LoginRequiredMixin, ContextMixin, TemplateResponseMixin, View): template_name = 'cbv/template.html' def get(self, *args, **kwargs): context = self.get_context_data(**kwargs) context['title'] = 'THIS IS ANOTHER TEMPLATE VIEW.' return self.render_to_response(context) def post(self): pass |
Generic display views: Detail View
1 2 3 4 5 6 |
from django.views.generic.detail import DetailView from .models import Book class BookDetail(DetailView): template_name = 'template.html' model = Book |
Reverse
1 2 3 4 5 6 7 8 9 10 |
# urls.py urlpatterns = [ url(r'^cbv/', include('cbv.urls', namespace='cbv')) ] # cbv/views.py from django.core.urlresolvers import reverse class Book(models.Model): def get_absolute_url(self): return reverse('cbv:book_detail', kwargs={'id': self.id}) |
Generic display views: Create View
1 2 3 4 5 6 7 8 9 10 11 12 |
class BookCreate(CreateView): template_name = 'form.html' model = Book form_class = BookForm # fields = ['title', 'description'] def form_valid(self, form): form.instance.added_by = self.request.user return super(BookCreate, self).form_valid(form) def get_success_url(self): return reverse('cbv:book_list') |
Handle MultipleObjectReturned
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class MultipleObjectMixin(obj): def get_object(self, queryset=None, *args, **kwargs): slug = self.kwargs.get('slug') if slug: try: obj = self.model.objects.get(slug=slug) except self.model.MultipleObjectReturned: obj = self.get_queryset().first() except: raise Http404 return obj return None class BookDetail(MultipleObjectMixin, DetailView): template_name = 'detail.html' model = Book |
SuccessMessageMixin
1 2 3 4 5 6 7 8 9 10 11 12 |
from django.contrib.messages.views import SuccessMessageMixin class BookCreate(SuccessMessageMixin, CreateView): template_name = 'cbv/form.html' model = Book success_message = "%(title)s was created at %(created_at)s" def get_success_message(self, cleaned_data): return self.success_message % dict( cleaned_data, created_at=self.object.timestamp ) |
FormMixin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# views.py from django.views.generic.edit import ModelFormMixin class BookDetail(ModelFormMixin, DetailView): template_name = 'detail.html' model = Book form_class = BookForm def get_context_data(self, *args, **kwargs): context = super(BookDetail, self).get_context_data(*args, **kwargs) context['form'] = self.get_form() context['btn_title'] = 'Update Book' return context def post(self, request, *args, **kwargs): form = self.get_form() if form.is_valid(): return self.form_valid(form) else: return self.form_invalid(form) # detail.html {% include "form.html" with form=form title="Detail View" btn_title=btn_title %} # form.html {% if title %} <h1>{{ title }}</h1> {% endif %} <form method='POST' action=""> {% csrf_token %} {{ form }} <input class="btn btn-default" type="submit" value='{% if btn_title %}{{ btn_title }}{% else %}Submit{% endif %}'> </form> |