8

我正在 python/django 中创建一个表单集,并且需要在单击按钮时向表单集动态添加更多字段。我正在处理的表格是为我的学校询问他们想向谁披露某些学术信息的学生,这里的按钮允许他们添加更多字段以输入他们想向其披露的家庭成员/人。

我的按钮工作到显示额外字段的位置,您可以添加任意数量的字段。问题是,之前输入到现有字段中的数据被删除了。但是,只有表单集中的内容会被删除。之前在表单中填写的所有其他内容都将保持不变。

有没有办法让表单集保留在按下按钮之前输入的数据?

表格.py:

from django import forms
from models import Form, ParentForm, Contact
from django.core.exceptions import ValidationError

def fff (value):
    if value == "":
        raise ValidationError(message = 'Must choose a relation', code="a")

# Create your forms here.
class ModelForm(forms.ModelForm):   
    class Meta:
        model = Form
        exclude = ('name', 'Relation',)

class Parent(forms.Form):
    name = forms.CharField()

    CHOICES3 = (    
    ("", '-------'),
    ("MOM", 'Mother'),
    ("DAD", 'Father'),
    ("GRAN", 'Grandparent'),
    ("BRO", 'Brother'),
    ("SIS", 'Sister'),
    ("AUNT", 'Aunt'),
    ("UNC", 'Uncle'),
    ("HUSB", 'Husband'),
    ("FRIE", 'Friend'),
    ("OTHE", 'Other'),
    ("STEP", 'Stepparent'),
    )
    Relation = forms.ChoiceField(required = False, widget = forms.Select, choices = CHOICES3, validators = [fff])

模型.py

from django.db import models
from django import forms
from content.validation import *
from django.forms.models import modelformset_factory

class Contact(models.Model):
    name = models.CharField(max_length=100)

class Form(models.Model):
    CHOICES1 = (
        ("ACCEPT", 'I agree with the previous statement.'),
        )
    CHOICES2 = (
        ("ACADEMIC", 'Academic Records'),
        ("FINANCIAL", 'Financial Records'),
        ("BOTH", 'I would like to share both'),
        ("NEITHER", 'I would like to share neither'),
        ("OLD", "I would like to keep my old sharing settings"),
        )

    Please_accept = models.CharField(choices=CHOICES1, max_length=200)
    Which_information_would_you_like_to_share = models.CharField(choices=CHOICES2, max_length=2000)
    Full_Name_of_Student = models.CharField(max_length=100)
    Carthage_ID_Number = models.IntegerField(max_length=7)
    I_agree_the_above_information_is_correct_and_valid = models.BooleanField(validators=[validate_boolean])
    Date = models.DateField(auto_now_add=True)
    name = models.ManyToManyField(Contact, through="ParentForm")

class ParentForm(models.Model):
    student_name = models.ForeignKey(Form)
    name = models.ForeignKey(Contact)

    CHOICES3 = (
    ("MOM", 'Mother'),
    ("DAD", 'Father'),
    ("GRAN", 'Grandparent'),
    ("BRO", 'Brother'),
    ("SIS", 'Sister'),
    ("AUNT", 'Aunt'),
    ("UNC", 'Uncle'),
    ("HUSB", 'Husband'),
    ("FRIE", 'Friend'),
    ("OTHE", 'Other'),
    ("STEP", 'Stepparent'),
    )
    Relation = models.CharField(choices=CHOICES3, max_length=200)
    def __unicode__(self):
        return 'name: %r, student_name: %r' % (self.name, self.student_name)

和views.py

from django.shortcuts import render
from django.http import HttpResponse
from form import ModelForm, Parent
from models import Form, ParentForm, Contact
from django.http import HttpResponseRedirect
from django.forms.formsets import formset_factory

