Reputation: 885
I'm working with my Django app, in which I have two models: Store
and Turn
. There is a one-to-many relationship where a store has many turns that need to be processed. This is the code:
class Store(models.Model):
name = models.CharField(max_length=20)
adress = models.CharField(max_length=40)
image = models.ImageField(upload_to=)
@property
def average_wait_time(self):
return #here's the problem
def __str__(self):
return self.name
class Turn(models.Model):
store = models.ForeignKey(Store, on_delete=models.SET_NULL, null=True)
creation_time = models.TimeField(auto_now=True)
completion_time = models.TimeField(blank=True, null=True)
def complete(self):
self.completion_time = timezone.now()
def __str__(self):
return f'Turno a las {creation_time} para el Negocio {completion_time}'
As you can see, I have a @property
method that I need to use in order to calculate the average wait time in a store, determined by the average of the turn durations. How can I make this work? I cannot access the Turn
model from the 'Store' model...
Upvotes: 0
Views: 325
Reputation: 6815
related_name
What you need is the related_name
argument in ForeignKey
. It works as follows:
store = models.ForeignKey(Store, on_delete=models.SET_NULL, null=True, related_name="turns")
This means you can now access all of the turns of a particular store as follows:
store = Store.objects.get(id=1) # get a store
turns = store.turns
turns
in the above will be a queryset of Turn
objects.
Note also, that if you don't specify a related_name
django actually creates one for you automatically by adding _set
onto the end of the related model name in lowercase, and you can do the same with the following:
turns = store.turn_set
But it's probably better to name the related_name
explicitly.
class Store(models.Model):
...
@property
def average_wait_time(self):
turns = self.turns
total_time = sum([turn.completion_time - turn.creation_time for turn in turns.all()])
average_time = total_time / turns.count()
return average_time
You can also do this using aggregate
and Avg
, but the above is probably fine.
Upvotes: 1