我有一个Django表单向导,可以很好地创建我的某个模型的内容。我想使用相同的向导来编辑现有内容的数据,但无法找到如何执行此操作的良好示例。
以下是我的项目代码的简化版本:
forms.py
class ProjectEssentialsForm(forms.ModelForm):
class Meta:
model = Project
fields = [
'title',
'short_description',
'who_description',
'problem_description',
'solution_description'
]
class ProjectYourInfoForm(forms.ModelForm):
class Meta:
model = Project
fields = [
'gender',
'location',
'post_code',
'sector',
]
views.py
TEMPLATES = {
'project_essentials': 'projects/essentials-form.html',
'project_your_info': 'projects/your-info-form.html',
}
class ProjectWizard(SessionWizardView):
instance = None
def get_form_instance(self, step):
"""
Provides us with an instance of the Project Model to save on completion
"""
if self.instance is None:
self.instance = Project()
return self.instance
def done(self, form_list, **kwargs):
"""
Save info to the DB
"""
project = self.instance
project.save()
def get_template_names(self):
"""
Custom templates for the different steps
"""
return [TEMPLATES[self.steps.current]]
urls.py
FORMS = [
('project_essentials', ProjectEssentialsForm),
('project_your_info', ProjectYourInfoForm),
]
urlpatterns = patterns('',
(r'^projects/add$', ProjectWizard.as_view(FORMS)),
)
我看到有这个函数https://docs.djangoproject.com/en/dev/ref/contrib/formtools/form-wizard/#django.contrib.formtools.wizard.views.WizardView.get_form_instance用于设置表单实例,但是我不确定如何获取模型ID来进行查找以及代码的确切方式会工作的。
最受欢迎的是代码示例或指向其中的链接。
谢谢, 皮特
答案 0 :(得分:11)
我刚刚完成了这项工作,所以如果有人帮助别人,我会发布答案。
您可以在urls.py中传递您要修改的项目的ID,如下所示:
(r'^projects/edit/(?P<project_id>[-\d]+)$', ProjectWizard.as_view(FORMS)),
然后,您可以使用
中的以下代码查找该项目views.py:
class ProjectWizard(SessionWizardView):
def get_form_initial(self, step):
if 'project_id' in self.kwargs and step == 'project_essentials':
project_id = self.kwargs['project_id']
project = Project.objects.get(id=project_id)
from django.forms.models import model_to_dict
project_dict = model_to_dict(project)
return project_dict
else:
return self.initial_dict.get(step, {})
您需要将模型转换为dict,以便将其设置为初始数据。
答案 1 :(得分:3)
pxg的答案是不够的。正如emin-buğra-saral所指出的,它创建了一个新的模型实例而不是编辑它。而emin-buğra-saral本身的答案是不够的。要么不要覆盖 get_form_initial 方法,也不要设置initial_dict值或使用此答案中提供的实现。这就是你应该如何结合他们的答案:
在urls.py中:
(r'^projects/edit/(?P<project_id>[-\d]+)$', ProjectWizard.as_view(FORMS)),
:
class ProjectWizard(SessionWizardView):
def get_form_initial(self, step):
if 'project_id' in self.kwargs:
return {}
return self.initial_dict.get(step, {})
def get_form_instance(self, step):
if not self.instance:
if 'project_id' in self.kwargs:
project_id = self.kwargs['project_id']
self.instance = Project.objects.get(id=project_id)
else:
self.instance = Project()
return self.instance
虽然pxg的 get_form_initial 版本实际上可以正常工作(只要你还添加了 get_form_instance 覆盖),但是没有必要查找实例,提取其数据,以及创建一个初始值字典。所有这些都是在从 initial_dict 初始化实例之前由ModelForm自动完成的。只需返回一个空的初始值字典,您就可以获得更简单,更高效的代码。
答案 2 :(得分:2)
除了pxg的答案之外,get_form_instance应该是这样的,否则你不会编辑模型而是创建它的新实例:
def get_form_instance(self, step):
if not self.instance:
if 'initial_id' in self.kwargs:
initial_id = self.kwargs['initial_id']
self.instance = Project.objects.get(id=initial_id)
else:
self.instance = Project()
return self.instance
答案 3 :(得分:1)
我不得不编辑这个以使它在Django 1.11中使用django-formtools 2.1。
class ProjectWizard(SessionWizardView):
def get_form_initial(self, step):
if 'project_id' in self.kwargs:
return {}
return self.initial_dict.get(step, {})
def get_form_instance(self, step):
if not self.instance_dict:
if 'project_id' in self.kwargs:
project_id = self.kwargs['project_id']
return Project.objects.get(id=project_id)
return None
get_form_instance
方法现在需要either an object or None to be returned。
答案 4 :(得分:0)
与Django 3.1和django-formtools 2.2一起使用的更新。就我而言,我有两个模型(Colaborattor和User),它们通过OneToOneField连接。我在第0步中显示用户表单,在第1步中显示协作者表单。
models.py:
karate.configure('logModifier', new LM());
views.py:
class Colaborattor(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
nome = models.CharField("Nome completo", max_length=128)
...
我希望它可以帮助遇到相同问题的人。