How to create alias for first active item in reverse relation in Django models?

29 Views Asked by At

I have a model called Item:

class Item(models.Model):
    ...

Also I have another model called Content. It has relation to Item and a ChoiceField to select is the content is active or not:

class Content(models.Model):
    item = ForeignKey(Item related_name=)
    is_active = BooleanField(default=False)
    content = TextField()

    def save(self, *args, **kwargs):
       """There's a logic to make sure every item has only one content"""

I have two questions.

  1. How to filter out the Items without any content or without any active content.
  2. Can I do something like alias to call item.content to return active content of the item without causing db performance issues.
1

There are 1 best solutions below

0
willeM_ Van Onsem On

How to filter out the Items without any content or without any active content.

You filter with:

from django.db.models import Q

Content.objects.filter(~Q(content=''), is_active=True)

Can I do something like alias to call item.content to return active content of the item without causing db performance issues.

Given the related name looks like:

class Content(models.Model):
    item = ForeignKey(Item, on_delete=models.PROTECT, related_name='contents')

You can prefetch these Contents to the contents with:

from django.db.models import Prefetch, Q

Item.objects.prefetch_related(
    Prefetch('contents', Content.objects.filter(~Q(content=''), is_active=True))
)

For these Items, it will set the .contents.all() to the related Contents with content not being empty, and is_active being True.