NewToJS
NewToJS

Reputation: 2101

Django views: Using a queryset with exclude after a for loop

in my views.py I have a queryset (bytes) that I loop through, adding a style property to certain items in the queryset:

bytes = Byte.objects.order_by('-publish_date')

for d in bytes:
  if not d.published:
    d.style = 'my-style'

Then in my views, I have another conditional statement:

if most_recent != most_shared:
    bytes = bytes.exclude(byte_id=most_shared_id)

But then when I sent bytes to the template, none of the info from the loop (if any item in the bytes got d.style) is there. How can I make this so when I use exclude I'm doing so on the bytes that just went through the loop??

Upvotes: 0

Views: 175

Answers (1)

Iain Shelvington
Iain Shelvington

Reputation: 32294

You can add the property via an annotation using a conditional expression

from django.db.models import Case, CharField, Value, When

queryset = Byte.objects.annotate(
    style=Case(
        When(published=False, then=Value('my-style')),
        default=Value(''),
        output_field=CharField()
    )
).order_by('-publish_date')

if most_recent != most_shared:
    queryset = queryset.exclude(byte_id=most_shared_id)

Since the annotation is part of the query the annotation will persist after any subsequent filters or exclusions

You shouldn't name your variables the same as any built-in functions, you are overriding the built-in function bytes

Upvotes: 1

Related Questions