Reverse relation (ForeignKey) in Django ORM with unique combination

146 views Asked by At

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.

0

There are 0 answers