[英]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.