def create(request):
    ParentFormSet = formset_factory(Parent, extra=1)
    if request.POST:        
        Parent_formset = ParentFormSet(request.POST, prefix='Parent_or_Third_Party_Name')
        if 'add' in request.POST:
            list=[]
            for kitties in Parent_formset:
                list.append({'Parent_or_Third_Party_Name-0n-ame': kitties.data['Parent_or_Third_Party_Name-0-name'], 'Parent_or_Third_Party_Name-0-Relation': kitties.data['Parent_or_Third_Party_Name-0-Relation']})
            Parent_formset = ParentFormSet(prefix='Parent_or_Third_Party_Name', initial= list)
        form = ModelForm(request.POST)
        if form.is_valid() and Parent_formset.is_valid():
            form_instance = form.save()

            for f in Parent_formset:
                if f.clean():
                    (obj, created) = ParentForm.objects.get_or_create(name=f.cleaned_data['name'], Relation=f.cleaned_data['Relation'])

            return HttpResponseRedirect('http://Google.com')
    else:
        form = ModelForm()
        Parent_formset = ParentFormSet(prefix='Parent_or_Third_Party_Name')

    return render(request, 'content/design.html', {'form': form, 'Parent_formset': Parent_formset})
def submitted(request):
    return render(request, 'content/design.html')

先感谢您!

4

4 回答 4

7

我之前在 Django 中动态添加字段时遇到了麻烦,这个 stackoverflow 问题帮助了我: 动态添加字段到表单

老实说,在您的情况下,我不完全确定您所说的“持久”是什么意思-在添加输入时是否会删除表单的值?您确定这与您的JS无关吗?

于 2013-08-07T14:44:28.820 回答
4

我的一个同事终于明白了。这是修改后的views.py:

from django.shortcuts import render
from django.http import HttpResponse
from form import ModelForm, Parent
from models import Form, ParentForm, Contact
from django.http import HttpResponseRedirect
from django.forms.formsets import formset_factory

def create(request):
    ParentFormSet = formset_factory(Parent, extra=1)
    boolean = False
    if request.POST:        
        Parent_formset = ParentFormSet(request.POST, prefix='Parent_or_Third_Party_Name')
        if 'add' in request.POST:
            boolean = True
            list=[]
            for i in range(0,int(Parent_formset.data['Parent_or_Third_Party_Name-TOTAL_FORMS'])):
                list.append({'name': Parent_formset.data['Parent_or_Third_Party_Name-%s-name' % (i)], 'Relation': Parent_formset.data['Parent_or_Third_Party_Name-%s-Relation' % (i)]})
            Parent_formset = ParentFormSet(prefix='Parent_or_Third_Party_Name', initial= list)
        form = ModelForm(request.POST)
        if form.is_valid() and Parent_formset.is_valid():
            form_instance = form.save()                 

            for f in Parent_formset:
                if f.clean():
                    (contobj, created) = Contact.objects.get_or_create(name=f.cleaned_data['name'])
                    (obj, created) = ParentForm.objects.get_or_create(student_name=form_instance, name=contobj, Relation=f.cleaned_data['Relation'])

            return HttpResponseRedirect('http://Google.com')
    else:
        form = ModelForm()
        Parent_formset = ParentFormSet(prefix='Parent_or_Third_Party_Name')

    return render(request, 'content/design.html', {'form': form, 'Parent_formset': Parent_formset, 'boolean':boolean})
def submitted(request):
    return render(request, 'content/design.html')

谢谢你的意见,那些回答的人:)

于 2013-08-07T14:47:50.280 回答
3

我曾经试图做这样的事情,并被一个比我聪明得多的人指导到django-crispy-forms。我从未完成过这个项目,所以我无法提供更多帮助,但这可能是一个起点.

于 2013-08-01T19:12:53.357 回答
0

如果您的表单集没有显示您之前所做的输入,则意味着它看不到模型的查询集。将查询集添加到表单集参数以解决此问题。例如:

formset = SomeModelFormset(queryset=SomeModel.objects.filter(arg_x=x))
于 2019-09-20T23:28:06.987 回答