0

Hi I was just wondering if this is feasible through Django ORM:

Please ignore model names etc, they are not real

class Image(models.Model):
    ...
    item = models.ForeignKey(Bag, related_name="images")
    flag_frontpage_image = models.BooleanField()
    imagefile = models.ImageField(upload_to="items/%m/%Y")
    ...


class Item(models.Model):
    ...

In views.py:

class LandingPageView(SomeMixin,SomeOtherMixin,ListView):
                ....
    def get_context_data(self, **kwargs):
        context = super(LandingPageView, self).get_context_data(**kwargs)
        context['items'] = Item.objects.prefetch_related('images').order_by('?').all()[:10]
        return context

This is ok and working ok, what I want to achieve is that I want in the view to fetch in 1 query applying a join the image a well. LandingPageView displays a list of items with the image that is flagged as frontpage image, as Django states (and SQL wise correctly) a reverse select_related is not possible, since Item can have many images, but...a Item can have only one frontpage image. I know there are other ways of achieving this in terms of refactoring, currently since I prefer to avoid partitioning models, I follow a mixin way:

class GetFeaturedMixin(object):
    @property
    def featured_image(self):
        if self.images.count > 0:
            for image in self.images.all():
                if image.flag_frontpage_image == 1:
                    return image.imagefile


class Item(models.Model, GetFeaturedMixin):
    ...

And then in the view:

<img src="{{ item.featured_image }}">

This works fine, but I would like to know if there is a way through Django relational querysets to achieve fetching the whole set in single queryset. Please don't answer or ask about raw queries, I know they do exist and have used them even on this type, I was just wondering if the above can be achieved with the ORM layer.

GiftZwergrapper
  • 2,602
  • 2
  • 20
  • 40
petkostas
  • 7,250
  • 3
  • 26
  • 29
  • `self.images.filter(flag_frontpage_image=True)` is obviously better than pythonically iterating over all of them. – yuvi Dec 31 '13 at 18:39
  • But that creates additional queries, since this is a reverse lookup, that's why I iterate through them with the above method, since the initial prefetch_related fetches all images for the items. I am gonna check again to make sure though – petkostas Dec 31 '13 at 18:45
  • Checked, I get 1 additional query for every call for featured_image so not preferred compared to the iteration. – petkostas Dec 31 '13 at 18:51
  • I forgot about the prefetched alright. As for the question - I can't think of a design where the query you're doing will be available through the ORM since it's a conditioned OR calculation – yuvi Dec 31 '13 at 20:14

0 Answers0