您的位置:首页 > 编程语言 > Go语言

Django基于类的编辑视图和Mixins

2016-03-18 11:32 525 查看
== 内建的基于类的通用编辑视图 (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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: