英文:
django clean function in forms.py does not work
问题
我正在阅读一本名为《使用Django进行Web开发》的书,我非常喜欢它。书中教授的其中一件事是你可以更改来自表单的值。我已经测试了引发错误(来自Django核心的验证错误),这个方法运行得很好。但是我无法让"clean_name"函数在输入上运行。这个函数位于底部。
from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError
def validate_regnr(value):
if value[:3].upper() != value[:3]:
raise ValidationError(f'{value} is not correct')
class BookingForm(forms.Form):
SERVICES = (
('1', 'Årsservice'),
('2', 'Storservice'),
('3', 'Bromsservice')
)
regnr = forms.CharField(min_length=6, max_length=6, validators=[validate_regnr])
service = forms.ChoiceField(choices=SERVICES)
name = forms.CharField(max_length=255)
tel = forms.CharField(max_length=20)
email = forms.EmailField()
datetime = forms.DateTimeField(widget=widgets.DateInput(attrs={'type': 'datetime-local'}))
kommentar = forms.TextInput()
def clean_name(self):
value = self.cleaned_data['name']
return value.upper()
希望这对你有帮助。
英文:
Im reading a book called "Web development with Django" which I like a lot.
One of the things which gets taught there is that you can change a value coming from the form. I have tested raising errors (validation error from django core) which works fine.
But I can't get the "clean_name" function to work on the input. The function is located at the bottom.
I hope someone here knows what im doing wrong
from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError
def validate_regnr(value):
if value[:3].upper() != value[:3]:
raise ValidationError(f'{value} is not correct')
class BookingForm(forms.Form):
SERVICES = (
('1', 'Årsservice'),
('2', 'Storservice'),
('3', 'Bromsservice')
)
regnr = forms.CharField(min_length=6, max_length=6, validators=[validate_regnr])
service = forms.ChoiceField(choices=SERVICES)
name = forms.CharField(max_length=255)
tel = forms.CharField(max_length=20)
email = forms.EmailField()
datetime = forms.DateTimeField(widget=widgets.DateInput(attrs={'type': 'datetime-local'}))
kommentar = forms.TextInput()
def clean_name(self):
value = self.cleaned_data['name']
return value.upper()
答案1
得分: 0
以下是翻译好的部分:
"事情的顺序很重要。首先,它将运行表单字段本身上定义的清理和验证器。然后它将运行表单中的 clean_…
方法,最后,它将运行 clean
方法。
因此,这意味着字段中的验证器在它传递给 clean_name
方法之前运行。因此,在字段上定义的验证器不能仅仅依靠 clean_…
方法来满足,因为控制从不会传递到这些方法。
但是,您可以通过子类化字段来在验证之前进行清理:
class UppercaseCharField(forms.CharField):
def to_python(self, value):
val = super().to_python(value)
if val is not None:
return val.upper()
然后使用它:
class BookingForm(forms.Form):
# ...
regnr = UpperCharField(
min_length=6, max_length=6, validators=[validate_regnr]
)
# 没有 clean_name ...
希望这有所帮助。
英文:
The order of things is important. First it will run the cleaning and validators defined on the form fields itself. Then it will run the <code>clean_…</code> methods in the form, and finally, it will run the clean
method.
This thus means that the validator in the field runs before it ever gets to the clean_name
method. Validators defined on the fields thus can not be satisfied with the <code>clean_…</code> methods, simply because control is never passed to these.
You can however do the cleaning before validating by subclassing the field:
<pre><code>class UppercaseCharField(forms.CharField):
def <b>to_python</b>(self, value):
val = super().to_python(value)
if val is not None:
return val.upper()</code></pre>
and then use that one:
<pre><code>class BookingForm(forms.Form):
# …
regnr = <b>UpperCharField(</b>
min_length=6, max_length=6, validators=[validate_regnr]
<b>)</b>
# <b>no</b> clean_name …</code></pre>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论