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来处理多个相关模型的字段。通过这些知识,我们可以更加高效地创建和更新对象的表单,并满足复杂的数据关联需求。
极客笔记