首页 文章

创建动态选择字段

提问于
浏览
121

我在尝试理解如何在django中创建动态选择字段时遇到了一些麻烦 . 我有一个模型设置类似于:

class rider(models.Model):
     user = models.ForeignKey(User)
     waypoint = models.ManyToManyField(Waypoint)

class Waypoint(models.Model):
     lat = models.FloatField()
     lng = models.FloatField()

我要做的是创建一个选择字段,其值是与该骑手相关联的航点(可以是登录的人) .

目前我在我的表单中覆盖init,如下所示:

class waypointForm(forms.Form):
     def __init__(self, *args, **kwargs):
          super(joinTripForm, self).__init__(*args, **kwargs)
          self.fields['waypoints'] = forms.ChoiceField(choices=[ (o.id, str(o)) for o in Waypoint.objects.all()])

但所有这一切都是列出所有航点,它们与任何特定的骑手没有联系 . 有任何想法吗?谢谢 .

6 回答

  • 4

    您可以通过将用户传递给表单init来过滤航点

    class waypointForm(forms.Form):
        def __init__(self, user, *args, **kwargs):
            super(waypointForm, self).__init__(*args, **kwargs)
            self.fields['waypoints'] = forms.ChoiceField(
                choices=[(o.id, str(o)) for o in Waypoint.objects.filter(user=user)]
            )
    

    在启动表单时从您的视图传递用户

    form = waypointForm(user)
    

    在模型形式的情况下

    class waypointForm(forms.ModelForm):
        def __init__(self, user, *args, **kwargs):
            super(waypointForm, self).__init__(*args, **kwargs)
            self.fields['waypoints'] = forms.ModelChoiceField(
                queryset=Waypoint.objects.filter(user=user)
            )
    
        class Meta:
            model = Waypoint
    
  • 9

    有针对您的问题的内置解决方案:ModelChoiceField .

    通常,当您需要创建/更改数据库对象时,始终值得尝试使用 ModelForm . 在95%的情况下工作,它比创建自己的实现更清洁 .

  • 1

    问题是当你这样做的时候

    def __init__(self, user, *args, **kwargs):
        super(waypointForm, self).__init__(*args, **kwargs)
        self.fields['waypoints'] = forms.ChoiceField(choices=[ (o.id, str(o)) for o in Waypoint.objects.filter(user=user)])
    

    在更新请求中,之前的值将丢失!

  • 7

    如何在初始化时将rider实例传递给表单?

    class WaypointForm(forms.Form):
        def __init__(self, rider, *args, **kwargs):
          super(joinTripForm, self).__init__(*args, **kwargs)
          qs = rider.Waypoint_set.all()
          self.fields['waypoints'] = forms.ChoiceField(choices=[(o.id, str(o)) for o in qs])
    
    # In view:
    rider = request.user
    form = WaypointForm(rider)
    
  • 2

    在具有正常选择字段的工作解决方案下 . 我的问题是每个用户都有基于几个条件的自己的CUSTOM选择字段选项 .

    class SupportForm(BaseForm):
    
        affiliated = ChoiceField(required=False, label='Fieldname', choices=[], widget=Select(attrs={'onchange': 'sysAdminCheck();'}))
    
        def __init__(self, *args, **kwargs):
    
            self.request = kwargs.pop('request', None)
            grid_id = get_user_from_request(self.request)
            for l in get_all_choices().filter(user=user_id):
                admin = 'y' if l in self.core else 'n'
                choice = (('%s_%s' % (l.name, admin)), ('%s' % l.name))
                self.affiliated_choices.append(choice)
            super(SupportForm, self).__init__(*args, **kwargs)
            self.fields['affiliated'].choices = self.affiliated_choice
    
  • 172

    正如Breedly和Liang指出的那样,Ashok的解决方案将阻止您在发布表单时获得选择值 .

    一种稍微不同但仍然不完美的解决方法是:

    class waypointForm(forms.Form):
        def __init__(self, user, *args, **kwargs):
            self.base_fields['waypoints'].choices = self._do_the_choicy_thing()
            super(waypointForm, self).__init__(*args, **kwargs)
    

    但是,这可能会导致一些并发问题 .

相关问题