2016-05-22 6 views
0

私のアプリケーションには、選択肢の静的配列からデータを取り込む複数のフィールド(チェックボックスが多いと思います)があります。私は、ユーザーが複数の項目を選択できるようにしたいと結果はカンマで区切られた文字列としてデータベースに保存されますが、Djangoの検証が(例えば)を示す保持:Django ModelFormの選択肢の配列をプリセットリストに対して検証する方法

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

答えて

1

これはBiomSearchJobとEcosystemChoices間の多対多の関係のためのユースケースです。これは、カバーの下にあなたのための中間のテーブルを実装します。

EDIT:下記の例の実装を追加:

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

+0

関数のrelated_name引数について説明できますか? –

+0

related_name:[related_name_caveats](https://docs.djangoproject.com/en/1.9/topics/db/models/#be-careful-with-related-name)のドキュメントに記載されているこの注意事項を確認してください。 –

+0

さて、ついにこのアプローチを理解した。ありがとう! –

関連する問題