Django表单处理动态字段标签

0 投票
2 回答
1193 浏览
提问于 2025-04-18 11:28

我做了一个表单,这个表单会根据传入的参数和数据库里存储的体重级别动态生成。这个过程都很顺利(注意:这不是一个模型表单,只是一个普通的表单)。

现在我想保存用户的回答。我该如何遍历他们提交的数据,以便保存呢?

这里有一个类似的问题:在Django中处理动态的多选字段

不过我这边的情况稍微有点不同,所以我没法照搬那个方法。我想看到用户在表单中选择的选项按钮的标签,并将这个值与数据库中已经存储的体重级别进行比较。这个表单里有像'first_name'和'last_name'这样的字段,而我用来动态生成体重级别的代码如下:

def __init__(self, event, *args, **kwargs):
    super(EntryForm, self).__init__(*args, **kwargs)

    groups = ClassGroup.objects.all()
    weight_classes = ClassOrder.objects.filter(event=event).order_by('weight')
    current_group = regclasses[0].competition_class.class_group

    for weight_class in weight_classes.all():
        self.fields['%s' % weight_class.competition_class.class_group.group_name] = forms.ChoiceField(choices=[ (o.id, o.class_name + ": " + o.class_info) for o in weight_class.competition_class.class_group.classes_in_group.all()], widget=forms.RadioSelect(), label=weight_class.competition_class.class_group.group_name, required=False)

这样我就得到了类似这样的内容:

男子体重级别

  • 男子轻量级
  • 男子中量级
  • 男子轻重量级
  • 男子重量级
  • 男子超级重量级

此外,还有一些不是动态生成的表单字段。

这些字段都是一个单选组的一部分。我正在尝试用以下代码来处理这个表单:

for field in form.fields:
    if Classes.objects.filter(class_name=field).count > 0: #checking to see if the field's name matches a class

    newentry = Entry(
        athlete = athlete,
        event = event,
        athlete_class = Classes.objects.filter(class_name=field)
        )

我的想法是,循环应该遍历表单中的字段,并检查字段的标签是否与数据库中的体重级别相同。如果字段和数据库中的体重级别匹配,那么就会创建一个新的记录,包含运动员、赛事和运动员在表单中选择的体重级别。当我运行代码时,我遇到了一个错误:

无法分配"[]": "Entry.athlete_class"必须是一个"Classes"实例。

我猜测'field'变量没有正确引用选项按钮的标签。我该如何让表单处理动态生成的体重级别的名称呢?

2 个回答

0

我之前是通过在表单上创建一个数组,里面放动态生成的字段,然后逐个遍历这个数组来实现的。

另外,你也可以把 objects.get(...) 放在一个 try/except 块里,这样可以处理可能出现的错误:

try:
    Classes.objects.get(class_name=field)
except:
    pass
else:
    newentry = Entry(
        athlete = athlete,
        event = event,
        athlete_class = Classes.objects.filter(class_name=field)
        )

if 语句不工作的原因是后面的代码块没有正确缩进。这样写也可以正常工作(注意 count 后面的括号):

if Classes.objects.get(class_name=field).count() > 0:
    newentry = Entry(
        athlete = athlete,
        event = event,
        athlete_class = Classes.objects.filter(class_name=field)
        )
1
Classes.objects.filter(class_name=field)

这个返回的是一个查询集,但你想要的是一个类的实例。

Classes.objects.get(class_name=field)

这样做就可以了。

撰写回答