Note that there are some explanatory texts on larger screens.

plurals
  1. POHow might I join two unrelated Django models via distance?
    primarykey
    data
    text
    <p>I'm working on a Django project that requires me to report, via web service, for each item in the School table all Hospitals that just so happen to be a set distance away. Here is a dummy implementation of the two models:</p> <pre><code>class School(models.Model): location = models.PointField(srid=4326, geography=True) ...some other fields... objects = models.GeoManager() class Hospital location = models.PointField(srid=4326, geography=True) ...some other fields... objects = models.GeoManager() </code></pre> <p>I will state for the record that this is a contrived example, but the point remains that:</p> <ol> <li>Neither model has a foreign key relationship with the other (nor should they)</li> <li>The only relationship is via distance</li> </ol> <p>Now, I am using Django Rest Framework (DRF) to render my requests, and I am using the Serializer classes that it provides to do something along these lines:</p> <pre><code>class SchoolSerializer(serializers.ModelSerializer): nearby_hospitals = serializers.SerializerMethodField('get_nearby_hospitals') class Meta: model = School fields = ('location', 'nearby_hospitals',) def get_nearby_hospitals(self, obj): geom = obj.location try: locations = Hospitals.objects.filter(loc__dwithin=(geom, 10000)) return HospitalSerializer(locations, many=True).data except: return </code></pre> <p>This <em>works</em> but it is not <em>efficient</em>. In essence what happens is that DRF loads all Schools, and then from there loops over each school and runs the query in get_nearby_hospitals. The number of database queries is equal to the number of items in Schools plus one (to get the Schools).</p> <p>Ideally I'd like a Django solution that performs something along these lines (obviously with the fields listed out, aliases for clashing ID column names, etc):</p> <pre><code>SELECT * FROM schools JOIN hospitals ON ST_DWithin(schools.location, hospitals.location, 10000) </code></pre> <p>The above query produces the intersection of all Schools and Hospitals within the proper distance. I could merge these results in manually with the <code>School.objects.all()</code> queryset or write a better query and call the <code>raw</code> QuerySet method to get what I'm after in one shot. </p> <p>Is there a better or more 'Django Way' solution to this problem? </p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload