Django仅保存表单集的第一种形式 [英] Django save only first form of formset

查看:103
本文介绍了Django仅保存表单集的第一种形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经浏览了每个类似的问题(并尝试了它们),但仍然找不到答案。



我有两个模型:

  class项目(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL,默认= 1)
名称= 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)
更新= models.DateTimeField(auto_now = True,auto_now_add = False)
时间戳= 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 (个体):来自django.urls的
导入反向
返回反向('projects:detail',args = [str(self.id)])

类ProjectPage(模型.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 =模型.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
字段= [
名称,
URL,
]
小部件= {
'名称':forms.TextInput(attrs = { '占位符':'Произвольноеназвание'}),
}

类ProjectPageForm(forms.ModelForm):
类元:
模型= ProjectPage
字段= [
'page_project',
'page_url',
'page_title',
'page_description',
'page_h1',
]
小部件= {
'page_project' :forms.HiddenInput()
}

在views.py中,我有:

  def projects_update(request,proj = None):
实例= get_object_or_404(Project,id = proj)
形式= ProjectFormUpdate(request.POST或None,instance = instance)

formset_f = modelformset_factory(ProjectPage,form = ProjectPageForm,extra = 3)
formset = formset_f(queryset = ProjectPage.objects.filter (page_project__id = proj),初始= [{{'page_project':proj}])

如果request.method =='POST':
formset = formset_f(request.POST)
用于formset_form formset:如果formset_form.is_valid()和formset_form.has_changed()为
formset_form.save()
如果form.is_valid()为
form.save()

context = {
'title':Редактируемпроект- + instance.name,
'form':form,
'formset':formset,
'instance':实例,
}
return render(request, projects_update.html,context)

最后,html

 < form method = POST action =类= 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-b​​g>

< h2>Общиеданные< / h2>

{{form | crispy}}
<输入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-b​​g>
< h3>Страница{{forloop.counter}}< / h3>


{{formset_form | crispy}}


< / div>
< / div>
{%endfor%}

< / form>

我要实现的目标是:当用户进入页面时,他得到一个带有项目名称的表格并且已经填写了项目URL。因此,他可以对其进行更正。



下面,我想为已经为此项目创建的每个页面显示一个填写好的表单,其中几个空白



发生的事情是所有初始数据都能正确显示,但是当我填写几个空白表格时-每次仅保存第一个空白表格。

解决方案

解决方法如下:


  1. 正确包含了错误。

  2. 看到倒数第二个表单缺少必填字段(hiddenInput)

  3. 视图发生了变化,因此看起来:

      formset_f = modelformset_factory(ProjectPage,form = ProjectPageForm,extra = 3)

    formset = formset_f (queryset = ProjectPage.objects.filter(page_project__id = proj),初始= [{{'page_project':proj},{'page_project':proj},{ 'page_project':proj}])


初始值现在匹配额外形式的数量-每个形式都有它自己的外键。



可能有更好的解决方案,但是问题为我找到并解决了! / p>

I've looked through every similar question (and tried them), but still couldn't find answer.

I have two models:

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

For each model there is a form:

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()
        }

In views.py I have:

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)

And, finaly, 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>

What I am trying to achieve is: when user enters a page, he gets a form with project name and project URL already filled in. So, he can correct them.

Below, I want to show a filled in form for every page allready created for this project and several empty forms for creating new.

What happens is all initial data is displayed correctly, but when I fill several empty forms - only first empty form is saved each time.

解决方案

Here is how it was solved:

  1. Included errors properly.
  2. Saw that second to last form lack required field (hiddenInput)
  3. Made changes in view so it looks like:

    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}])
    

Initial values now match number of extra forms - every form got it's own foreign key.

Probably there is a better solution, but the the problem is found and solved for me!

这篇关于Django仅保存表单集的第一种形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