Skip to content

Instantly share code, notes, and snippets.

@ralphking
Last active March 28, 2019 11:51
Show Gist options
  • Save ralphking/d7572e94075937920112 to your computer and use it in GitHub Desktop.
Save ralphking/d7572e94075937920112 to your computer and use it in GitHub Desktop.
Django search
class SearchResponse(FormMixin, ListView):
# formview stuff
template_name = 'search.html'
context_object_name = 'spaces'
form_class = SearchForm
def get_initial(self):
if self.request.GET:
initial = self.request.GET.dict()
return initial
# listview stuff
def get_queryset(self):
spaces = Space.objects.all()
location = self.request.GET.get('location', '')
radius = self.request.GET.get('radius')
space_size = self.request.GET.get('size')
venue_style = self.request.GET.get('style')
# chain all filters below with if
if location: # and radius?
# create a geo POINT from location entry
geocoder = GoogleV3()
latlon = geocoder.geocode(location)
latilongi = latlon[1]
latitude, longitude = latilongi
current_point = geos.fromstr("POINT({0} {1})".format(longitude, latitude))
# get search radius from get request
if not radius:
radius = 2.0
distance_from_point = float(radius)
spaces = Space.objects.all()
spaces = spaces.filter(location__distance_lte=(current_point, measure.D(mi=distance_from_point)))
if space_size:
spaces = spaces.filter(size__gte=space_size)
if not venue_style == 'All Styles':
spaces = spaces.filter(venue__style=venue_style)
if not spaces:
return None # return all objects if no radius or space.
else:
return spaces
def get_context_data(self, **kwargs):
context = super(SearchView, self).get_context_data(**kwargs)
context["form"] = self.get_form()
return context
#return everything as json upon get request.
def get(self, request, *args, **kwargs):
response = serializers.serialize('json', self.get_queryset(), use_natural_primary_keys=True)
return HttpResponse(response, {'MEDIA_URL': MEDIA_URL})
class SearchView(FormMixin, ListView):
template_name = 'search.html'
context_object_name = 'spaces'
form_class = SearchForm
def get_initial(self):
'''get initial values from request params'''
if self.request.GET:
initial = self.request.GET.dict()
return initial
def get_queryset(self):
'''return all spaces on initial get '''
spaces = Space.objects.all()
return spaces
def get_context_data(self, **kwargs):
context = super(SearchView, self).get_context_data(**kwargs)
context["form"] = self.get_form()
return context
{% extends 'base.html' %}
{% load bootstrap %}
{% block search %}
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?libraries=places">
</script>
<div style='height: 100%; overflow: scroll;'>
<div class='col-md-7' style='margin-top:30px;'>
<form action="" method="get" class='form-horizontal' id="search_form">
<div class="form-group">
<label class="col-sm-2 control-label">Location</label>
<div class='col-sm-6'>
{{ form.location }}
</div>
<div class='col-sm-4'>
{{ form.radius }}
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Venue Style</label>
<div class='col-sm-4'>
{{ form.style }}
</div>
<label class="col-sm-2 control-label">Space Size</label>
<div class='col-sm-4'>
{{ form.size }}
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<button type="Filter Results" class="btn btn-primary" style="width:100%;">Submit</button>
</div>
</div>
</form><!-- form -->
<div id="show_results">
{% if spaces %}
{% for space in spaces %}
<div class="col-md-6 col-md-6">
<div class="thumbnail">
{% if space.image1 %}
<img src="{{ space.image1.url }}" alt="Space Image">
{% endif %}
<div class="caption">
<h3>{{ space.name }}</h3>
<p>{{ space.description }}</p>
<p><a href="{% url 'space_detail' space.pk %}" class="btn btn-primary" role="button">View Space</a></p>
</div>
</div>
</div>
{% endfor %}
{% else %}
<p>No spaces are available.</p>
{% endif %}
</div>
</div>
<div class="col-md-5 nopadding" style="height: 100%; position: fixed !important; right: 0;">
<div id="map-canvas" style="width: 100%; height: 100%; display: block;" class="map-canvas"></div>
</div>
</div>
<script>
{% block footer %}{% endblock %}
var map;
var markers = [];
var bounds = new google.maps.LatLngBounds();
var center = new google.maps.LatLng(51.508515,-0.125487);
var markerImage = "{{ STATIC_URL }}images/marker.png";
var media_url = "{{ MEDIA_URL }}"
function initialize() {
var mapOptions = {
zoom:13,
center: center,
mapTypeId: google.maps.MapTypeId.ROADMAP,
panControl: false,
mapTypeControl: false,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL
}
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var image = "{{ STATIC_URL }}images/marker.png";
//autocomplete
var input = document.getElementById('id_location');
var autocomplete = new google.maps.places.Autocomplete(input, options);
var options = {
types: [],
componentRestrictions: {country: 'uk'}
};
// new marker function
function addMarker(latitude, longitude) {
center = new google.maps.LatLng(latitude, longitude);
var marker = new google.maps.Marker({
position: center,
map: map,
//title: name,
icon: markerImage,
});
// add marker to markers array
markers.push(marker)
// fit map to bounds
bounds = new google.maps.LatLngBounds(null);
for (i = 0; i < markers.length; i++)
{
bounds.extend(markers[i].getPosition());
}
map.fitBounds(bounds);
};
var search_location = $('#id_location').val();
if ( search_location != '') {
fetchResults();
}
function fetchResults() {
var params = $('#search_form').serialize()
//remove old markers
function removeMarker(marker) {
marker.setMap(null);
markers = [];
}
$.each(markers, function(key, val) {
removeMarker(val);
});
$.ajax({
url: {% url 'search_response' %},
data: params,
type: 'GET',
dataType: 'json',
success: function(data) {
/* var result = $('<div />').append(data).find('#show_results').html();
$('#show_results').html(result); */
$('#show_results').empty();
for (var i = 0; i < data.length; i++) {
var coords = data[i]['fields']['location'];
var regex = /[+-]?\d+(\.\d+)?/g;
var coords = coords.split(";").pop();
var coords = coords.match(regex).map(function(v) { return parseFloat(v); });
var latitude = coords[1];
var longitude = coords[0];
console.log(latitude, longitude);
//ad markesr
addMarker(latitude, longitude);
var image = media_url + data[i]['fields']['image1'];
var name = data[i]['fields']['name'];
var desc = data[i]['fields']['description'];
var url = window.location.origin + '/spaces/' + data[i]['pk'];
result ='<div class="col-md-6 col-md-6"><div class="thumbnail"><img src="' + image + '" alt="Space Image"><div class="caption"><h3>' + name + '</h3><p>'+ desc + '</p><p><a href="' + url + '" class="btn btn-primary" role="button">View Space</a></p></div></div></div>'
$('#show_results').append(result);
}
}
});
} // fetchresults
$('#search_form').submit(function() {
event.preventDefault();
fetchResults();
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
{% endblock %}
@ralphking
Copy link
Author

A basic Google maps search tool for Django. Search your model, place markers on the map using Ajax.

  1. Make the ajax call
  2. Build your query with the view
  3. Return JSON
  4. Play with the Json in your template

I haven't used GEOJson here, as frankly it's not very useful for dealing with POINT fields which kind of defeats the object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment