Я весело разрабатывал веб-приложение, используя версию для разработки Django. Через некоторое время я обновился до версии 1.2 alpha 1 SVN-12271. Теперь я получаю сообщения об ошибках очистки поля формы по умолчанию типа «Значение u'A325» не является допустимым выбором ». Это поле выбора без возможности неверного выбора. Кроме того, я вижу «Это поле не может быть пустым», когда оно может быть фактически пустым. Я не думаю, что это какое-то поле формы для ошибки индексации атрибута модели. Приложение продолжает работать должным образом под Django 1.1.1. Итак, какое серьезное изменение произошло в Django, что объясняет это? Я искал обратно-несовместимые изменения в http://docs.djangoproject.com/en/dev/releases/1.2-alpha-1/, но на самом деле ничего не вижу.
Вот несколько важных подсказок: 1) Моя проверка по каждому полю по-прежнему работает отлично; только проверка по умолчанию облажается. 2) Изменяются только поля выбора, но некоторые поля выбора не затрагиваются. 3) Из затронутых полей выбора некоторые являются стандартными, а некоторые используют недокументированную функцию optgroup, так что это не кажется важным фактором. Есть идеи?
Я действительно хочу вернуться к разрабатываемой версии, потому что мне нужны новые разрешения на уровне объектов (на уровне строк).
ДОБАВЛЕННЫЙ КОД
С удовольствием, Залев. Это моя базовая модель:
class BXEEP_L_Dataset(models.Model):
date_time = models.DateTimeField(editable=False, auto_now=True, auto_now_add=True,
help_text="Date and time created or last saved.")
unique_ID = models.CharField(max_length=20, blank=True, default="",
help_text="Unique identifier for problem")
project_name = models.CharField(max_length=55, blank=True, default="", help_text="Project name")
project_number = models.CharField(max_length=20, blank=True, default="", help_text="Project number")
description = models.CharField(max_length=55, blank=True, default="",
help_text="Problem description")
n_bolts = models.IntegerField(choices=BXEEP_BOLTS, blank=False, default=4,
help_text="4 or 8 bolts?")
stiffeners = models.BooleanField(blank=True, help_text="Stiffeners?")
cont_plates = models.BooleanField(blank=True, help_text="Continuity plates?")
partial_width = models.BooleanField(blank=True, help_text="Partial width plates?")
doubler_plate = models.BooleanField(blank=True, help_text="Doubler plate?")
column_top = models.BooleanField(blank=True, help_text="Top of column?")
shims = models.BooleanField(blank=True, help_text="Finger shims?")
flange_weld_type = models.CharField(max_length=11, choices=WELD_TYPE, blank=False, default="fillet",
help_text="Flange weld type")
flange_weld_size = models.IntegerField(blank=True, null=True, default=0, help_text="Flange weld size")
web_weld_type = models.CharField(max_length=11, choices=WELD_TYPE, blank=False, default="fillet")
web_weld_size = models.IntegerField(blank=True, null=True, default=0, help_text="Web weld size")
bolt_grade = models.CharField(max_length=8, choices=Bolt_grades, blank=False, default="A325",
help_text="Bolt grade")
db = models.FloatField(choices=Bolt_diameters, blank=False, default=0.750,
help_text="d<sub>b</sub>")
liw = models.BooleanField(blank=True, help_text="Load-indicating washers?")
end_pl_grade = models.CharField(max_length=8, choices=PL_grades_50, blank=False, default="A36",
help_text="End PL grade")
stiff_pl_grade = models.CharField(max_length=8, choices=PL_grades, blank=False, default="A36",
help_text="Stiffener PL grade")
cont_pl_grade = models.CharField(max_length=8, choices=PL_grades, blank=False, default="A36",
help_text="Continuity PL grade")
doubler_pl_grade = models.CharField(max_length=8, choices=PL_grades, blank=False, default="A36",
help_text="Doubler PL grade")
bm_profile = models.CharField(max_length=8, choices=W_profiles, help_text="Beam profile")
col_profile = models.CharField(max_length=8, choices=W_profiles, help_text="Column profile")
beam_grade = models.CharField(max_length=11, choices=W_grades, blank=False, default="A992",
help_text="Beam grade")
col_grade = models.CharField(max_length=11, choices=W_grades, blank=False, default="A992",
help_text="Column grade")
Muc = models.FloatField(help_text="M<sub>uc</sub>")
Vu = models.FloatField(help_text="V<sub>u</sub>")
Nu = models.FloatField(help_text="N<sub>u</sub>", blank=True, null=True, default=0.0)
Pcu = models.FloatField(help_text="P<sub>cu</sub>", default=0.0)
Vcu = models.FloatField(help_text="V<sub>cu</sub>", blank=True, null=True, default=0.0)
tp = models.FloatField(help_text="t<sub>p</sub>")
bp = models.FloatField(help_text="b<sub>p</sub>")
a = models.FloatField(help_text="a", default=0.0)
g = models.FloatField(help_text="g")
pfo = models.FloatField(help_text="p<sub>fo</sub>")
pfi = models.FloatField(help_text="p<sub>fi</sub>")
de = models.FloatField(help_text="d<sub>e</sub>")
pb = models.FloatField(blank=True, null=True, default=0.0, help_text="p<sub>b</sub>")
ts = models.FloatField(blank=True, null=True, default=0.0, help_text="t<sub>s</sub>")
tcp = models.FloatField(blank=True, null=True, default=0.0, help_text="t<sub>cp</sub>")
bcp = models.FloatField(blank=True, null=True, default=0.0, help_text="b<sub>cp</sub>")
td = models.FloatField(blank=True, null=True, default=0.0, help_text="t<sub>d</sub>")
hcol = models.FloatField(blank=True, null=True, default=0.0, help_text="h<sub>col</sub>")
tshim = models.FloatField(blank=True, null=True, default=0.0, help_text="t<sub>shim</sub>")
def __unicode__(self):
# return self.date_time
return u"%s" % (self.date_time)
В bolt_grade возникают ошибки «Неправильный выбор», хотя невозможно сделать неверный выбор. Ошибки «это поле обязательны» возникают в beam_profile, column_profile, даже когда сделан выбор, и в других полях (например, stiffener_grade, doubler_grade), даже если они не обязательны. Вот ModelForm:
class BXEEP_L_Form(ModelForm):
unique_ID = forms.CharField(max_length=20, required=False,
widget=forms.TextInput(attrs={"class": "short-char"}))
project_name = forms.CharField(max_length=55, required=False,
widget=forms.TextInput(attrs={"class": "long-char"}))
project_number = forms.CharField(max_length=20, required=False,
widget=forms.TextInput(attrs={"class": "short-char"}))
description = forms.CharField(max_length=55, required=False,
widget=forms.TextInput(attrs={"class": "long-char"}))
flange_weld_size = forms.IntegerField(min_value=2, required=False,
widget=forms.TextInput(attrs={"class": "short-int"}))
web_weld_size = forms.IntegerField(min_value=2, required=False,
widget=forms.TextInput(attrs={"class": "short-int"}))
stiff_pl_grade = forms.ChoiceField(choices=PL_grades, required=False)
cont_pl_grade = forms.ChoiceField(choices=PL_grades, required=False)
doubler_pl_grade = forms.ChoiceField(choices=PL_grades, required=False)
Muc = forms.FloatField(widget=forms.TextInput(attrs={"class": "std-float"}))
Vu = forms.FloatField(widget=forms.TextInput(attrs={"class": "std-float"}))
Nu = forms.FloatField(widget=forms.TextInput(attrs={"class": "std-float"}), required=False)
Pcu = forms.FloatField(widget=forms.TextInput(attrs={"class": "std-float"}))
Vcu = forms.FloatField(widget=forms.TextInput(attrs={"class": "std-float"}), required=False)
tp = forms.FloatField(widget=forms.TextInput(attrs={"class": "std-float"}),
min_value=0.125)
bp = forms.FloatField(widget=forms.TextInput(attrs={"class": "std-float"}))
a = forms.FloatField(widget=forms.TextInput(attrs={"class": "std-float"}), min_value=0.0)
g = forms.FloatField(widget=forms.TextInput(attrs={"class": "std-float"}))
pfo = forms.FloatField(widget=forms.TextInput(attrs={"class": "std-float"}))
pfi = forms.FloatField(widget=forms.TextInput(attrs={"class": "std-float"}))
de = forms.FloatField(widget=forms.TextInput(attrs={"class": "std-float"}))
pb = forms.FloatField(required=False, widget=forms.TextInput(attrs={"class": "std-float"}))
ts = forms.FloatField(required=False, widget=forms.TextInput(attrs={"class": "std-float"}),
min_value=0.125)
tcp = forms.FloatField(required=False, widget=forms.TextInput(attrs={"class": "std-float"}),
min_value=0.125)
bcp = forms.FloatField(required=False, widget=forms.TextInput(attrs={"class": "std-float"}),
min_value=0.125)
td = forms.FloatField(required=False, widget=forms.TextInput(attrs={"class": "std-float"}),
min_value=0.125)
hcol = forms.FloatField(required=False, widget=forms.TextInput(attrs={"class": "std-float"}),
min_value=0.0)
tshim = forms.FloatField(required=False, widget=forms.TextInput(attrs={"class": "std-float"}),
min_value=0.0625, max_value=0.250)
def clean(self):
...
<extensive custom validation omitted>
...
return cleaned_data
def __unicode__(self):
return self.unique_ID
class Meta:
model = BXEEP_L_Dataset
Наконец, фрагмент из вида:
if form.is_valid():
# Station K
# The form is saved into a new record only if it is valid.
new_dataset = form.save()
# Station L
# We need the new_dataset object so we can get the primary key from it, so we can't just say
# "form.save()."
dataset_id = new_dataset.pk
# Station M
# We reset the dataset_id from False to the new primary key.
#
# Now, with valid form data stored in the correct database record, the normalized version of
# the dataset, form.cleaned_data, may be processed, yielding preliminary analysis results
# in the form of unity checks (ratios) and status lines.
results = analyze_bxeep_l(form.cleaned_data)