Reputation: 141
class Value(models.Model):
attribute = models.ForeignKey(Attribute)
platform = models.ForeignKey(Platform)
value = models.CharField(max_length=30)
class Attribute(models.Model):
name = models.CharField(max_length=50)
....
1.
for attribute in attributes:
attribute.value = Value.objects.get(Q(attribute__id=attribute.id) & Q(platform__id=platform.id))
2.
values = Value.objects.filter(platform__id=platform.id)
for attribute in attributes:
attribute.value = values.get(attribute__id=attribute.id)
Can I say the method 2 is more efficient than 1 because it prevents excessive DB query?
Upvotes: 0
Views: 79
Reputation: 32244
Example 2 can be reduced to only 1 DB query like so:
values = Value.objects.filter(platform__id=platform.id)
attribute_values = {value.attribute_id: value for value in values}
for attribute in attributes:
attribute.value = attribute_values[attribute.id]
I'm assuming that Value.attribute is a ForeignKey
Upvotes: 2
Reputation: 25539
I wouldn't say that's the case, because filter
and get
are just building up some where
statements for sql query. You might think that django is caching the value values
because you only do it once, but the query is not even evaluated when you do:
values = Value.objects.filter(platform__id=platform.id)
Every time you call get
, it's adding a where
statement upon the filter
statement and hit the database to fetch the results, so you don't gain anything in terms of performance.
By the way, Value.objects.get(Q(attribute__id=attribute.id) & Q(platform__id=platform.id))
is the same as:
Value.objects.get(attribute=attribute, platform=platform)
which is more readable.
Upvotes: 2