Gra*_*ntU 26 django django-models django-views django-class-based-views
假设我想创建一个基于类的视图,它既可以更新也可以创建一个对象.根据我之前提出的问题,我可以做以下事情之一:
1)使用2周通用的观点CreateView和UpdateView我认为将意味着有两个网址指向两个不同的类.
2)使用继承base的基于类的视图View,我认为这意味着有两个URL指向只有1个类(我创建了哪个继承View).
我有两个问题:
a)哪个更好?
b)ccbv.co.uk显示了一个基础View,但我没有看到记录的任何get,post等方法,这是正确的吗?
scu*_*dha 45
我遇到了一个我想要这样的事情.这是我想出的(请注意,如果您尝试将其用作更新视图并且无法找到所请求的对象,则它将表现为创建视图而不是抛出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)
Run Code Online (Sandbox Code Playgroud)
事实证明,UpdateView并且CreateView从完全相同的类和mixin继承.唯一的区别在于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'
Run Code Online (Sandbox Code Playgroud)
如您所见,CreateView get和post方法在设置self.object = None时UpdateView设置self.get_object().我所做的就是在我的CreateUpdateView.get_object方法中将这两个结合起来,它试图调用父类' get_object并返回None而不是在没有对象的情况下引发异常.
要在用作更新视图时提供404页面,您可以覆盖as_view并传递一个update_only布尔参数.如果update_only是True,并且视图找不到该对象,则提高404.
Pao*_*rre 10
就像@scubabuddha所建议的那样,我遇到了类似的情况,我在他的评论中使用了@ mario-orlandi修改后的答案:
from django.views.generic import UpdateView
class CreateUpdateView(UpdateView):
def get_object(self, queryset=None):
try:
return super().get_object(queryset)
except AttributeError:
return None
Run Code Online (Sandbox Code Playgroud)
我在Django 1.11中使用了这个解决方案,但我认为它可以在Django 2.0中使用.
我确认这个解决方案适用于Django 2.0和2.1.
小智 7
所有链接中最简单且基本上是最佳的解决方案
class WorkerUpdate(UpdateView):
form_class = WorkerForm
def get_object(self, queryset=None):
# get the existing object or created a new one
obj, created = Worker.objects.get_or_create(mac=self.kwargs['mac'])
return obj
Run Code Online (Sandbox Code Playgroud)
就是这样,谢谢@chriskief
为什么需要通过单个View处理创建和更新?拥有两个单独的视图要简单得多,每个视图都从其各自的通用视图类继承.如果您愿意,他们可以共享相同的表单和模板,并且他们最有可能来自不同的URL,所以我看不到将它变成单个视图会得到什么.
所以:使用两种观点,从一个继承CreateView和其他UpdateView.这些可以处理您可能需要的所有内容,而第二种方法则需要您自己重新发明轮子.如果情况下,当您有使用这两种创建或更新对象时,使用一个混合的选项,也可以或许创建自己的观点,即涵盖了使用情况,从两个继承一些常见的"看家"的代码CreateView和UpdateView.
| 归档时间: |
|
| 查看次数: |
13851 次 |
| 最近记录: |