milesrichardson / ParsePy

A relatively up-to-date fork of ParsePy, the Python wrapper for the Parse.com API. Originally maintained by @dgrtwo
MIT License
515 stars 184 forks source link

GeoPoint doesn't appear to support extra arguments, e.g. maxDistanceInMiles #53

Open dgrtwo opened 10 years ago

dgrtwo commented 10 years ago

The Parse REST API supports queries along the lines of "all locations within 10 miles", by passing the argument "maxDistanceInMiles to the filter constraint:

    "location": {
      "$nearSphere": {
        "__type": "GeoPoint",
        "latitude": 30.0,
        "longitude": -20.0
      },
      "$maxDistanceInMiles": 10.0
    }

However, while as of f679b4d8a61ba622f84065c25c07d19bc3960ed0 we can use nearSphere:

nearby_restaurants = Restaurant.Query.filter(location__nearSphere=my_loc)

I don't see how in the current framework one could add both nearSphere and maxDistanceInMiles to the same constraint. I'm not even sure what it would look like, though perhaps the most plausible is something like

nearby_restaurants = Restaurant.Query.filter(location__nearSphere=my_loc,
                                                                        location__maxDistanceInMiles=10)

This would indicate that instead of having a finite list of operators that can follow __, we should always look for __ in an argument and add what follows to the list of constraints. I'm not sure if there would be undesired consequences. Any thoughts?

lullis commented 10 years ago

I would keep a list of the operators, most as a way to help us know if we are up-to-date with Parse. Perhaps we could/should separate the location-specific operators into their own list, to make sure that the queryset is applying the right filters to a given type.

As for how to map these new operators to our library, is there any kind of problem of having your approach ( filter(attr__op1, attr__op2)? Also, another test that should be done is filter(attr__op1).filter(attr__op2).

dgrtwo commented 10 years ago

You're right about the latter point (I had to take a look into the code to check). However, what is the advantage of keeping a list of the existing operators? The only sense in which it helps us know if we are up-to-date is that it unexpectedly leads to people trying to do things they can't yet do, thus requiring active maintenance (regular Issues of "why doesn't this operator work yet"). Treating anything after the __ as being an operator would let the library stay up to date automatically.

lullis commented 10 years ago

I see your point. As it is now, having anything after the separator to be treated as an operator would make things a bit easier.

However, It might be that I am being too zealous, If we ever get to the point where we can do more complex queries, generalizing this rule will eventually lead us to weird bugs. Think of join queries* (filter(restaurant__owner__name='John Smith'), or filter(posted_date__year__lte=2003), and we can see that the "anything after __ is an operator" rule wouldn't hold.