转载:Django基于类的编辑视图和Mixin
== 内建的基于类的通用编辑视图 (Forms)
表单(处理)通常包含3条路径:
* 初始的GET (空或预填充的表单)
* 非法数据的POST (通常重新显示表单并提示错误)
* 合法数据的POST (处理数据并通常重定向)
你自己实现这些常常需要重复很多模式化的代码。帮助避免这些,Django提供了一系列通用的基于类的视图用于表单处理。
- 基本表单
# forms.py
from django import forms
class ContactForm(forms.Form):
name = forms.CharField()
message = forms.CharField(widget=forms.Textarea)
def send_email(self):
# send email using the self.cleaned_data dictionary
pass
# views.py
from myapp.forms import ContactForm
from django.views.generic.edit import FormView
class ContactView(FormView):
template_name = 'contact.html'
form_class = ContactForm
success_url = '/thanks/'
def form_valid(self, form):
# 当合法form数据被POST时,此方法被调用。
# 它应当返回一个HttpResponse.
form.send_email()
return super(ContactView, self).form_valid(form)
- Model表单
通用视图将自动创建ModelForm, 依据下列规则:
* 如果给出model属性,其model类将被使用
* 如果get_object()返回一个对象,此对象的类被使用
* 如果给出queryset,则queryset的model被使用
Model form视图提供了一个form_valid()实现,自动保存model对象。你可以根据自己的需要重写它。
对于CreateView或UpdateView,你甚至不需要提供一个success_url, 它们将使用model对象的get_absolute_url(),如果可用。
如果你需要自定义ModelForm(例如,增加校验),只需要在你的视图(view)中设置form_class, *还必须设置model.
# models.py
from django.core.urlresolvers import reverse
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=200)
def get_absolute_url(self):
return reverse('author-detail', kwargs={'pk': self.pk})
# views.py
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.core.urlresolvers import reverse_lazy
from myapp.models import Author
class AuthorCreate(CreateView):
model = Author
fields = ['name']
class AuthorUpdate(UpdateView):
model = Author
fields = ['name']
class AuthorDelete(DeleteView):
model = Author
success_url = reverse_lazy('author-list')
# urls.py
from django.conf.urls import url
from myapp.views import AuthorCreate, AuthorUpdate, AuthorDelete
urlpatterns = [
url(r'author/add/$', AuthorCreate.as_view(), name='author-add'),
url(r'author/(?P<pk>[0-9]+)/$', AuthorUpdate.as_view(), name='author-update'),
url(r'author/(?P<pk>[0-9]+)/delete/$', AuthorDelete.as_view(), name='author-delete'),
]
- Models 和 request.user
为跟踪使用CreateView创建某对象的用户,你可以自定义一个ModelForm.
# models.py
class Author(models.Model):
name = models.CharField(max_length=200)
created_by = models.ForeignKey(User)
# views.py
class AuthorCreate(CreateView):
model = Author
fields = ['name']
def form_valid(self, form):
form.instance.created_by = self.request.user
return super(AuthorCreate, self).form_valid(form)
- AJAX 用例
from django.http import JsonResponse
from django.views.generic.edit import CreateView
from myapp.models import Author
class AjaxableResponseMixin(object):
"""
Mixin用于为form增加AJAX支持。
必须用于基于类的FormView(如,CreateView), 即用于编辑视图
"""
def form_invalid(self, form):
response = super(AjaxableResponseMixin, self).form_invalid(form)
if self.request.is_ajax():
return JsonResponse(form.errors, status=400)
else:
return response
def form_valid(self, form):
# 我们需要确保调用父类的form_valid()方法,因为它可能会做一些处理
# (在CreateView的例子中,它将调用form.save())
response = super(AjaxableResponseMixin, self).form_valid(form)
if self.request.is_ajax():
data = {
'pk': self.object.pk,
}
return JsonResponse(data)
else:
return response
class AuthorCreate(AjaxableResponseMixin, CreateView):
model = Author
fields = ['name']
== 在基于类的视图中使用Mixins
https://docs.djangoproject.com/en/1.8/ref/class-based-views/mixins/
- 内容及模板响应
TemplateResponseMixin
ContextMixin
- 构建Django的通用基于类的视图
DetailView: working with a single Django object
#To get the object, DetailView relies on SingleObjectMixin
#To then make a TemplateResponse, DetailView uses SingleObjectTemplateResponseMixin
ListView: working with many Django objects
#To get the objects, ListView uses MultipleObjectMixin
#To make a TemplateResponse, ListView then uses MultipleObjectTemplateResponseMixin
- 使用Django的基于类视图的Mixins
Using SingleObjectMixin with View
Using SingleObjectMixin with ListView
- 避免更复杂
Using FormMixin with DetailView
A better solution
An alternative better solution
- 不限于HTML
from django.http import JsonResponse
class JSONResponseMixin(object):
"""
A mixin that can be used to render a JSON response.
"""
def render_to_json_response(self, context, **response_kwargs):
"""
Returns a JSON response, transforming 'context' to make the payload.
"""
return JsonResponse(
self.get_data(context),
**response_kwargs
)
def get_data(self, context):
"""
Returns an object that will be serialized as JSON by json.dumps().
"""
# Note: This is *EXTREMELY* naive; in reality, you'll need
# to do much more complex handling to ensure that arbitrary
# objects -- such as Django model instances or querysets
# -- can be serialized as JSON.
return context
from django.views.generic import TemplateView
class JSONView(JSONResponseMixin, TemplateView):
def render_to_response(self, context, **response_kwargs):
return self.render_to_json_response(context, **response_kwargs)
————————————————
版权声明:本文为CSDN博主「lzx1104」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lzx1104/java/article/details/50921867