Django 基于类的CreateView和UpdateView,使用多个内联formsets
在本文中,我们将介绍Django中基于类的CreateView
和UpdateView
视图,并讨论如何在表单中使用多个内联formsets
。
阅读更多:Django 教程
什么是CreateView和UpdateView?
CreateView
和UpdateView
是Django中基于类的视图,用于处理创建和更新对象的表单。它们为我们提供了一个快速而简洁的方式来创建和更新模型实例。
CreateView
负责处理创建新的模型实例,而UpdateView
负责处理更新现有的模型实例。它们内置了一套标准操作,使得我们可以轻松地处理表单验证、渲染和重定向。
使用CreateView和UpdateView
首先,我们需要导入CreateView
和UpdateView
视图类以及相关的模型和表单。
from django.views.generic.edit import CreateView, UpdateView
from .models import MyModel
from .forms import MyModelForm
接下来,我们定义一个派生自CreateView
或UpdateView
的视图类,并设置相关的属性。
class MyCreateView(CreateView):
model = MyModel
form_class = MyModelForm
template_name = 'my_app/my_model_form.html'
class MyUpdateView(UpdateView):
model = MyModel
form_class = MyModelForm
template_name = 'my_app/my_model_form.html'
pk_url_kwarg = 'pk'
注意,我们需要指定模型(model
)、表单类(form_class
)和模板名称(template_name
)等属性。在UpdateView
中,还需要设置pk_url_kwarg
以指定主键的命名参数。
然后,我们可以在模板中使用这些视图类,并进行必要的渲染和表单处理。例如,我们可以创建一个表单模板my_model_form.html
,并在其中渲染表单字段。
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="保存">
</form>
在视图中,我们还可以定义其他方法来处理表单验证、保存对象和重定向。
class MyCreateView(CreateView):
# ...
def form_valid(self, form):
# 表单验证通过时的处理逻辑
return super().form_valid(form)
def get_success_url(self):
# 保存成功后的重定向URL
return reverse('my_model_list')
使用内联formsets
有时候,我们需要在表单中包含多个相关模型的字段。在这种情况下,我们可以使用Django的内联formsets
来处理这些字段。
首先,我们需要导入相关的formsets
类。
from django.forms.models import inlineformset_factory
然后,我们需要定义每个模型的表单类和内联formset
。
MyRelatedModelFormSet = inlineformset_factory(
MyModel, MyRelatedModel, fields=('field1', 'field2'))
这里,我们使用inlineformset_factory
函数创建一个内联formset
,指定了相关模型、关联字段和需要包含的字段列表。
接下来,我们可以将内联formset
添加到我们的CreateView
和UpdateView
中。
class MyCreateView(CreateView):
model = MyModel
form_class = MyModelForm
template_name = 'my_app/my_model_form.html'
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
if self.request.POST:
data['formset'] = MyRelatedModelFormSet(self.request.POST, instance=self.object)
else:
data['formset'] = MyRelatedModelFormSet(instance=self.object)
return data
def form_valid(self, form):
context = self.get_context_data()
formset = context['formset']
if formset.is_valid():
self.object = form.save()
formset.instance = self.object
formset.save()
return super().form_valid(form)
else:
return self.render_to_response(self.get_context_data(form=form))
class MyUpdateView(UpdateView):
model = MyModel
form_class = MyModelForm
template_name = 'my_app/my_model_form.html'
pk_url_kwarg = 'pk'
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
if self.request.POST:
data['formset'] = MyRelatedModelFormSet(self.request.POST, instance=self.object)
else:
data['formset'] = MyRelatedModelFormSet(instance=self.object)
return data
def form_valid(self, form):
context = self.get_context_data()
formset = context['formset']
if formset.is_valid():
self.object = form.save()
formset.instance = self.object
formset.save()
return super().form_valid(form)
else:
return self.render_to_response(self.get_context_data(form=form))
上述代码中,我们在get_context_data
方法中获取表单和内联formset
的上下文数据。在POST
请求中,我们使用传入的数据和MyModel
的实例来初始化formset
;而在GET
请求中,我们只使用MyModel
的实例来初始化formset
。这样,我们就可以在模板中渲染和处理表单和内联formset
了。
在form_valid
方法中,首先我们验证formset
是否有效。如果有效,我们保存form
和内联formset
的实例,然后调用super().form_valid(form)
来完成表单的保存和重定向。如果formset
无效,我们重新渲染表单和formset
,并将无效的表单传递给模板。
总结
本文介绍了Django中基于类的CreateView
和UpdateView
视图,并讨论了如何在表单中使用多个内联formsets
。我们了解了这些视图类的基本用法,并学习了如何在模板中渲染表单字段和处理表单验证和重定向。最后,我们探讨了如何使用内联formsets
来处理多个相关模型的字段。通过这些知识,我们可以更加高效地创建和更新对象的表单,并满足复杂的数据关联需求。