Note that there are some explanatory texts on larger screens.

plurals
  1. PODjango Generic Relations and ORM Queries
    primarykey
    data
    text
    <p>Say I have the following models:</p> <pre><code>class Image(models.Model): image = models.ImageField(max_length=200, upload_to=file_home) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey() class Article(models.Model): text = models.TextField() images = generic.GenericRelation(Image) class BlogPost(models.Model): text = models.TextField() images = generic.GenericRelation(Image) </code></pre> <p>What's the most processor- and memory-efficient way to find all Articles that have at least one Image attached to them?</p> <p>I've done this:</p> <pre><code>Article.objects.filter(pk__in=Image.objects.filter(content_type=ContentType.objects.get_for_model(Article)).values_list('object_id', flat=True)) </code></pre> <p>Which works, but besides being ugly it takes forever.</p> <p>I suspect there's a better solution using raw SQL, but that's beyond me. For what it's worth, the SQL generated by the above is as following:</p> <pre><code> SELECT `issues_article`.`id`, `issues_article`.`text` FROM `issues_article` WHERE `issues_article`.`id` IN (SELECT U0.`object_id` FROM `uploads_image` U0 WHERE U0.`content_type_id` = 26 ) LIMIT 21 </code></pre> <p><strong>EDIT:</strong> czarchaic's suggestion has much nicer syntax but even worse (slower) performance. The SQL generated by his query looks like the following:</p> <pre><code>SELECT DISTINCT `issues_article`.`id`, `issues_article`.`text`, COUNT(`uploads_image`.`id`) AS `num_images` FROM `issues_article` LEFT OUTER JOIN `uploads_image` ON (`issues_article`.`id` = `uploads_image`.`object_id`) GROUP BY `issues_article`.`id` HAVING COUNT(`uploads_image`.`id`) &gt; 0 ORDER BY NULL LIMIT 21 </code></pre> <p><strong>EDIT:</strong> Hooray for Jarret Hardie! Here's the SQL generated by his should-have-been-obvious solution:</p> <pre><code>SELECT DISTINCT `issues_article`.`id`, `issues_article`.`text` FROM `issues_article` INNER JOIN `uploads_image` ON (`issues_article`.`id` = `uploads_image`.`object_id`) WHERE (`uploads_image`.`id` IS NOT NULL AND `uploads_image`.`content_type_id` = 26 ) LIMIT 21 </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload