【问题标题】:How to get multiple values from a model field into a form choice field?如何从模型字段中获取多个值到表单选择字段中?
【发布时间】:2022-11-27 15:32:55
【问题描述】:

我有一个名为 Listing 的模型,它有一个名为 categories 的字段,用于存储所有不同的类别。还有一个带有名为 categories 的字段的表单,它应该向用户显示一个选择字段,其中的选择应该是存储在 Listing.categories 模型字段中的值。所以我试图遍历它,但这是不可能的,因为选择字段值以 dict 格式存储。

那么如何将模型字段中的值放入选择字段中呢?

模型.py

class Category(models.Model):
    name = models.CharField(max_length=50)


class Listing(models.Model):
    ...
    category = models.ForeignKey(Category, on_delete=models.PROTECT, null=True)

表格.py:

from .models import Listing

for i in Listing.category:
    category_choices = (
        (i, Listing.category)
    )


class NewListing(forms.Form):
    ...
    category = forms.ChoiceField(choices=category_choices)

【问题讨论】:

    标签: python django django-models django-forms


    【解决方案1】:

    您可以使用 ModelChoiceField 来传递查询集并允许用户在此查询集中的所有模型之间进行选择。 然后你会得到类似的东西:

    category = forms.ModelChoiceField(queryset=Category.objects.all())
    

    【讨论】:

    • 它有效,但我只需要确保从行中的 models.py 导入类别:from .models import Category
    【解决方案2】:

    对我来说,我是这样做的:

    楷模(选择字段在您的模型中)

       CATEGORYCHOICES=(
        (1, 'New'),
        (2, 'Refurbished'),
        (3, 'Opened'),
        (4, 'Used'),
    )
        
        class Listing(models.Model):
        ...
        categories = models.IntegerField(choices=CATEGORYCHOICES,default=0)
    

    然后在您的 forms.py 中,您将需要使用“表单选择”

    class NewListing(ModelForm):
        class Meta:
            model = Listing
            fields = ('field_name1','field_name2')
            
            labels ={
                'field_name1': '',
                'field_name2': '',
            }
            widgets = {
                        'field_name1':forms.Select(attrs={'class':'form-control'}),
                        'field_name2': forms.Select(attrs={'class':'form-control'}),
              }
    

    是否有意义?

    您显然需要在 views.py 中处理该数据。如果您有任何问题,请告诉我,我很乐意分享我的代码。

    【讨论】:

      【解决方案3】:

      如果Category 是模型,那么您的condition_choices 应该是多余的,如果这些选项是硬编码的,为什么还要使用模型?不要只使用forms.Form,您应该使用模型形式forms.ModelForm。然后,您可以通过查询集传递您的类别选择:

      class ListingForm(forms.ModelForm):
         self.categories = Category.objects.all()
         super(ListingForm, self).__init__(*args, **kwargs)
         self.fields['categories'].queryset = self.categories
      

      【讨论】:

        【解决方案4】:

        此处显示的类定义在模型初始化之前执行。因此,您必须做一些动态的事情来构建表单类或修补它的选择。

        我刚刚在控制台上试过这个,它似乎有效。定义 BaseForm 以及您不想在运行时摆弄的所有字段:

        class BaseForm( forms.Form): 
            something = forms.WhateverField( args)
            ...
        

        省略您的动态选择字段。在运行时,比如在基于类的视图的 get_form_class 方法中,使用 3 参数 type 构建您想要的表单。

        我不太清楚什么查询集返回类别集,所以修改这段代码

        class SomethingView( FormView): 
            ...
            def get_form_class( self):
        
            # interrogate the DB to get a list of categories, or categories and labels.
        
                 choices = list( enumerate(categories) ) # [ (0,'cat0'), (1,'cat1'), ...]
                 choicefield = forms.ChoiceField( choices=choices, ...)
        
                 return type('My_runtime_form',
                     (BaseForm, ),
                     { 'category': choicefield }
                 ) 
        

        如果您有一个数据库表 Categories 包含一对值 choice_valuechoice_label 那么您可以获得如下选择

        choices = Category.objects.filter( ... # maybe via a ManyToMany relation
            ).values_list('choice_value', 'choice_label')
        

        【讨论】:

          猜你喜欢
          • 2011-02-04
          • 1970-01-01
          • 2021-09-18
          • 1970-01-01
          • 2020-07-09
          • 2020-07-07
          • 1970-01-01
          • 1970-01-01
          • 2019-09-12
          相关资源
          最近更新 更多