#34629 closed New feature (fixed)

AttributeError when using filter argument with Collect in GeoDjango Aggregate

Reported by: Olivier Le Thanh Duong Owned by: Olivier Le Thanh Duong
Component: GIS Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When using the django.contrib.gis.db.models.aggregates.Collect aggregate function in GeoDjango, a AttributeError is raised when a filter argument is passed. The error is in GeoAggregate so I believe it affect all the other GeoAggregate: MakeLine, Union, Extend and Extent3D

Reproduction Steps:

  1. Define the Form and Submission models as follows:
    from django.contrib.gis.db.models import PointField
    from django.db import models
    
    class Form(models.Model):
        name = models.TextField()
    
    class Submission(models.Model):
        location = PointField()
        name = models.ForeignKey(Form, on_delete=models.CASCADE)
        deleted = models.BooleanField(default=False)
    
  2. Execute the following query to annotate the submission_center using Collect, applying a filter to only include undeleted submissions:
    Form.objects.annotate(submission_locations=Collect('submission__location', filter=Q(deleted=False)))
    

Expected Result:
The query should execute successfully, annotating the submission_center field in the Form model with the collected locations of undeleted submissions.

Actual Result:
An AttributeError is raised with the following traceback:

File ~/.virtualenvs/iaso/lib/python3.8/site-packages/django/contrib/gis/db/models/aggregates.py:44, in GeoAggregate.resolve_expression(self, query, allow_joins, reuse, summarize, for_save)
     42 c = super().resolve_expression(query, allow_joins, reuse, summarize, for_save)
     43 for expr in c.get_source_expressions():
---> 44     if not hasattr(expr.field, 'geom_type'):
     45         raise ValueError('Geospatial aggregates only allowed on geometry fields.')
     46 return c

AttributeError: 'WhereNode' object has no attribute 'field'

Versions Affected:
This issue can be reproduced on Django versions 3.2.15 and the main branch (1136aa5005f0ae70fea12796b7e37d6f027b9263 of 3 June). The Git log suggests that this problem exists in all versions between the reported ones.

I have a the working of a patch and will open a corresponding pull request in GitHub

Change History (9)

comment:1 by Olivier Le Thanh Duong, 17 months ago

Owner: changed from nobody to Olivier Le Thanh Duong
Status: newassigned

comment:2 by Claude Paroz, 17 months ago

Triage Stage: UnreviewedAccepted

Good catch!

comment:3 by Mariusz Felisiak, 17 months ago

Type: BugNew feature

comment:4 by Mariusz Felisiak, 17 months ago

Needs documentation: set
Needs tests: set
Patch needs improvement: set

comment:5 by Mariusz Felisiak, 17 months ago

Needs documentation: unset

comment:6 by Mariusz Felisiak, 17 months ago

Needs tests: unset

comment:7 by Mariusz Felisiak, 17 months ago

Patch needs improvement: unset
Triage Stage: AcceptedReady for checkin

comment:8 by Mariusz Felisiak <felisiak.mariusz@…>, 17 months ago

In c1cff3c4:

Refs #34629 -- Changed SDOAGGRTYPE wrapping to Func() in GIS aggregates on Oracle.

comment:9 by Mariusz Felisiak <felisiak.mariusz@…>, 17 months ago

Resolution: fixed
Status: assignedclosed

In 1b754d63:

Fixed #34629 -- Added filtering support to GIS aggregates.

Note: See TracTickets for help on using tickets.
Back to Top