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, которые Instantiate формы и передают в начальном значении следующим образом:

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

Но в идеале я хотел бы избежать этого, так как я пытаюсь придерживаться общей базы Джанго просмотров (которые выглядят как это, и не позволяют за 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

В основном это делается в 'get()', используя методы, предоставленные Django. 'self.get_form_kwargs()' содержит ''initial': {'devices': 42}', но он по-прежнему не устанавливается ни с идентификатором, ни с объектом (что это должно быть?). Позаботьтесь о моем обновленном вопросе? – 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