Last active
January 24, 2023 14:41
-
-
Save AndrewIngram/bc899db44d88160809d989a336f30bdf to your computer and use it in GitHub Desktop.
Django Queryset capabilites example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
This snippet will return all the letting agents, bucketed into discrete bands based on distance from | |
an origin point (for example, the user's current location), then sorted alphabetically within each | |
band. The goal being to prioritise agents in close proximity, but not excessively so -- all agents | |
within the same band should be given equal distance-related priority. | |
If there's a search term, we then boost the distance score based on the name's similiarity to the | |
search query. | |
""" | |
qs = LettingAgentLocation.objects.select_related("agent").filter(postcode__isnull=False) | |
ordering = ("location_name", "-id") | |
if origin: | |
qs = qs.annotate( | |
distance=Distance("location", origin), | |
distance_score=Case( | |
When(location__isnull=True, then=Value(1)), | |
When(distance__lte=D(km=2), then=Value(5)), | |
When(distance__lte=D(km=5), then=Value(4)), | |
When(distance__lte=D(km=10), then=Value(3)), | |
When(distance__lte=D(km=20), then=Value(2)), | |
default=Value(1), | |
), | |
) | |
ordering = ("-distance_score",) + ordering | |
if len(search_term) >= 3: | |
qs = qs.annotate( | |
similarity=Cast( | |
TrigramWordSimilarity("location_name", search_term), | |
output_field=FloatField(), | |
), | |
score=(1 + Ln(F("distance_score"))) * F("similarity"), | |
).filter( | |
similarity__gt=0.2, | |
) | |
ordering = ("-score",) + ordering | |
else: | |
qs = qs.filter(distance_score__gte=2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment