gpt4 book ai didi

python - 如何将不同的模型表单添加到 modelformset_factory

转载 作者:行者123 更新时间:2023-12-03 13:37:36 24 4
gpt4 key购买 nike

关于这些模型:

class Projects(models.Model):
projectDescription = models.CharField(max_length=50,blank=True,null = True,)
status = models.IntegerField(choices = Status_CHOICES, default = 4)
projectOwner = models.ForeignKey(staff, on_delete=models.CASCADE, blank=True,null = True,)

class Updates(models.Model):
project = models.ForeignKey(Projects, on_delete=models.CASCADE)
update = models.CharField(max_length=50,blank=True,null = True,)
updateDate = models.DateTimeField(default = timezone.now, editable = False)
addedBy = models.CharField(max_length=35,blank=True,)

我想创建一个 View 来显示所有当前项目的表单。这很容易使用 modelformset_factory .但是我怎样才能为这些项目表单实例中的每一个添加一个附加表单,以便可以对项目(外键)进行更新?
理想情况下,用户对各种项目进行更改,为一个或多个项目添加更新,然后提交表单以保存所有更改。
我在下面的内容似乎非常接近,但它正在保存对每个项目的更新,其中包含我在最后一个表单中输入的任何内容的值。这似乎是因为形式不是唯一的。我走上了使用前缀的道路,这似乎也无济于事。帮助!

更新表格
class updateForm(ModelForm):
def __init__(self, *args, **kwargs):
super(updateForm, self).__init__(*args, **kwargs)
class Meta:
model = Updates
fields = ('update',)

查看:
def MDSprojects(request):
projects = Projects.objects.filter(dept = 'Assistive Technology')
projectFormset = modelformset_factory(Projects, form=EditProjectForm, extra = 0)

if request.method == 'POST':
formsetA = projectFormset(request.POST,request.FILES)
if formsetA.is_valid():
for f in formsetA:
formA = f.save(commit = False)
id = formA.id
formA.save()
formsetB = updateForm(request.POST,request.FILES)
if formsetB.is_valid():
formB = formsetB.save(commit = False)
project = Projects.objects.get(id = id)
formB.project = project
formB.save()
else:
print(formsetB.errors)
return redirect('MDS_Projects')
else:
print(formsetA.errors)
else:
formsetA = projectFormset(queryset = projects)
formsetB = updateForm()
return render(request,'MDSprojectsB.html',{'formset':formsetA,'formsetB':formsetB,})

模板:
<form method="POST" enctype= multipart/form-data>
{{ formset.management_form }}
{% csrf_token %}
{%for form in formset%}
{{ form.management_form }}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
<div class="card border-primary mb-3" style="max-width: 85rem;">
<div class="card-header text-primary">
<strong>{{form.instance.projectDescription}}</strong>
</div>
<div class="card-body text-primary"> Project Name: {{form.projectDescription}}</div>
<div class="card-body text-primary"> Status: {{form.status}}</div>
<div class="card-body text-primary"> Status: {{form.projectOwner}}</div>
<div class="card-body text-primary"> Status: {{form.priority}}</div>
<div>
{{ formsetB.management_form }}
{% for hidden in formsetB.hidden_fields %}
{{ hidden }}
{% endfor %}
{{formsetB}}
</div>
</div>
{% endfor %}
<button class="btn btn-success btn" type="submit">Save Changes</button>
</form>

编辑:

也许解释我的问题的另一种方式是:

如果我有与上面相同的模型:
class Projects(models.Model):
projectDescription = models.CharField(max_length=50,blank=True,null = True,)
status = models.IntegerField(choices = Status_CHOICES, default = 4)
projectOwner = models.ForeignKey(staff, on_delete=models.CASCADE, blank=True,null = True,)

class Updates(models.Model):
project = models.ForeignKey(Projects, on_delete=models.CASCADE)
update = models.CharField(max_length=50,blank=True,null = True,)
updateDate = models.DateTimeField(default = timezone.now, editable = False)
addedBy = models.CharField(max_length=35,blank=True,)

我想要一个 View ,将所有当前项目呈现为单独的表单,以便用户可以在一个 View 中更改项目模型。此外,我希望用户也能够为每个项目添加更新。

例如,如果我有 3 个项目,我希望在页面上看到 3 个表单。每个表单都将包含用于修改此项目的字段(因此这些表单字段将使用当前值预先填充)。最后(我被卡住的部分)将是一个额外的空字段,用于向项目添加更新。

最佳答案

解决方案一

