Ich versuche, ein Objekt zu generieren, das Werte in einer Standardeinheit gespeichert, aber in verschiedenen Einheiten basierend auf den Einstellungen für das Projekt angezeigt werden kann. Unten ist ein Beispiel, wo ich die Temperatur eines Raumes speichern kann. Ich möchte, dass der Datenbankwert zur Vereinfachung der Berechnungen in Kelvin ist, möchte aber, dass die Benutzer F oder C anzeigen oder eingeben können, wie es das Projekt erfordert.Django ändern Modelldaten vor dem Rendern ModelForm
Das Modell kann die Werte aus einem Formular übernehmen und beim Speichern in Kelvin konvertieren. Ich weiß, dass dies in der Form gemacht werden kann, aber ich habe es hier für andere Dateneingabemethoden. Eine gestreifte abgespeckte Version des Modells ist wie folgt:
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)
ich eine Modelform in Create und UpdateView verwenden erstellt. Ich brauchte das ModelForm, um das queryset für andere Felder zu begrenzen (das funktioniert gut). Hier konnte ich das Temperaturfeld auf die gewünschten Einheiten für ein neues Objekt in Create konvertieren, aber ich kann nicht scheinen, den Weg zu finden dies für einen bestehenden Datensatz
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']
Für eine gute Maßnahme ziehen aus, hier sind die Ansichten, die diese Form aufrufen.
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
In den Vorlagen (nicht Formulare) verwende ich dies, um die Temperatur korrekt anzuzeigen.
{{ room.temperature|convert_temperature:room.plant.temperature_scale }}
Ich nehme an, ich brauche das Teil zu ergänzen, wo die Modelform die Daten aus dem Datenbank-Datensatz importiert, aber ich konnte nicht erkennen, wo diese im Code django.forms Quelle passiert.
Ich habe versucht, diese manuell in der Shell-Aufruf
>>> 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()
und das gerenderte Form wird mit dem falschen Wert für die Temperatur wie folgt
<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
Ich verwende 1.10.3 Django-Version, wenn es möglich, das ist ein Fehler.
Hallo Brian, hast du convert.temperature selbst geschrieben, oder gibt es ein fertiges Paket, das ich vermisse? Ich möchte mich an Konventionen halten, gibt es irgendwelche :) – gabn88
Ich schrieb mein eigenes Convert-Modul. Ich habe eine Reihe von Verweisen auf Pint gesehen, aber ich fand die Syntax verwirrend. –