Django表单;使用ModelForm替代选择

时间:2018-12-17 07:29:49

标签: python django django-forms

我要做的是根据页面隐藏或显示某些选择。 例如,

models.py

USA = 'usa'
FRANCE = 'france'
CHINA = 'china'
GERMANY = 'germany'
SPAIN = 'spain'

TOPICS = (
    (USA, 'USA'),
    (FRANCE, 'France'),
    (CHINA, 'China'),
    (GERMANY, 'Germany'),
    (SPAIN, 'Spain'),
        )

topic = models.CharField(
    choices=TOPICS,
    default=USA,
    )

对于页面,我想强迫用户不要选择USA,所以我想在表单中隐藏USA并更改默认值。我该怎么办?

这是我当前的代码。     AForm(forms.ModelForm)类:

    class Meta:
        model = A
        fields = ['topic',]

    def __init__(self, *args, **kwargs):


        super().__init__(*args, **kwargs)

                self.fields['topic'].choices = ['France', 'Germany', 'Spain']

有错误。

  

ValueError:太多值无法解包(预期2)

,我将其替换为随机的两个字符,例如ab,即使我没有在模型上定义它,也可以选择其中一个字符出现在表单上。我仍然不明白如何将覆盖的选择与模型相关联。 ModelForm的正确方法是什么?

3 个答案:

答案 0 :(得分:0)

如Pjot在评论中所述,您可以在表单的__init__方法上动态填充值

# put this two on the top of your forms.py, remove them later if you wish
from pprint import pprint
logger = logging.getLogger(__name__)

class YourForm(Form):
    # you may set an empty choices list here, we'll override it later
    a_choicefield = ChoiceField(label="My choice field", choices=[('', '---------')])

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

        # add this log output to inspect the inner guts of your Form/ModelForm
        logger.warn(pprint(vars(self)))

        # here you may get params from args or kwargs comming from elsewhere
        # so you may fill the choices list accordingly

        my_dynamic_choices = []

        if kwargs['foo']:
            my_dynamic_choices = [A, B, C]
        else:
            my_dynamic_choices = [C, D, E]

        self.fields['a_choicefield'] = ChoiceField(label="My choice field", choices=my_dynamic_choices)

答案 1 :(得分:0)

我找到了一种简单的方法。可以像这样覆盖。

self.fields['field_name'].choices = list(self.fields['field_name'].choices)[:3]

答案 2 :(得分:0)

这与ModelForm无关,但与选择的定义方式有关-选择应该是(value, label)元组的列表(请看您如何在模型中定义选择),而不是值的列表。您想要的是:

self.fields['topic'].choices = [
  ('france','France'), 
  ('germany', 'Germany'), 
  ('spain', 'Spain')
  ]

或(更好):

self.fields['topic'].choices = [
   choice for choice in YourModel.TOPICS
   if choice[0] in ('france', 'germany', 'spain')
   ]