问题:创建动态选择字段
我在尝试了解如何在Django中创建动态选择字段时遇到了一些麻烦。我有一个模型设置类似:
class rider(models.Model):
user = models.ForeignKey(User)
waypoint = models.ManyToManyField(Waypoint)
class Waypoint(models.Model):
lat = models.FloatField()
lng = models.FloatField()
我想做的是创建一个选择字段whos的值是与该骑手相关联的航点(将是登录的人)。
目前,我以如下形式覆盖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()])
但是所有要做的就是列出所有路标,它们与任何特定的骑手都没有关联。有任何想法吗?谢谢。
回答 0
您可以通过将用户传递给表单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
回答 1
有针对您的问题的内置解决方案:ModelChoiceField。
通常,ModelForm
当您需要创建/更改数据库对象时,总是值得尝试使用。在95%的情况下都有效,并且比创建自己的实现要干净得多。
回答 2
问题是你什么时候做
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)])
在更新请求中,先前的值将丢失!
回答 3
在初始化骑乘者实例时将其传递给表单怎么样?
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)
回答 4
在正常选择字段下的工作解决方案下。我的问题是,每个用户都基于很少的条件有自己的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
回答 5
正如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)
但是,这可能会导致一些并发问题。
回答 6
您可以将字段声明为表单的一流属性,并且可以动态设置选项:
class WaypointForm(forms.Form):
waypoints = forms.ChoiceField(choices=[])
def __init__(self, user, *args, **kwargs):
super().__init__(*args, **kwargs)
waypoint_choices = [(o.id, str(o)) for o in Waypoint.objects.filter(user=user)]
self.fields['waypoints'].choices = waypoint_choices
您也可以使用ModelChoiceField并以类似方式在init上设置queryset。
回答 7
如果您需要django admin中的动态选择字段;这适用于Django> = 2.1。
class CarAdminForm(forms.ModelForm):
class Meta:
model = Car
def __init__(self, *args, **kwargs):
super(CarForm, self).__init__(*args, **kwargs)
# Now you can make it dynamic.
choices = (
('audi', 'Audi'),
('tesla', 'Tesla')
)
self.fields.get('car_field').choices = choices
car_field = forms.ChoiceField(choices=[])
@admin.register(Car)
class CarAdmin(admin.ModelAdmin):
form = CarAdminForm
希望这可以帮助。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。