【问题标题】:How to create a dynamic Django choice field如何创建动态 Django 选择字段
【发布时间】:2017-09-03 03:31:58
【问题描述】:

我正在尝试生成一个列表来填充表单的选项。该列表将是动态的,并且取决于其他用户创建的选择。以下是列表应源自的模型示例:

#models.py
class User(models.Model):
    brewery_you_work_for = models.CharField(choises=ALL_THE_BREWERIES_IN_THE_WORLD)
    username = models.CharField()

我希望表单是这样的:

#forms.py
class BestBrewery(forms.Form):
    vote = forms.ChoiceField(choices=BREWERIES_A_USER_WORKS_FOR)

我想要做的是列出世界上所有啤酒厂的列表,供一些用户选择作为他们工作的啤酒厂。然后我想生成一个列表,让其他用户投票选出最佳啤酒厂。

假设我有 3 个用户声称他们在 Sierra Nevada 工作,2 个用户声称他们在 Budweiser 工作,5 个用户声称他们在 Coors 工作。

我想生成如下所示的啤酒厂列表:

(
'Budweiser',
'Coors,
'Sierra Nevada',
)

注意字母顺序,不要重复啤酒厂列表。

【问题讨论】:

    标签: python django list


    【解决方案1】:

    初始化表单时,您需要传递一个额外的user 参数。如果你使用视图函数,通常是这样的:

    form = BestBrewery(request.user)
    

    如果您使用基于类的视图,您应该覆盖视图中的get_form_kwargs 方法:

    def get_form_kwargs(self):
        kwargs = super(MyView, self).get_form_kwargs()
        kwargs['user'] = self.request.user
    
        return kwargs
    

    您的表单应如下所示:

    class BestBrewery(forms.Form):
    
        def __init__(self, user, *args, **kwargs):
            super(BestBrewery, self).__init__(*args, **kwargs)
    
            self.fields['vote'].choices = (
                user.brewery_you_work_for,
                user.get_brewery_you_work_for_display()
            )
    

    请注意,要覆盖 choices 字段,您需要提供包含表单值和要在下拉菜单中显示的文本的元组。

    【讨论】:

      【解决方案2】:

      嗯,我认为你可以将“选择”设置为函数的结果。 我试过这样:

      def yolo():
          # there we will get stats from db and return choices depends on stats
          first_query = 1  # there U will use more complicated logic :)
          second_query = 3
          if first_query > second_query:
              return (1, 2, 3)
          else:
              return (1, 3)
      
      class Event(models.Model):
          date = models.DateField(primary_key=True)
          count_of_updates = models.SmallIntegerField(default=0)
          yolos = models.CharField(max_length=255, choices=yolo())
      

      而且,为了确保你可以用丑陋的东西检查你的选择:

      choices = s._meta.get_field_by_name('yolos')[0].choices
      print choices
      

      您可以在 func 逻辑中设置的顺序和其他内容 :)

      【讨论】:

      • 这种方法的问题是选项在运行时不会更新,只有在应用重启时才会更新
      【解决方案3】:

      在您的表单中,您可以在 init 中更改字段的选择。

      class BestBrewery(forms.Form):
          vote = forms.ChoiceField()
      
          def __init__(self, *args, **kwargs):
              super(BestBrewery, self).__init__(*arg, **kwargs)
      
              # get the choices from where you need
              choices = (...)
              self.fields['vote'].choices = choices
      

      【讨论】:

        猜你喜欢
        • 2011-03-26
        • 1970-01-01
        • 2016-04-18
        • 2012-04-23
        • 2019-01-20
        • 2018-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多