Ren
Ren

Reputation: 4683

Django: QuerySet.update() returns FieldError when using Count() with filter

Given that:

class User(models.Model):
    organization = models.ForeingKey(
        "Organization",
        related_name="users",
        ...
    )
    is_active = models.BooleanField(default=True)


class Organization(models.Model):
    active_user_count = models.IntegerField(default=0)

When I run this, if we run line 2 or 3 exclusively, both fail:

au_count = Count("users", filter=Q(users__is_active=True))

# Line: 2
Organization.objects.update(active_user_count=au_count)
# Line: 3
Organization.objects.annotate(auc=au_count).update(active_user_count=F("auc")

I get the following error:

FieldError: Joined field references are not permitted in this query

Annotating (annotate()) instead of updating, works just fine.

I couldn't find examples of this solution using Subquery()

What's an alternative to this requirement? Am doing making a design mistake perhaps?

Upvotes: 1

Views: 343

Answers (1)

Ren
Ren

Reputation: 4683

I solved this by doing the following:

customers = Customer.objects.annotate(
    auc=Count("users", filter=Q(users__is_active=True))
).values("pk", "auc")

customers = [Customer(pk=c["pk"], active_user_count=c["auc"]) for c in customers]

Customer.objects.bulk_update(customers, ["active_user_count"])

Still not sure if it's the best answer, but it solves the issue in an efficient manner for a total of 2 queries.

Upvotes: 1

Related Questions