我有一个类似的模型:
CAMPAIGN_TYPES = (
('email','Email'),
('display','Display'),
('search','Search'),
)
class Campaign(models.Model):
name = models.CharField(max_length=255)
type = models.CharField(max_length=30,choices=CAMPAIGN_TYPES,default='display')
表格:
class CampaignForm(ModelForm):
class Meta:
model = Campaign
有没有办法限制“类型”字段可用的选项?我知道我可以做一个单值字段:CampaignForm(initial={'name':'Default Name'})
但是我找不到任何方法来为选择集做这个。
答案 0 :(得分:6)
这就是我限制显示选项的方式:
在forms.py中为表单添加 init 方法
class TaskForm(forms.ModelForm):
....
def __init__(self, user, *args, **kwargs):
'''
limit the choice of owner to the currently logged in users hats
'''
super(TaskForm, self).__init__(*args, **kwargs)
# get different list of choices here
choices = Who.objects.filter(owner=user).values_list('id','name')
self.fields["owner"].choices = choices
答案 1 :(得分:1)
选择仅适用于列表,不适用于CharFields。您需要做的是创建custom validator on clean()
。
CAMPAIGN_TYPES = ('email', 'display', 'search')
# this would be derived from your Campaign modelform
class EnhancedCampaignForm(CampaignForm):
# override clean_FIELD
def clean_type(self):
cleaned_data = self.cleaned_data
campaign_type = cleaned_data.get("type")
# strip whitespace and lowercase the field string for better matching
campaign_type = campaign_type.strip().lower()
# ensure the field string matches a CAMPAIGN_TYPE, otherwise
# raise an exception so validation fails
if not campaign_type in CAMPAIGN_TYPE:
raise forms.ValidationError("Not a valid campaign type.")
# if everything worked, return the field's original value
return cleaned_data
答案 2 :(得分:1)
通过覆盖'type'字段,这似乎是最好的方法:
class CampaignForm(ModelForm):
type = forms.ModelChoiceField(queryset=OtherModel.objects.filter(type__id=1))
class Meta:
model = Campaign
我现在不确定如何传递'1'但即使它需要硬编码也会很好。此外,它让Django完成了大部分繁重的工作。
@soviut我会将字段名称更改为非保留字。谢谢您的提醒。