こういうものが欲しくなる場面に出くわしました。これが私が思いついたものです(更新ビューとして使用しようとしていて、要求されたオブジェクトが見つからない場合、404をスローするのではなく、作成ビューとして動作することに注意してください):
from django.views.generic.detail import SingleObjectTemplateResponseMixin
from django.views.generic.edit import ModelFormMixin, ProcessFormView
class CreateUpdateView(
SingleObjectTemplateResponseMixin, ModelFormMixin, ProcessFormView
):
def get_object(self, queryset=None):
try:
return super(CreateUpdateView,self).get_object(queryset)
except AttributeError:
return None
def get(self, request, *args, **kwargs):
self.object = self.get_object()
return super(CreateUpdateView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
return super(CreateUpdateView, self).post(request, *args, **kwargs)
まったく同じクラスと mixinUpdateView
を継承していることがわかりました。CreateView
唯一の違いは、get/post メソッドにあります。Django ソース (1.8.2) で定義されている方法は次のとおりです。
class BaseCreateView(ModelFormMixin, ProcessFormView):
"""
Base view for creating an new object instance.
Using this base class requires subclassing to provide a response mixin.
"""
def get(self, request, *args, **kwargs):
self.object = None
return super(BaseCreateView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.object = None
return super(BaseCreateView, self).post(request, *args, **kwargs)
class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView):
"""
View for creating a new object instance,
with a response rendered by template.
"""
template_name_suffix = '_form'
class BaseUpdateView(ModelFormMixin, ProcessFormView):
"""
Base view for updating an existing object.
Using this base class requires subclassing to provide a response mixin.
"""
def get(self, request, *args, **kwargs):
self.object = self.get_object()
return super(BaseUpdateView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
return super(BaseUpdateView, self).post(request, *args, **kwargs)
class UpdateView(SingleObjectTemplateResponseMixin, BaseUpdateView):
"""
View for updating an object,
with a response rendered by template.
"""
template_name_suffix = '_form'
ご覧のとおり、CreateView の get メソッドと post メソッドが設定されself.object = None
、 が にUpdateView
設定されていself.get_object()
ます。私が行ったのは、オブジェクトがない場合に例外を発生させるのではなくCreateUpdateView.get_object
、親クラスを呼び出そうとするメソッドでこれら2つを組み合わせてget_object
返すことだけです。None
更新ビューとして使用するときに 404 ページを提供するには、おそらくオーバーライドしてブール値の引数as_view
を渡すことができます。であり、ビューがオブジェクトを見つけられないupdate_only
場合は、404 を発生させます。update_only
True