簡體   English   中英

在基於類的視圖中為動態創建的ModelChoiceField設置初始值

[英]Set initial value for dynamically created ModelChoiceField in Class Based View

我正在創建一個具有ModelChoiceFieldForm 我可以如下設置該字段的值:

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變形):

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

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

因為self.get_form_kwargs()返回:在get_initial()設置設備應該可以工作。

{'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))

在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

有人知道實現此目標的方法嗎?

您需要使用建議的方式來分配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})

由於您已經覆蓋了表單的__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

最后,在模板方面,這是我的愚蠢錯誤。 該值實際上已在視圖中正確設置,但是我忘記在模板中設置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 %}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM