# in your models.py or managers.py

class PlaceManager(models.Manager):
    def nearest_to(self, point, number=5, geom_column='geom', from_srid=4326, to_srid=4326):
        """finds the model objects nearest to a given point
        
        `point` is a tuple of (x, y) in the spatial ref sys given by `from_srid`
        
        returns a list of tuples, sorted by increasing distance from the given `point`. 
        each tuple being (model_object, dist), where distance is in the units of the 
        spatial ref sys given by `to_srid`"""
        if not isinstance(point, tuple):
            raise TypeError
        from string import Template
        cursor = connection.cursor()
        x, y = point
        table = self.model._meta.db_table
        sql = Template("""
            SELECT id,
                Length(Transform(SetSRID(MakeLine($geom_column, GeomFromText('POINT(' || $x || ' ' || $y || ')', $from_srid)), $from_srid), $to_srid))
            FROM $table
            WHERE $geom_column IS NOT NULL
            ORDER BY Distance(GeomFromText('POINT($x $y)', $from_srid), $geom_column) ASC
            LIMIT $number;
        """)
        cursor.execute(sql.substitute(locals()))
        nearbys = cursor.fetchall()
        # get a list of primary keys of the nearby model objects
        ids = [p[0] for p in nearbys]
        # get a list of distances from the model objects
        dists = [p[1] for p in nearbys]
        places = self.filter(id__in=ids)
        # the QuerySet comes back in an undefined order; let's
        # order it by distance from the given point
        def order_by(objects, listing, name):
            """a convenience method that takes a list of objects,
            and orders them by comparing an attribute given by `name`
            to a sorted listing of values of the same length."""
            sorted = []
            for i in listing:
                for obj in objects:
                    if getattr(obj, name) == i:
                        sorted.append(obj)
            return sorted
        return zip(order_by(places, ids, 'id'), dists)

# ex. REPL

>>> Places.objects.nearest_to((-87.96, 42.06), number=5, to_srid=26971)
[(<Place: 600 S See Gwun Ave, Mount Prospect, IL 60056, USA>, 1908.34541121444), (<Place: 48 Raupp Blvd, Buffalo Grove, IL 60089, USA>, 9209.1395558741897), (<Place: 1000 S Milwaukee Ave, IL 60090, USA>, 7996.2420822250497), (<Place: 1175 Howard Ave, Des Plaines, IL 60018, USA>, 8095.9994070327703), (<Place: 701 Thorndale Ave, Wood Dale, IL 60191, USA>, 9613.4684521103609)]