Reputation: 4683
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
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