简体   繁体   English

如何根据预设的选择列表验证Django ModelForm中的选择数组

[英]How to validate array of choices in Django ModelForm against preset list of choices

I have the following model form in my application which features a multiple choice field (think lots of checkboxes) populated from a static array of choices. 我的应用程序中具有以下模型形式,其特征是从静态选择数组中填充的多选字段(认为很多复选框)。 I want users to be able to select multiple items and the result will be stored in the database as a string separated by commas but the Django validation keeps showing (for example): 我希望用户能够选择多个项目,并且结果将以逗号分隔的字符串形式存储在数据库中,但是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."]}

These choices are stored in the database for record purposes, they are not tied to any other tables. 这些选择存储在数据库中用于记录目的,它们不与任何其他表绑定。 Is there a way to iterate through the submitted multiple choice array and check if the constituent strings are of the available choices? 有没有一种方法可以遍历提交的多项选择数组,并检查组成字符串是否属于可用选项? I found out that if we pass a single string instead of an array, it will validate correctly. 我发现,如果我们传递单个字符串而不是数组,则它将正确验证。

Here are my model and its form: 这是我的模型及其形式:

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",
    )

This is a use case for ManyToMany relationship between BiomSearchJob and EcosystemChoices. 这是BiomSearchJob与EcosystemChoices之间的ManyToMany关系的用例。 This will implement an intermediate table for you under the covers. 这将为您实施一个中间表。

EDIT: Adding an example implementation below: 编辑:在下面添加示例实现:

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')

Pre-fill the table EcosystemChoices with your defined choices. 使用定义的选项预填充表EcosystemChoices。 This may help: Django ManyToMany Field 这可能会有所帮助: Django ManyToMany字段

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM