Query preloaded objects without using db?
I am getting multiple objects with predefined relationships from my db:
datei_logs = DateiLog.objects.filter(user=request.user)
.order_by("-pk")
.prefetch_related('transfer_logs')
transfer_logs
refers to this:
class TransferLog(models.Model):
datei_log = models.ForeignKey("DateiLog", related_name="transfer_logs")
status = models.CharField(
max_length=1,
choices=LOG_STATUS_CHOICES,
default='Good'
)
server_name = models.CharField(max_length=100, blank=True, default="(no server)")
server = models.ForeignKey('Server')
class Meta:
verbose_name_plural = "Transfer-Logs"
def __unicode__(self):
return self.server_name
Now I want to get all TransferLogs
that have status "Good"
. But I think that if I do this:
datei_logs[0].transfer_logs.filter(...)
It asks for db again! Since this happens on a website with many log entries, I end up with 900 requests!
I use:
datei_logs[0].transfer_logs.count()
Besides, it also makes a lot of db queries!
What can I do to "just get everything" and then just request an object containing all information instead of db?
source to share
Since you are using Django 1.7, you can use the new objects Prefetch()
to specify the set of queries you want to use for the corresponding search.
queryset = TransferLog.objects.filter(status='Good')
datei_logs = DateiLog.objects.filter(user=request.user)
.order_by("-pk")
.prefetch_related(Prefetch('transfer_logs',
queryset=queryset,
to_attr='good_logs'))
Then you can access datei_logs[0].good_logs
and check len(datei_logs[0].good_logs)
.
If you are interested in multiple statuses, you can simply use multiple objects Prefetch
. But if you get all the logs anyway, you can also use your original query and then split the logs in Python instead of naming filter()
.
source to share