我的应用程序中有以下模型表单,其中包含从静态选择数组中填充的多选字段(很多复选框)。我希望用户能够选择多个项目,结果将作为以逗号分隔的字符串存储在数据库中,但Django验证会一直显示(例如):
>>> bsf = BiomSearchForm({"otu_text": ["Test"], "criteria":"soil"})
>>> bsf.errors
{'otu_file': ['This field is required.']}
>>> bsf = BiomSearchForm({"otu_text": ["Test"], "criteria":["soil", "geothermal"]})
>>> bsf.errors
{'otu_file': ['This field is required.'], 'criteria': ["Select a valid choice. ['soil', 'geothermal'] is not one of the available choices."]}
这些选项存储在数据库中以供记录,它们不与任何其他表绑定。有没有办法迭代提交的多选数组并检查组成字符串是否可用?我发现如果我们传递一个字符串而不是一个数组,它将正确验证。
以下是我的模型及其形式:
class BiomSearchJob(models.Model):
ECOSYSTEM_CHOICES = (
("all", "All Ecosystem"),
("animal", "Animal/Human"),
("anthropogenic", "Anthropogenic"),
("freshwater", "Freshwater"),
("marine", "Marine"),
("soil", "Soil"),
("plant", "Plant"),
("geothermal", "Geothermal"),
("biofilm", "Biofilm"),
)
user = models.ForeignKey(User, on_delete=models.CASCADE)
completed = models.BooleanField(default=False)
criteria = models.CharField(
default="all", choices=ECOSYSTEM_CHOICES, max_length=200,
)
otu_text = models.TextField(default=None)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def set_completed(self, completed):
self.completed = completed
class BiomSearchForm(forms.ModelForm):
class Meta:
model = BiomSearchJob
fields = {
"otu_text": forms.CharField,
"otu_file": forms.FileField,
"criteria": forms.MultipleChoiceField(
required=True,
),
}
labels = {
"otu_text": "Paste your BIOM table",
"criteria": "Select the ecosystem",
}
widgets = {
"otu_text": forms.Textarea(attrs={'cols': 30, 'rows': 12}),
"criteria": forms.CheckboxSelectMultiple,
}
otu_file = forms.FileField(
label="or upload your BIOM file",
)
答案 0 :(得分:1)
这是BiomSearchJob和EcosystemChoices之间ManyToMany关系的一个用例。这将为您实现一个中间表。
编辑:在下面添加一个示例实现:
class BiomSearchJob(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
completed = models.BooleanField(default=False)
criteria = models.ManyToManyField('EcosystemChoices', related_name='%(app_label)s_%(class)s_prs', blank=True)
otu_text = models.TextField(default=None)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def set_completed(self, completed):
self.completed = completed
class EcosystemChoices(models.Model):
ecosystem = models.CharField(verbose_name=u'Ecosystem Type', max_length=60, help_text='Select all that apply')
使用您定义的选项预填充EcosystemChoices表。这可能有所帮助:Django ManyToMany Field