Django只保存formset的第一种形式

时间:2017-01-12 09:25:19

标签: python django forms django-forms modelform

我查看了每个类似的问题(并尝试过),但仍然无法找到答案。

我有两种模式:

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的表单。因此,他可以更正它们。

下面,我想为已经为这个项目创建的每个页面显示一个填写的表单,以及几个用于创建新表单的空表单。

所有初始数据都会正确显示,但是当我填写几个空表格时 - 每次只保存第一个空表格。

2 个答案:

答案 0 :(得分:1)

以下是解决方法:

  1. 正确包含错误。
  2. 看到倒数第二个表格缺少必填字段(hiddenInput)
  3. 在视图中进行了更改,如下所示:

    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}])
    
  4. 初始值现在匹配额外表单的数量 - 每个表单都有自己的外键。

    可能有一个更好的解决方案,但问题是找到并解决了我!

答案 1 :(得分:0)

我的问题是,当我尝试手动呈现表单集的每种形式时,我添加了一个未经修饰的<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>

更改后,我的表格被正确识别。