簡體   English   中英

如何覆蓋 __init__ 添加實例 forms.Form Django

[英]How override __init__ add instance forms.Form Django

我想在我的 forms.Form 中添加一個實例參數,這樣我可以在視圖中對其進行初始化並在我的表單中獲得預期的結果。 我知道我可以使用'initial' ,但我想嘗試一些不同的東西。

視圖.py

city_form = CityForm(instance=user.profile.city)

表格.py

class CityForm(forms.Form):
    post_nr = forms.CharField(max_length=5, widget=forms.TextInput(attrs={'placeholder': 'Post nr.'}))
    city = forms.CharField(required=False, max_length=30, widget=forms.TextInput(attrs={'placeholder': 'By', 'readonly': True}))

    class Meta:
        model = City

    def __init__(self, *args, **kwargs):
        self.instance = kwargs.pop('instance', None)

        if self.instance:
            self.fields['post_nr'] = self.instance.post_code
            self.fields['city'] = self.instance.name

        super(CityForm, self).__init__(*args, **kwargs)

引用的實例將是一個 City 對象,來自我的 City 類,該類具有我在上面指定的變量。

但我得到:

“CityForm”對象沒有屬性“字段”

在您調用super().__init__()之前,表單沒有fields屬性。 您需要將該代碼向下移動。 您當前正在做的是用其值覆蓋字段實例。 相反,您應該設置初始值:

def __init__(self, *args, **kwargs):
    instance = kwargs.get('instance', None)

    super(CityForm, self).__init__(*args, **kwargs)

    if instance:
        self.initial['post_nr'] = instance.post_code
        self.initial['city'] = instance.name

您可能還想看看使用ModelForm

@knbk 發布的答案完美地解決了 OP 的問題。 但在用戶場景中,我想添加一些改進。

def __init__(self, *args, **kwargs):
    instance = kwargs.pop('instance', None)
    super(CityForm, self).__init__(*args, **kwargs)
    if instance:
        self.instance = instance
        if self.data.get('title', None) is None:
            self.initial['title'] = instance.title
  1. 通過繼承forms.Form ,使用pop獲取instance ,因為forms.Form構造函數不需要關鍵字。

  2. 如果傳入實例,請將其分配給表單,以便您可以在保存方法等中使用它。

  3. 始終檢查request.POST是否傳入,如果數據中沒有包含初始值,這意味着您沒有在實例中提交更新表單,只有這樣您才應該覆蓋初始值,否則數據將永遠不會更新。

暫無
暫無

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

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