假设我想创建一个基于类的 View ,它既更新又创建一个对象。来自 previous question我发现我可以做以下事情之一:
1) 使用 2 个通用 View CreateView
和 UpdateView
,我认为这意味着有两个 URL 指向两个不同的类。
2) 使用继承基础 View
的基于类的 View ,我认为这意味着有两个 URL 指向仅 1 个类(我创建的继承 View
)。
我有两个问题:
a) 哪个更好?
b) ccbv.co.uk显示了一个基本的 View
,但我没有看到任何 get、post 等方法的文档,这是正确的吗?
最佳答案
我遇到了我想要这样的东西的情况。这是我想出的(请注意,如果您尝试将其用作更新 View 并且找不到请求的对象,它将表现为创建 View 而不是抛出 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)
事实证明,UpdateView
和 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
方法中结合这两者,该方法尝试调用父类的 get_object
并返回 None
而不是如果没有对象则引发异常。
要在用作更新 View 时提供 404 页面,您可能可以覆盖 as_view
并向其传递一个 update_only
bool 参数。如果 update_only
为 True
并且 View 找不到该对象,则引发 404。
关于用于创建和更新的基于 Django 类的 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17192737/