0

我正在创建一个Form,它有一个ModelChoiceField。我可以设置此字段的值如下:在基于类的视图中为动态创建的ModelChoiceField设置初始值

class DeviceForm(Form): 
    devices = ModelChoiceField(queryset=None, widget=RadioSelect, empty_label=None) 

    def __init__(self, *args, **kwargs): 
     super(DeviceForm, self).__init__(*args, **kwargs) 
     user_id = kwargs['initial']['user_id'] 
     devices = Device.objects.filter(user_id=user_id, is_validated=True) 
     self.fields['devices'].queryset = devices 

这很好,但我似乎无法设置初始值。我尝试过许多东西,如添加一个初始值get_initial()

def get_initial(self): 
    initial = super(DeviceView, self).get_initial() 
    initial['user_id'] = self.kwargs['user_id'] 
    default_device = Device.objects.get(user_id=self.kwargs['user_id'], is_validated=True, is_default=True) 
    initial['devices'] = default_device.id 
    return initial 

但是,这并不工作。我已经遇到StackOverflow上该实例的形式,并通过在初始值,像这样多的问题:

#Get default device 
form = DeviceForm(initial={'devices': default_device.id}) 

但我非常希望避免它,因为我想坚持Django的通用基础观点(这看起来是这样,而且不允许的initial kwarg据我所知):

def get(self, request, user_id, **kwargs): 
    # Do stuff 

    form = self.get_form() 
    return self.render_to_response(self.get_context_data(form=form)) 

get_initial()设置设备应该工作,因为self.get_form_kwargs()回报:

{'prefix': None, 'initial': {'user_id': u'1', 'devices': 42}} 

,或者根据什么我应该选择:

{'prefix': None, 'initial': {'user_id': u'1', 'devices': <Device: Device object>}} 

执行以下仍然没有得到它的工作(基本上是同样的事情get_form()手动)。

def get(self, request, user_id, **kwargs): 
    #Do stuff 
    form_class = self.get_form_class() 
    form = form_class(**self.get_form_kwargs()) 
    return self.render_to_response(self.get_context_data(form=form)) 

设置在窗体的构造函数的初始值也不起作用:

class DeviceForm(Form): 
    devices = ModelChoiceField(queryset=None, widget=RadioSelect, empty_label=None) 

    def __init__(self, *args, **kwargs): 
     super(DeviceForm, self).__init__(*args, **kwargs) 
     user_id = kwargs['initial']['user_id'] 
     devices = Device.objects.filter(user_id=user_id, is_validated=True) 
     self.fields['devices'].queryset = devices 
     default_device = devices.filter(is_default=True) 
     self.fields['devices'].initial = default_device # or default_device.id 

有谁知道的一种方式做到这一点?

+0

请显示您的看法。 – Alasdair

回答

0

最后,这是我的模板部分愚蠢的错误。该值实际上在视图中正确设置,但我忘记了在模板中设置checked值。我以为这只是使用{{form}},但我没有。只适用于想知道如何手动设置的人:

{% for device in form.devices.field.choices.queryset %} 
    <input type="radio" name="devices" value="{{ device.pk }}" class="radio-device" 
     {% ifequal form.devices.value device.pk %}checked{% endifequal %} 
    /> 
{% endfor %} 
1

您需要使用建议的方式来指定initial,但仍然可以在基于视图的类中使用。从django doc报价:

class MyFormView(View): 
    form_class = MyForm 
    initial = {'key': 'value'} 
    template_name = 'form_template.html' 

    def get(self, request, *args, **kwargs): 
     form = self.form_class(initial=self.initial) 
     return render(request, self.template_name, {'form': form}) 
+0

这基本上是通过使用Django提供的方法在'get()'中完成的。 'self.get_form_kwargs()'包含''initial':{'devices':42}',但它仍然没有被设置为id或object(它需要什么?)。小心看看我更新的问题? – Bono

0

既然你已经覆盖表单的__init__方法,它可能是最容易设置的初始值出现。

class DeviceForm(Form): 
    devices = ModelChoiceField(queryset=None, widget=RadioSelect, empty_label=None) 

    def __init__(self, *args, **kwargs): 
     super(DeviceForm, self).__init__(*args, **kwargs) 
     user_id = kwargs['initial']['user_id'] 
     devices = Device.objects.filter(user_id=user_id, is_validated=True) 
     self.fields['devices'].queryset = devices 
     default_device = Device.objects.get(user_id=user_id, is_validated=True, is_default=True) 
     self.fields['devices'].initial = default_device 
+0

我没有提到它,但我尝试了同样的东西。不幸的是,它似乎并不奏效。 'default_device'不是'default_device.id'(我认为这应该是正确的)。 – Bono

相关问题