簡體   English   中英

Django在呈現ModelForm之前更改模型數據

[英]Django alter model data before rendering ModelForm

我正在嘗試生成一個對象,該對象允許將值存儲在標准單位中,但根據項目的設置以不同的單位顯示。 以下是我需要能夠存儲房間溫度的示例。 我希望數據庫值在開爾文中以便於計算,但希望用戶能夠根據項目要求在F或C中查看/輸入。

該模型可以從表單中獲取值並將其保存為開爾文。 我知道這可以通過表格完成,但是我在這里有其他數據輸入方法。 該模型的簡化版本如下:

class Room(models.Model):
    name                = models.CharField(max_length=255)            
    temperature         = models.FloatField(default=293.15)

    def save(self, *args, **kwargs):
        self.temperature = convert.temperature(self.temperature, 
            from_unit=self.plant.temperature_scale)
        super(Room, self).save(*args, **kwargs)

我創建了一個ModelForm以在CreateView和UpdateView中使用。 我需要ModelForm來限制其他字段的查詢集(工作正常)。 在這里,我能夠將溫度場轉換為CreateView中新對象的所需單位,但似乎找不到找到現有記錄的方法

class RoomForm(ModelForm):
    def __init__(self, plant, *args, **kwargs):
        super (RoomForm,self ).__init__(*args,**kwargs)

        self.fields['temperature'].initial = convert.temperature(
            value=self.fields['temperature'].initial, 
            from_unit='K',
            to_unit=self.fields['unit'].queryset[0].plant.temperature_scale)

        self.instance.temperature = convert.temperature(
            value=self.instance.temperature, 
            from_unit='K',
            to_unit=self.fields['unit'].queryset[0].plant.temperature_scale)

    class Meta:
        model = Room
        fields = ['name', 'temperature']

出於良好的考慮,以下是調用此表單的視圖。

class NewRoom(CreateView):
    model = Room
    form_class = RoomForm

    def get_form_kwargs(self, **kwargs):
        form_kwargs = super(NewRoom, self).get_form_kwargs(**kwargs)
        form_kwargs["plant"] = Plant.objects.get(slug=self.kwargs['plant'])
        return form_kwargs    

class EditRoom(UpdateView):
    model = Room
    form_class = RoomForm
    template_name_suffix = "_update_form"

    def get_form_kwargs(self, **kwargs):
        form_kwargs = super(EditRoom, self).get_form_kwargs(**kwargs)
        form_kwargs["plant"] = Plant.objects.filter(slug=self.kwargs['plant'])
        return form_kwargs

在模板(非表格)中,我使用它來正確顯示溫度。

{{ room.temperature|convert_temperature:room.plant.temperature_scale }}

我假設我需要補充ModelForm從數據庫記錄中導入數據的部分,但是我無法確定django.forms源代碼中發生這種情況的地方。

我嘗試在外殼中手動調用此

>>> from rooms.models import *
>>> from rooms.forms import *
>>> room = Room.objects.first()
>>> form = RoomForm(room.plant, instance=room)
>>> form.instance.temperature
20.0 
>>> form.as_p()

並且呈現的形式如下,其中溫度值不正確

<p>
    <label for="id_name">Name:
    </label> 
    <input id="id_name" maxlength="255" name="name" type="text" value="Testing" 
        required />
</p>\n
<p>
    <label for="id_temperature">Temperature:
    </label> 
    <input id="id_temperature" name="temperature" 
        step="any" type="number" value="293.15" required /> 
</p>\n

我正在使用Django 1.10.3版(如果有可能是一個bug)。

要在呈現之前修改現有記錄中的數據,只需在調用父級的__init__之后在self.instance進行操作即可。

def __init__(self, plant, *args, **kwargs):
    super(RoomForm,self ).__init__(*args,**kwargs)
    self.instance.temperature = # ...

盡管lucasnadalutti讓我處於正確的位置,但並沒有成功。 覆蓋傳遞給ModelForm.__init__的實例,並在更改后再次調用它。

class RoomForm(ModelForm):

    def __init__(self, plant, *args, **kwargs):
        super(RoomForm, self).__init__(*args,**kwargs)

        self.instance.temperature = convert.temperature(
            value=self.instance.temperature,
            from_unit='K', to_unit=self.fields['unit'].queryset[0].plant.temperature_scale)

        # Override instance passed to __init__ and call super again
        kwargs['instance'] = self.instance
        super(RoomForm, self).__init__(*args, **kwargs)

    class Meta:
        model = Room
        fields = ['name', 'temperature']

暫無
暫無

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

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