Uno dei miei modelli ha attributi che non sono memorizzati nel database. Tutto va bene alla vista e al livello del modello, ma non riesco a visualizzare questi attributi 'non-database' nel mio modello.Creazione di attributi transitori (non di database) nel modello Django disponibile per il modello
Ecco un esempio di codice, un esempio artificiale che rispecchia l'effettivo dominio del problema, per dimostrare il comportamento indesiderato.
La vista:
def odometer(request):
cars = Car.objects.all()
for car in cars:
car.read_meters()
context = {'cars': cars}
return render_to_response('odometer.html', context)
I modelli:
class Car(models.Model):
name = models.CharField(_('name'), max_length=100, unique=True)
def read_meters(self):
for meter in self.meter_set.all():
meter.read()
def __unicode__(self):
return '%s' % self.name
class Meter(models.Model):
name = models.CharField(_('name'), max_length=100)
car = models.ForeignKey(Car)
difference = 0
previous = 0
changed = False
def read(self):
# this is completely artificial. in the real application we would interface with the hardware
# meter to get data
try:
previous_count = MeterReading.objects.filter(meter__id=self.id).order_by('-stamp')[0].count
except:
previous_count = 0
self.previous = previous_count
current_count = previous_count
if (random.randrange(0, 2) == 0):
self.difference = int(random.random() * 100)
if self.name == 'Odometer' or (random.randrange(0, 2) == 0):
current_count += self.difference
else:
current_count -= self.difference
if current_count < 0:
current_count = 0
if current_count > previous_count:
self.changed = True
new_reading = MeterReading()
new_reading.count = current_count
new_reading.meter = self
new_reading.save()
def __unicode__(self):
return '%s' % self.name
class MeterReading(models.Model):
count = models.IntegerField(_('count'))
stamp = models.DateTimeField(editable=False, auto_now_add=True)
meter = models.ForeignKey(Meter)
def __unicode__(self):
return '%s' % self.count
E il modello:
{% for car in cars %}
<h2>{{ car }}</h2>
{% for meter in car.meter_set.all %}
<h3>{{ meter }}</h3>
<p>Difference: {{ meter.difference }}</p>
<p>Changed: {{ meter.changed }}</p>
<ul>
{% for reading in meter.meterreading_set.all %}
<li>{{ reading }}</li>
{% endfor %}
</ul>
{% endfor %}
{% endfor %}
Il problema è 'meter.difference' e 'meter.changed' don 't produrre i valori aggiornati corretti. Che cosa sto facendo di sbagliato? Qualsiasi consiglio è apprezzato.
Grazie.
UPDATE: Aggiornato il codice in base alla risposta di Daniel:
il modello di auto:
class Car(models.Model):
name = models.CharField(_('name'), max_length=100, unique=True)
def read_meters(self):
for meter in self.meters:
meter.read()
def __unicode__(self):
return '%s' % self.name
@property
def meters(self):
if not hasattr(self, '_meters'):
self._meters = self.meter_set.all()
return self._meters
E il modello:
{% for car in cars %}
<h2>{{ car }}</h2>
{% for meter in car.meters %}
<h3>{{ meter }}</h3>
<p>{{ meter.name }} difference: {{ meter.difference }}</p>
<p>Changed: {{ meter.changed }}</p>
<ul>
{% for reading in meter.meterreading_set.all %}
<li>{{ reading }}</li>
{% endfor %}
</ul>
{% endfor %}
{% endfor %}
Fantastico grazie. –