0

我在 Ubuntu 12.10 上使用 Django 1.4 和 Python 2.7。

我有一个表单,我需要动态地填充一些下拉列表(使用 jQuery),但需要其中 2 个是必需的,而第 3 个是可选的。

我正在使用 Tastypie 来帮助 API 获取选项。基本上,第一个下拉列表中填充了学校的行业级代码。选择代码后,将为该代码的所有类别填充类别下拉列表。选择类别后,将为该代码和类别组合的所有子类别填充子类别下拉列表。

我可以要求下拉代码(它不是动态填充的)。但是,我很难让类别下拉列表成为必需。基本上我可以采取 2 条路线 - 前端验证或后端验证。我正在尝试进行后端验证,以便在需要时轻松创建进一步的验证。

这是表格:

class SchoolProductForm(forms.ModelForm):
    cip_category = forms.ChoiceField(required=True,
                                     choices=(('', '----------'),))

    def __init__(self, *args, **kwargs):
        super(SchoolProductForm, self).__init__(*args, **kwargs)

        self.fields['short_description'].widget = TA_WIDGET
        self.fields['salary_info'].widget = TA_WIDGET
        self.fields['job_opportunities'].widget = TA_WIDGET
        self.fields['related_careers'].widget = TA_WIDGET
        self.fields['meta_keywords'].widget = TI_WIDGET
        self.fields['meta_description'].widget = TI_WIDGET
        self.fields['cip'].queryset = models.CIP.objects.filter(
            parent_id__isnull=True)


    class Meta:
        model = models.SchoolProduct
        exclude = ('campus',)

我试图覆盖该clean方法。我试图创建一个特定于字段的clean方法。两者似乎都不起作用。

以下变体:

def clean(self):
    super(SchoolProductForm, self).clean()
    if cip_category in self._errors:
        del self._errors['cip_category']
    if self.cleaned_data['cip_category'] == '----------':
        self._errors['cip_category'] = 'This field is required.'

    return self.cleaned_data

这给出了一个没有cip_categoryin的错误,cleaned_data这是有道理的,因为它没有验证。

我已经尝试了特定领域清洁的变体:

def clean_cip_category(self):
    data = self.cleaned_data['cip_category']
    self.fields['cip_category'].choices = data

    return data

但是在页面上出现验证错误,说明我的选择不是可用的选择之一。

我试图创建一个动态字段类型(几种变体):

class DynamicChoiceField(forms.ChoiceField):
    def valid_value(self, value):
        return True

class SchoolProductForm(forms.ModelForm):
    cip_category = DynamicChoiceField(required=True,
                                      choices=(('', '----------'),))

但它接受----------为有效选项(我不想要)并导致错误,因为 ORM 尝试匹配----------数据库中的值(它不会找到)。

有任何想法吗?

4

1 回答 1

1

我能够通过稍微覆盖ChoiceField.

我将该字段添加到表单并使用以下方法处理预填充self.initial

class SchoolProductForm(forms.ModelForm):
    cip_category = common_forms.DynamicChoiceField(
        required=True, choices=(('', '----------'),))

    def __init__(self, *args, **kwargs):
        super(SchoolProductForm, self).__init__(*args, **kwargs)

        self.fields['short_description'].widget = TA_WIDGET
        self.fields['salary_info'].widget = TA_WIDGET
        self.fields['job_opportunities'].widget = TA_WIDGET
        self.fields['related_careers'].widget = TA_WIDGET
        self.fields['meta_keywords'].widget = TI_WIDGET
        self.fields['meta_description'].widget = TI_WIDGET
        self.fields['cip'].queryset = models.CIP.objects.filter(
            parent_id__isnull=True)

        # Get the top parent and pre-populate
        if 'cip' in self.initial:
            self.initial['cip'] = models.CIP.objects.get(
                pk=self.initial['cip']).top_parent()

    class Meta:
        model = models.SchoolProduct
        exclude = ('campus',)

在哪里DynamicChoiceField

class DynamicChoiceField(forms.ChoiceField):
    def valid_value(self, value):
        return True

然后,在视图中,我在form_valid覆盖中添加了处理:

def form_valid(self, form):
    self.object = form.save(commit=False)

    # Handle the CIP code
    self.object.cip_id = self.request.POST.get('cip_subcategory')
    if self.object.cip_id == '':
        self.object.cip_id = self.request.POST.get('cip_category')

    self.object.save()
于 2012-12-05T16:15:26.280 回答