你所做的几乎是正确的。您已经启动了一个 UpdateForm,但您将它视为一个表单集。然而,它是一个 Form 实例。如果您按如下方式更改代码,则可能会实现您的目标。

模型.py

class Project(models.Model):
description = models.CharField(max_length=50, blank=True, null=True)
status = models.IntegerField(choices=STATUS_CHOICES, default=4)
owner = models.ForeignKey(staff, on_delete=models.CASCADE, blank=True, null=True)
...

class Update(models.Model):
project = models.ForeignKey(Project, on_delete=models.CASCADE)
notes = models.CharField(max_length=50, blank=True, null=True)
update_date = models.DateTimeField(default=timezone.now, editable=False)
added_by = models.CharField(max_length=35, blank=True)

表格.py

class CreateUpdateForm(ModelForm):
class Meta:
model = Update
fields = ('notes')


class EditProjectForm(ModelForm)
class Meta:
model = Project
fields = ('__all__')


View .py

def mds_projects(request):
project_formset = modelformset_factory(Project, form=EditProjectForm, extra=0)

if request.method == 'POST':
formset = project_formset(request.POST,request.FILES)
if formset.is_valid():
for f in formset:
project = f.save(commit = False)

update_form = CreateUpdateForm(request.POST,request.FILES)
if update_form.is_valid():
update = update_form.save(commit = False)
update.project = project
project.save()
update.save()
else:
print(update_form.errors)
return redirect('MDS_Projects')
else:
print(formset.errors)
else:
projects = Project.objects.filter(dept='Assistive Technology')
formset = project_formset(queryset=projects)
update_form = updateForm()
return render(request,'MDSprojectsB.html',{'formset':formset, 'update_form':update_form})


MDSprojectsB.html

<form method="POST" enctype= multipart/form-data>
{{ formset.management_form }}
{% csrf_token %}
{%for form in formset%}
{{ form.management_form }}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
<div class="card border-primary mb-3" style="max-width: 85rem;">
<div class="card-header text-primary">
<strong>{{form.instance.description}}</strong>
</div>
<div class="card-body text-primary"> Project Name: {{form.description}}</div>
<div class="card-body text-primary"> Status: {{form.status}}</div>
<div class="card-body text-primary"> Owner: {{form.owner}}</div>
<div class="card-body text-primary"> Priority: {{form.priority}}</div>
<div>
{{ update_form }}
</div>
</div>
{% endfor %}
<button class="btn btn-success btn" type="submit">Save Changes</button>
</form>

方案二

您也可以对两种模型使用一种形式。由于您只需要 Update 的更新说明您可以添加额外的表单字段来更新项目表单,因此您不需要额外的更新表单。

表格.py

class EditProjectForm(ModelForm)
update_notes = forms.CharField(max_length=50, help_text='50 characters max.')
class Meta:
model = Project
fields = ('__all__')


View .py

def mds_projects(request):
project_formset = modelformset_factory(Project, form=EditProjectForm, extra=0)

if request.method == 'POST':
formset = project_formset(request.POST,request.FILES)
if formset.is_valid():
for f in formset:
project = f.save(commit = False)
update = Update.objects.create(notes=f.cleaned_data['update_notes'], project=project)
project.save()

return redirect('MDS_Projects')
else:
print(formset.errors)
else:
projects = Project.objects.filter(dept='Assistive Technology')
formset = project_formset(queryset=projects)
return render(request,'MDSprojectsB.html',{'formset':formset})


MDSprojectsB.html

<form method="POST" enctype= multipart/form-data>
{{ formset.management_form }}
{% csrf_token %}
{%for form in formset%}
{{ form.management_form }}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
<div class="card border-primary mb-3" style="max-width: 85rem;">
<div class="card-header text-primary">
<strong>{{form.instance.description}}</strong>
</div>
<div class="card-body text-primary"> Project Name: {{form.description}}</div>
<div class="card-body text-primary"> Status: {{form.status}}</div>
<div class="card-body text-primary"> Owner: {{form.owner}}</div>
<div class="card-body text-primary"> Priority: {{form.priority}}</div>
<div class="card-body text-primary"> Update: {{form.update_notes}}</div>
</div>
{% endfor %}
<button class="btn btn-success btn" type="submit">Save Changes</button>
</form>

附言您提供的代码违反了 python 和 django 命名约定。请尽量遵守这些约定。我已经修复了我的代码中的一些。例如,您不应将模型命名为复数,而应为函数和变量使用驼峰命名法。

关于python - 如何将不同的模型表单添加到 modelformset_factory,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62246742/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com