Django 只保存第一种形式的 formset
Django save only first form of formset
我浏览了所有类似的问题(并尝试过),但仍然找不到答案。
我有两个型号:
class Project(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
name = models.CharField(max_length=120, verbose_name = "Название проекта")
url = models.URLField(max_length=120, unique=True, verbose_name = "Полный адрес сайта")
robots_length = models.CharField(max_length=5, default=0)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
def __unicode__(self):
return self.name
def __str__(self):
return self.name
def get_absolute_url(self):
from django.urls import reverse
return reverse('projects:detail', args=[str(self.id)])
class ProjectPage(models.Model):
page_project = models.ForeignKey(Project, on_delete=models.CASCADE)
page_url = models.URLField(verbose_name = "Адрес страницы")
page_title = models.CharField(max_length=300, blank=True, verbose_name = "meta-title",default="")
page_description = models.CharField(max_length=300, blank=True, verbose_name = "meta-description",default="")
page_h1 = models.CharField(max_length=300, blank=True, verbose_name = "Заголовок h1",default="")
def __unicode__(self):
return self.page_url
def __str__(self):
return self.page_url
每个模型都有一个表格:
class ProjectFormUpdate(forms.ModelForm):
class Meta:
model = Project
fields = [
"name",
"url",
]
widgets = {
'name': forms.TextInput(attrs={'placeholder': 'Произвольное название'}),
}
class ProjectPageForm(forms.ModelForm):
class Meta:
model = ProjectPage
fields = [
'page_project',
'page_url',
'page_title',
'page_description',
'page_h1',
]
widgets = {
'page_project': forms.HiddenInput()
}
在 views.py 我有:
def projects_update(request, proj=None):
instance = get_object_or_404(Project, id=proj)
form = ProjectFormUpdate(request.POST or None, instance=instance)
formset_f = modelformset_factory(ProjectPage, form=ProjectPageForm, extra=3)
formset = formset_f(queryset=ProjectPage.objects.filter(page_project__id=proj), initial =[{'page_project': proj}])
if request.method == 'POST':
formset = formset_f(request.POST)
for formset_form in formset:
if formset_form.is_valid() and formset_form.has_changed():
formset_form.save()
if form.is_valid():
form.save()
context = {
'title': "Редактируем проект - "+instance.name,
'form': form,
'formset': formset,
'instance': instance,
}
return render(request, "projects_update.html", context)
最后,html
<form method="POST" action="" class="create-form">
{{ formset.management_form }}
{% csrf_token %}
<div class="row">
<div class="col-lg-6 offset-lg-3 col-md-10 offset-md-1 col-xs-10 offset-xs-1 form-bg">
<h2>Общие данные</h2>
{{ form|crispy}}
<input type="submit" class="btn btn-success" value="Обновить проект" />
</div>
</div>
{% for formset_form in formset %}
<div class="row form-container">
<div class="col-lg-6 offset-lg-3 col-md-10 offset-md-1 col-xs-10 offset-xs-1 form-bg">
<h3>Страница {{forloop.counter}}</h3>
{{ formset_form|crispy}}
</div>
</div>
{% endfor %}
</form>
我想要实现的是:当用户进入一个页面时,他会得到一个表格,其中已经填写了项目名称和项目 URL。因此,他可以更正它们。
在下面,我想显示为该项目所有已创建的每个页面填写的表单和几个用于创建新页面的空表单。
所有初始数据都正确显示,但是当我填写多个空表格时 - 每次只保存第一个空表格。
解决方法如下:
- 正确包含错误。
- 看到倒数第二个表单缺少必填字段(hiddenInput)
对视图进行了更改,使其看起来像:
formset_f = modelformset_factory(ProjectPage, form=ProjectPageForm, extra=3)
formset = formset_f(queryset=ProjectPage.objects.filter(page_project__id=proj), initial =[{'page_project': proj}, {'page_project': proj}, {'page_project': proj}])
初始值现在匹配额外表单的数量 - 每个表单都有自己的外键。
可能有更好的解决方案,但问题已找到并为我解决!
我的问题是,当我尝试手动呈现表单集的每个表单时,我添加了一个不需要的 <form></form>
html 元素
错误:
{ form.management_form }}
{% for form in formset %}
<form class="form-class">
{{form.name}}
</form>
对:
{ form.management_form }}
{% for form in formset %}
<div class="form-class">
{{form.name}}
</div>
更改后我的表单被正确识别。
我浏览了所有类似的问题(并尝试过),但仍然找不到答案。
我有两个型号:
class Project(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
name = models.CharField(max_length=120, verbose_name = "Название проекта")
url = models.URLField(max_length=120, unique=True, verbose_name = "Полный адрес сайта")
robots_length = models.CharField(max_length=5, default=0)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
def __unicode__(self):
return self.name
def __str__(self):
return self.name
def get_absolute_url(self):
from django.urls import reverse
return reverse('projects:detail', args=[str(self.id)])
class ProjectPage(models.Model):
page_project = models.ForeignKey(Project, on_delete=models.CASCADE)
page_url = models.URLField(verbose_name = "Адрес страницы")
page_title = models.CharField(max_length=300, blank=True, verbose_name = "meta-title",default="")
page_description = models.CharField(max_length=300, blank=True, verbose_name = "meta-description",default="")
page_h1 = models.CharField(max_length=300, blank=True, verbose_name = "Заголовок h1",default="")
def __unicode__(self):
return self.page_url
def __str__(self):
return self.page_url
每个模型都有一个表格:
class ProjectFormUpdate(forms.ModelForm):
class Meta:
model = Project
fields = [
"name",
"url",
]
widgets = {
'name': forms.TextInput(attrs={'placeholder': 'Произвольное название'}),
}
class ProjectPageForm(forms.ModelForm):
class Meta:
model = ProjectPage
fields = [
'page_project',
'page_url',
'page_title',
'page_description',
'page_h1',
]
widgets = {
'page_project': forms.HiddenInput()
}
在 views.py 我有:
def projects_update(request, proj=None):
instance = get_object_or_404(Project, id=proj)
form = ProjectFormUpdate(request.POST or None, instance=instance)
formset_f = modelformset_factory(ProjectPage, form=ProjectPageForm, extra=3)
formset = formset_f(queryset=ProjectPage.objects.filter(page_project__id=proj), initial =[{'page_project': proj}])
if request.method == 'POST':
formset = formset_f(request.POST)
for formset_form in formset:
if formset_form.is_valid() and formset_form.has_changed():
formset_form.save()
if form.is_valid():
form.save()
context = {
'title': "Редактируем проект - "+instance.name,
'form': form,
'formset': formset,
'instance': instance,
}
return render(request, "projects_update.html", context)
最后,html
<form method="POST" action="" class="create-form">
{{ formset.management_form }}
{% csrf_token %}
<div class="row">
<div class="col-lg-6 offset-lg-3 col-md-10 offset-md-1 col-xs-10 offset-xs-1 form-bg">
<h2>Общие данные</h2>
{{ form|crispy}}
<input type="submit" class="btn btn-success" value="Обновить проект" />
</div>
</div>
{% for formset_form in formset %}
<div class="row form-container">
<div class="col-lg-6 offset-lg-3 col-md-10 offset-md-1 col-xs-10 offset-xs-1 form-bg">
<h3>Страница {{forloop.counter}}</h3>
{{ formset_form|crispy}}
</div>
</div>
{% endfor %}
</form>
我想要实现的是:当用户进入一个页面时,他会得到一个表格,其中已经填写了项目名称和项目 URL。因此,他可以更正它们。
在下面,我想显示为该项目所有已创建的每个页面填写的表单和几个用于创建新页面的空表单。
所有初始数据都正确显示,但是当我填写多个空表格时 - 每次只保存第一个空表格。
解决方法如下:
- 正确包含错误。
- 看到倒数第二个表单缺少必填字段(hiddenInput)
对视图进行了更改,使其看起来像:
formset_f = modelformset_factory(ProjectPage, form=ProjectPageForm, extra=3) formset = formset_f(queryset=ProjectPage.objects.filter(page_project__id=proj), initial =[{'page_project': proj}, {'page_project': proj}, {'page_project': proj}])
初始值现在匹配额外表单的数量 - 每个表单都有自己的外键。
可能有更好的解决方案,但问题已找到并为我解决!
我的问题是,当我尝试手动呈现表单集的每个表单时,我添加了一个不需要的 <form></form>
html 元素
错误:
{ form.management_form }}
{% for form in formset %}
<form class="form-class">
{{form.name}}
</form>
对:
{ form.management_form }}
{% for form in formset %}
<div class="form-class">
{{form.name}}
</div>
更改后我的表单被正确识别。