Django:ModelMultipleChoiceField 正在将基础模型的 max_length 验证器应用于所选结果的总长度
Django: ModelMultipleChoiceField is applying underlying model's max_length validator to total length of selected results
我正在使用 ModelMultipleChoiceField 允许用户select 删除某些模型对象。当 selected 单个对象时它工作正常,但是当 selected 多个对象时会触发验证错误:“确保此值最多有 50 个字符”。 50 个字符的限制来自基础模型的 max_length 属性。我不确定为什么要进行这种验证,因为我正在 selecting 现有模型对象,更不确定为什么它们要组合我所有 selection 的字符长度而不是验证每个 select离子单独。我还注意到,在总字符长度时,每个对象 selected 大约多了 20 个字符。感谢任何帮助。
这是我的代码:
型号:
class Template(models.Model):
# Relationships
user = models.ForeignKey("users.CustomUser", on_delete=models.CASCADE)
# Fields
name = models.CharField(max_length=50)
description = models.TextField(max_length=250)
docx_file = models.FileField(("DOCX File"),
upload_to=user_directory_path,
validators=[FileExtensionValidator(allowed_extensions=['docx'])])
created = models.DateTimeField(auto_now_add=True, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
def __str__(self):
return self.name
表格:
class TemplateChoiceDelete(forms.ModelForm):
name = forms.ModelMultipleChoiceField(queryset=Template.objects.all())
class Meta:
model = Template
fields = ['name']
# Limit results to templates owned by the current user
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
super(TemplateChoiceDelete, self).__init__(*args, **kwargs)
self.fields['name'].queryset = Template.objects.filter(user=user)
视图:(忽略过滤器代码,这是与另一个功能相关的正在进行的工作)
def manage_templates(request):
f = TemplateFilter(request.GET, queryset=Template.objects.filter(user=request.user))
if request.method == 'GET':
choice_form = TemplateChoiceDelete(request.GET, user=request.user)
print(choice_form)
if choice_form.is_valid():
choice_form.cleaned_data['name'].delete()
else:
form = TemplateChoiceDelete
return render(request, 'docs/manage_templates.html', {'filter': f, 'choice_form': choice_form})
模板:(再次请忽略与过滤器相关的代码)
{% block content %}
<p> <b> Search </b> </p>
<form method="get">
{{ filter.form.as_p }}
<input type="submit" value="Search" />
</form>
{% for obj in filter.qs %}
{{ obj.name }} | {{ obj.description }}<br />
{% endfor %}
<br>
<p><b> Delete Templates </b></p>
<form method="GET">
{{ choice_form.as_p }}
<input type="submit" onclick="return confirm('Are you sure? This will delete the selected template(s)')" value="Delete">
</form>
{% endblock %}
The error
这是不是一个ModelForm
,如果你使用ModelForm
,它当然会从模型中“继承”某些验证器。这是一个简单的Form
,所以:
class TemplateChoiceDelete(<b>forms.Form</b>):
name = forms.ModelMultipleChoiceField(queryset=Template.objects.all())
# <i>no</i> Meta
# Limit results to templates owned by the current user
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
super().__init__(*args, **kwargs)
self.fields['name'].queryset = Template.objects.filter(user=user)
ModelForm
是针对特定模型定制的 Form
以创建或更新模型 实例 ,而不是编辑具有“有事可做”与那个模型。
Note: Section 9 of the HTTP protocol
specifies that requests like GET and HEAD should not have side-effets, so you
should not change entities with such requests. Normally POST, PUT, PATCH, and
DELETE requests are used for this. In that case you make a small <form>
that
will trigger a POST request, or you use some AJAX calls.
我正在使用 ModelMultipleChoiceField 允许用户select 删除某些模型对象。当 selected 单个对象时它工作正常,但是当 selected 多个对象时会触发验证错误:“确保此值最多有 50 个字符”。 50 个字符的限制来自基础模型的 max_length 属性。我不确定为什么要进行这种验证,因为我正在 selecting 现有模型对象,更不确定为什么它们要组合我所有 selection 的字符长度而不是验证每个 select离子单独。我还注意到,在总字符长度时,每个对象 selected 大约多了 20 个字符。感谢任何帮助。
这是我的代码:
型号:
class Template(models.Model):
# Relationships
user = models.ForeignKey("users.CustomUser", on_delete=models.CASCADE)
# Fields
name = models.CharField(max_length=50)
description = models.TextField(max_length=250)
docx_file = models.FileField(("DOCX File"),
upload_to=user_directory_path,
validators=[FileExtensionValidator(allowed_extensions=['docx'])])
created = models.DateTimeField(auto_now_add=True, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
def __str__(self):
return self.name
表格:
class TemplateChoiceDelete(forms.ModelForm):
name = forms.ModelMultipleChoiceField(queryset=Template.objects.all())
class Meta:
model = Template
fields = ['name']
# Limit results to templates owned by the current user
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
super(TemplateChoiceDelete, self).__init__(*args, **kwargs)
self.fields['name'].queryset = Template.objects.filter(user=user)
视图:(忽略过滤器代码,这是与另一个功能相关的正在进行的工作)
def manage_templates(request):
f = TemplateFilter(request.GET, queryset=Template.objects.filter(user=request.user))
if request.method == 'GET':
choice_form = TemplateChoiceDelete(request.GET, user=request.user)
print(choice_form)
if choice_form.is_valid():
choice_form.cleaned_data['name'].delete()
else:
form = TemplateChoiceDelete
return render(request, 'docs/manage_templates.html', {'filter': f, 'choice_form': choice_form})
模板:(再次请忽略与过滤器相关的代码)
{% block content %}
<p> <b> Search </b> </p>
<form method="get">
{{ filter.form.as_p }}
<input type="submit" value="Search" />
</form>
{% for obj in filter.qs %}
{{ obj.name }} | {{ obj.description }}<br />
{% endfor %}
<br>
<p><b> Delete Templates </b></p>
<form method="GET">
{{ choice_form.as_p }}
<input type="submit" onclick="return confirm('Are you sure? This will delete the selected template(s)')" value="Delete">
</form>
{% endblock %}
The error
这是不是一个ModelForm
,如果你使用ModelForm
,它当然会从模型中“继承”某些验证器。这是一个简单的Form
,所以:
class TemplateChoiceDelete(<b>forms.Form</b>):
name = forms.ModelMultipleChoiceField(queryset=Template.objects.all())
# <i>no</i> Meta
# Limit results to templates owned by the current user
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
super().__init__(*args, **kwargs)
self.fields['name'].queryset = Template.objects.filter(user=user)
ModelForm
是针对特定模型定制的 Form
以创建或更新模型 实例 ,而不是编辑具有“有事可做”与那个模型。
Note: Section 9 of the HTTP protocol specifies that requests like GET and HEAD should not have side-effets, so you should not change entities with such requests. Normally POST, PUT, PATCH, and DELETE requests are used for this. In that case you make a small
<form>
that will trigger a POST request, or you use some AJAX calls.