0

I'm trying to get a flat list of site names associated with each user. The results will be written to a CSV file:

email,sites
a@b.com,site1|site2|site3
b@b.com,site3

StringAgg works to flatten sites in an annotation. Both has_flag and is_admin work in an annotation. All of these fields work with created_date. But if I try to include sites with either has_flag or is_admin, it throws the error 'WhenNode' object has no attribute 'copy'.

Simplified code:

users = (
    account.get_users()
    .annotate(
        is_admin=ExpressionWrapper(Q(role=1), output_field=BooleanField()),
        has_flag=ExpressionWrapper(Q(thing__isnull=False), output_field=BooleanField(),
        created_date=Func(F("created_at"),Value("YYYY-MM-DD"),function="to_char", output_field=CharField()),
        sites=StringAgg('usersite__site__name', delimiter="|"),
    )
    .values_list(
        "email",
        "is_admin",
        "has_thing",
        "created_date",
        "sites",
    )
)

class UserSite():
    class Meta(object):
        unique_together = ("user", "site")

    user = models.ForeignKey(User, on_delete=models.CASCADE)
    site = models.ForeignKey(Site, on_delete=models.CASCADE)
earthtone0ne
  • 3
  • 1
  • 2
  • Why do you use ExpressionWrapper? – Nikita Zhuikov Apr 19 '21 at 13:29
  • Good question. It should add a `copy` method [from the BaseExpression class](https://github.com/django/django/blob/ed0cc52dc3b0dfebba8a38c12b6157a007309900/django/db/models/expressions.py#L346), and at some point when I added `ExpressionWrapper` I was able to get a different error... but unfortunately I haven't been able to reproduce that. With the current code, ExpressionWrapper has no effect. – earthtone0ne Apr 19 '21 at 14:51
  • Thanks, your question made me question why the ExpressionWrapper had no effect, and it turns out the error may involve a different field. Updated my question. – earthtone0ne Apr 19 '21 at 16:39

0 Answers0