[英]Django: create multi choice form with input option
我想詢問是否有人知道如何在一個選項中添加輸入的表單中進行選擇
在我的forms.py中:
class InRes(forms.ModelForm):
class Meta:
model=Results
在我的models.py中:
PORT_STATUS=(
('FTP','21'),
('HTTP','443,80'),
)
class Results(models.Model):
status=models.CharField(max_length=5, choices=PORT_STATUS, default='HTTP')
我想添加和選項選擇其中一個選項或輸入我自己的輸入。 有任何想法嗎?
當談到什么是有效的選擇時,Django形式非常挑剔,這是一件好事。 它可以防止惡意值通過操縱的POST數據傳入。
因此,您將無法以編程方式為一個選項添加選項,因為您的選擇是一個硬編碼的元組,兩個,因為您添加的任何選項都不會成為表單在clean
時認為有效的選項的一部分運行,因為初始化表單時該值不存在。
相反,考慮將選擇作為單獨的模型,並提供單獨的表單字段來為該模型添加記錄,以便下次選擇將存在。
Django表單可以混合使用模型和非模型字段,因此使用它來添加輸入字段。 您還可以通過JavaScript控制額外字段的可見性。 可能將所有這些組合成一個自定義字段的多小部件。
# theoretical code, not tested
class PortStatus(models.Model):
status = models.CharField(max_length=100)
def __unicode__(self):
return self.status
# I prefer singular model names
class Result(models.Model):
status = models.ForeignKey(PortStatus, blank=True)
class ResultsForm(forms.ModelForm):
class Meta:
model = Result
extra_choice = forms.CharField(max_length=100, required=False)
def __init__(self, *args, **kwargs):
super(ResultsForm, self).__init__(*args, **kwargs)
self.save_new_status = False
def clean(self):
cleaned_data = self.cleaned_data()
status = cleaned_data.get('status')
extra_choice = cleaned_data.get('extra_choice')
if status and extra_choice:
raise forms.ValidationError("Can't specify both")
if not status and not extra_choice:
raise forms.ValidationError('Make a selection or add status')
if not status and extra_choice:
# make sure extra_choice isn't already in choices
if PostStatus.objects.filter(
status__iexact=extra_choice).count() > 0:
raise forms.ValidationError('Status present, etc')
else:
self.save_new_status = True
return cleaned_data
def save(self, commit=True)
instance = super(ResultsForm, self).save(commit=False)
if self.save_new_status:
new_status = PostStatus.objects.create(
status=self.cleaned_data.get('extra_choice'))
self.status = new_status
if commit:
instance.save()
return instance
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.