[英]Django Forms; Overiride choices with ModelForm
What I want to do is to hide or show some of the choices depending on the page. 我想要做的是根据页面隐藏或显示一些选择。 For example,
例如,
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,
)
For a page, I want to force users not to choose USA, so I want to hide USA in form and also change the default value. 对于页面,我想强制用户不要选择USA,所以我想以表格形式隐藏USA并更改默认值。 How can I do this?
我怎样才能做到这一点?
Here is my current code. 这是我当前的代码。 class AForm(forms.ModelForm):
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']
There is an error. 发生错误。
ValueError: too many values to unpack (expected 2)
ValueError:太多值无法解包(预期2)
and I replaced it with random two characters like ab
One of the characters appears on the form as a choice even though I didn't define it on model. 我将其替换为随机的两个字符,例如
ab
,即使我没有在模型上定义它,也可以选择其中一个字符出现在表单上。 I still don't understand how I can associate the overriden choices with model. 我仍然不明白如何将覆盖的选择与模型相关联。 What is the correct way with
ModelForm
? 使用
ModelForm
的正确方法是什么?
As Pjot said in the comments, you can fill the values dynamically on the __init__
method of the form 如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)
I found an easy way to do it. 我找到了一种简单的方法。 Can override like this.
可以像这样覆盖。
self.fields['field_name'].choices = list(self.fields['field_name'].choices)[:3]
This has nothing to do with ModelForm, but with how choices are defined - choices are expected to be a list of (value, label)
tuples (look at how you defined the choices in your model), not a list of values. 这与ModelForm无关,但与选择的定义方式有关-选择应该是
(value, label)
元组的列表(请看您如何在模型中定义选择),而不是值的列表。 What you want is: 您想要的是:
self.fields['topic'].choices = [
('france','France'),
('germany', 'Germany'),
('spain', 'Spain')
]
or (better): 或更好):
self.fields['topic'].choices = [
choice for choice in YourModel.TOPICS
if choice[0] in ('france', 'germany', 'spain')
]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.