Python 如何修复Modelformset验证中的错误“'id”:选择有效选项?

Python 如何修复Modelformset验证中的错误“'id”:选择有效选项?,python,django,django-models,django-forms,Python,Django,Django Models,Django Forms,我有一个模型表单集,在提交时会引发此验证错误: {'id':['选择一个有效的选项。该选项不是 可用选项。“]} 此错误出现的次数与我的queryset中的对象相同,即: qs = Task.objects.filter(property=property) 在过去的几天里,我一直在努力解决这个问题。我读过很多类似的帖子,尝试过不同的解决方案,但没有一个对我有效 我的表格集可以在这里看到: 我的表格: 最后,我的模型: 我已经知道问题与“状态”字段无关。事实上,我相信这与“任务”领域有关。我还

我有一个模型表单集,在提交时会引发此验证错误:

{'id':['选择一个有效的选项。该选项不是 可用选项。“]}

此错误出现的次数与我的queryset中的对象相同,即:

qs = Task.objects.filter(property=property)
在过去的几天里,我一直在努力解决这个问题。我读过很多类似的帖子,尝试过不同的解决方案,但没有一个对我有效

我的表格集可以在这里看到:

我的表格:

最后,我的模型:

我已经知道问题与“状态”字段无关。事实上,我相信这与“任务”领域有关。我还将{form.id}添加到模板中,正如我在其他一些问题上看到的那样

作为参考,我的模板:

此错误指向ModelChoiceField中的无效选择,在提供的示例中,该字段是TaskCheckForm的状态字段

这是类级属性,仅在应用程序启动且首次导入TaskCheckForm时才会启动。 并且它的查询集在开始时只解析一次,并且它将看到此时存在的TaskStatus对象,并且从不更新新项目或已删除项目的选项列表

要使用动态queryset处理关系字段和其他字段,请在字段上定义空queryset,并在表单的_init__方法中将其设置为必填字段:

代码中的其他潜在问题位置:

tasks=Task.objects.filterproperty=property\u pk-将返回结果列表。但在后面的代码中,它被分配给模板中的任务变量,该变量可能期望但可能是ok,并且它期望列出单个项。您可以先使用tasks=Task.objects.filterproperty=property\u pk.first

taskscheck=formset.savecommit=False-首先,它返回一个项目列表,因为它是一个作用于一组表单的表单集,所以为了向项目添加属性检查属性,您需要迭代结果;second-commit=False表示实例不会被保存,这是正常的,因为稍后会设置一些附加属性,但之后不会调用instance.save,因此仍然不会保存任何更改


看起来您的查询不正确。你在干什么

qs = Task.objects.filter(property=property)
应该是这样的-

qs = Task.objects.filter(property__id=property.id)
或者你可以这样做:

qs = Task.objects.filter(property__in=[property_pk])

这里的属性是一个多对多字段。您的查询看起来像是在搜索外键。

由于ModelFormSet和QuerySet中使用了不同的模型而引发的问题。 这些问题可以通过以下方式解决:

property = get_object_or_404(Property, pk=property_pk)
pcheck = get_object_or_404(Propertycheck, pk=pk)
qs = Task.objects.filter(property=property)
category = qs.values('category').distinct()
TaskCheckFormset = formset_factory(TaskCheckForm,extra=len(qs))

formset = TaskCheckFormset()
    for i in range(len(qs)):
        formset.forms[i].initial['task']=qs[i].id
        formset.forms[i].instance.task=qs[i]
        formset.forms[i].instance.property_check=pcheck
        formset.forms[i].initial['property_check']=pcheck.id

感谢Oleg,我在表单上添加了_uinit__uu函数,但错误仍然存在。我再次尝试的是从任何地方删除status字段,但仍然会出现相同的错误。这就是为什么我认为问题与地位无关,无论如何我会像你说的那样使用。tasks=Task.objects.filterproperty=property_与qs queryset相同,我可能会删除它。另外,为什么表单和表单集用于TaskCheck,而queryset用于Task?这是因为我的依赖关系。TaskCheck的目的是保存特定任务的状态,并且任务可以与特定属性相关。因此,我的queryset遍历实例属性的任务。我将更新我的问题并插入任务模型以便更好地理解。formset=TaskCheckFormsetrequest.POST,request.FILES,queryset=qs-formset使用TaskCheck模型,但qs用于任务模型。这可能会导致不兼容的字段等。我将尝试创建一个TaskCheck查询,返回相同的结果。我只是在这里猜测,但您是否可以尝试将id:type从分配给您的状态字段的小部件的属性中删除?@ruhaib id:type用于引用我表单上的CSS id。我已经试过了,没有区别。。谢谢这可能是因为TaskCheckForm中缺少task字段,并且模型task.ForeignKey中没有null=True。能否尝试将任务添加到TaskCheckForm字段中?这是django.forms.models或django.forms.fields中非常常见的默认错误消息。为了更具体,可能有必要对该异常进行回溯。感谢您的帮助,不幸的是,我的问题与此无关。表单集无效,因此它甚至没有达到该点。不管怎样,我做了那些改变。
if request.method == 'POST':
        formset = TaskCheckFormset(request.POST, request.FILES, queryset=qs)
        if formset.is_valid():
            instances = formset.save(commit=False)
            for instance in instances:
                # do something with instance
                instance.property_check=pcheck.id
                instance.save()
    status = forms.ModelChoiceField(queryset=TaskStatus.objects.none(), to_field_name="name", widget=...)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['status'].queryset = TaskStatus.objects.all()
qs = Task.objects.filter(property=property)
qs = Task.objects.filter(property__id=property.id)
qs = Task.objects.filter(property__in=[property_pk])
property = get_object_or_404(Property, pk=property_pk)
pcheck = get_object_or_404(Propertycheck, pk=pk)
qs = Task.objects.filter(property=property)
category = qs.values('category').distinct()
TaskCheckFormset = formset_factory(TaskCheckForm,extra=len(qs))

formset = TaskCheckFormset()
    for i in range(len(qs)):
        formset.forms[i].initial['task']=qs[i].id
        formset.forms[i].instance.task=qs[i]
        formset.forms[i].instance.property_check=pcheck
        formset.forms[i].initial['property_check']=pcheck.id