Какое большое изменение в версии разработки Django может объяснить эти ошибки? - PullRequest
3 голосов
/ 26 января 2010

Я весело разрабатывал веб-приложение, используя версию для разработки 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)

1 Ответ

1 голос
/ 28 января 2010

Извините, что отвечаю на мой собственный вопрос, но я понял это к моему удовлетворению, и вы могли бы также получить выгоду.

Проблема либо в двух разных ошибках, либо в одной ошибке и одном недоразумении. Подлинная ошибка заключается в том, что выделение с помощью optgroups в значительной степени нарушено в версии для разработки Django, по крайней мере, для использования с формой модели. В Django, когда вам нужны optgroups, вы используете вложенные кортежи для их определения. Историю см. http://code.djangoproject.com/ticket/4412,, а в документации - пример MEDIA_CHOICES по адресу http://docs.djangoproject.com/en/dev/ref/models/fields/.. Моя теория состоит в том, что в настоящее время код проверки изначально не находит значения во внутренних кортежах, поэтому когда проверка выполнена, допустимый выбор может отсутствовать в списке, который проверяется, и определенно не будет в списке, если у вас нет «внешних» опций. Вот билет: http://code.djangoproject.com/ticket/12722.

Вторая ошибка (или недоразумение) заключается в том, что при обычном (не в optgroup) выборе пусто = False, по умолчанию = "A36" не работает, если поле отключено (как в JavaScript) и выбор не сделан. Работало под 1.1.1, но не сейчас. Может быть, это должен быть второй билет, но, возможно, это правильно, и я не понимаю философию. Я изменил на пустое = True, и все хорошо со мной.

Для полноты позвольте мне отметить, что 1) я еще не проверил проблему optgroup в Admin, 2) все это относится к модельной форме, и я не знаю, будут ли проблемы другими, если были моделью без формы модели, и 3) все мои проблемы (в обеих категориях) связаны с CharFields.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...