I recently built a site for finding vineyards, and used GeoDjango with Postgres+PostGIS.
Setting up was a small PITA, but a bounding box query looks like this:
footprint = Polygon(((ullon, ullat), (lrlon, ullat), (lrlon, lrlat), (ullon, lrlat), (ullon, ullat)))
vineyards = Winery.objects.filter(loc__within=footprint)
If you're interested, check it out: http://finelocalwine.com/