You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

229 lines
7.7 KiB

# -*- coding: utf-8 -*-
from django.db import models
from django.core.serializers.json import DjangoJSONEncoder
from django.core import exceptions
from django import forms
from django.utils.safestring import mark_safe
from django.conf import settings
from south.modelsinspector import add_introspection_rules
try:
import json
except:
from django.utils import simplejson as json
FILE_TYPES = ('PDF', 'DOC', 'TXT', 'OTHER')
IMG_TYPES = ('JPG', 'BMP', 'PNG', 'GIF',)
PURPOSES = ('photo', 'flat')
from south.modelsinspector import add_introspection_rules
add_introspection_rules([], ["^functions\.custom_fields\.EnumField", "^functions\.custom_fields\.LocationField"])
# dont delete
class EnumField(models.Field):
"""
A field class that maps to MySQL's ENUM type.
Usage:
Class Card(models.Model):
suit = EnumField(values=('Clubs', 'Diamonds', 'Spades', 'Hearts'))
c = Card()
c.suit = 'Clubs'
c.save()
"""
def __init__(self, *args, **kwargs):
self.values = kwargs.pop('values')
kwargs['choices'] = [(v, v) for v in self.values]
kwargs['default'] = self.values[0]
super(EnumField, self).__init__(*args, **kwargs)
def db_type(self, connection):
return "enum({0})".format( ','.join("'%s'" % v for v in self.values) )
#snippet http://djangosnippets.org/snippets/1478/
class JSONField(models.TextField):
"""JSONField is a generic textfield that neatly serializes/unserializes
JSON objects seamlessly"""
# Used so to_python() is called
__metaclass__ = models.SubfieldBase
def to_python(self, value):
"""Convert our string value to JSON after we load it from the DB"""
if not isinstance(value, basestring):
return value
try:
return json.loads(value)
except ValueError, e:
# If string could not parse as JSON it's means that it's Python
# string saved to JSONField.
return value
def get_db_prep_value(self, value, connection, prepared=True):
"""Convert our JSON object to a string before we save"""
return json.dumps(value)
'''
def get_db_prep_save(self, value, connection):
"""Convert our JSON object to a string before we save"""
if value == "":
return None
if isinstance(value, dict):
value = json.dumps(value, cls=DjangoJSONEncoder)
return value
'''
DEFAULT_WIDTH = 590
DEFAULT_HEIGHT = 200
DEFAULT_LAT = 55.75
DEFAULT_LNG = 37.62
DEFAULT_ADDRESS = u'(Не задано)'
class LocationWidget(forms.TextInput):
def __init__(self, *args, **kw):
self.map_width = kw.get("map_width", DEFAULT_WIDTH)
self.map_height = kw.get("map_height", DEFAULT_HEIGHT)
super(LocationWidget, self).__init__(*args, **kw)
self.inner_widget = forms.widgets.HiddenInput()
def render(self, name, value, *args, **kwargs):
"""
handle on the rendering on the server
"""
if value is None or value==u'':
lat, lng, address = DEFAULT_LAT, DEFAULT_LNG, DEFAULT_ADDRESS
value = {'lat': lat, 'lng': lng, 'address': address}
else:
if isinstance(value, basestring):
a = json.loads(value)
lat, lng, address = float(a['lat']), float(a['lng']), a['address']
else:
lat, lng, address = float(value['lat']), float(value['lng']), value['address']
if isinstance(value, basestring):
curLocation = value
else:
curLocation = json.dumps(value, cls=DjangoJSONEncoder)
js = '''
<script type="text/javascript">
//<![CDATA[
var map_%(functionName)s;
function savePosition_%(functionName)s(point, address)
{
var input = document.getElementById("id_%(name)s");
var location = {'lat': point.lat().toFixed(6), 'lng': point.lng().toFixed(6)};
location.address = '%(defAddress)s';
if (address) {
location.address = address;
}
input.value = JSON.stringify(location);
map_%(functionName)s.panTo(point);
}
function load_%(functionName)s() {
var point = new google.maps.LatLng(%(lat)f, %(lng)f);
var options = {
zoom: 13,
center: point,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map_%(functionName)s = new google.maps.Map(document.getElementById("map_%(name)s"), options);
geocoder = new google.maps.Geocoder();
var marker = new google.maps.Marker({
map: map_%(functionName)s,
position: point,
draggable: true
});
google.maps.event.addListener(marker, 'dragend', function(mouseEvent) {
geocoder.geocode({'latLng': mouseEvent.latLng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK && results[0]) {
$('#address_%(name)s').val(results[0].formatted_address);
savePosition_%(functionName)s(mouseEvent.latLng, results[0].formatted_address);
}
else {
savePosition_%(functionName)s(mouseEvent.latLng);
}
});
});
google.maps.event.addListener(map_%(functionName)s, 'click', function(mouseEvent){
marker.setPosition(mouseEvent.latLng);
geocoder.geocode({'latLng': mouseEvent.latLng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK && results[0]) {
$('#address_%(name)s').val(results[0].formatted_address);
savePosition_%(functionName)s(mouseEvent.latLng, results[0].formatted_address);
}
else {
savePosition_%(functionName)s(mouseEvent.latLng);
}
});
});
$('#address_%(name)s').autocomplete({
source: function(request, response) {
geocoder.geocode({'address': request.term}, function(results, status) {
response($.map(results, function(item) {
return {
value: item.formatted_address,
location: item.geometry.location
}
}));
})
},
select: function(event, ui) {
marker.setPosition(ui.item.location);
savePosition_%(functionName)s(ui.item.location, ui.item.value);
}
});
}
$(document).ready(function(){
load_%(functionName)s();
});
//]]>
</script>
''' % dict(functionName=name.replace('-', '_'), name=name, lat=lat, lng=lng, defAddress=DEFAULT_ADDRESS)
html = self.inner_widget.render("%s" % name, "%s" % curLocation, dict(id='id_%s' % name))
html += '<input style="width: 580px" id="address_%s" type="text"/><br>' % ( name)
html += '<br/><div id="map_%s" style="width: %dpx; height: %dpx"></div>' % (name, self.map_width, self.map_height)
html += '<br /><label>%s: </label><span>%s</span>' % (u'Текущий адрес', address)
return mark_safe(js + html)
class Media:
css = {'all': (
'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/redmond/jquery-ui.css',
settings.MEDIA_URL+'css/main.css',
)}
js = (
'http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js',
'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js',
'http://maps.google.com/maps/api/js?sensor=false',
)
class LocationField(JSONField):
def formfield(self, **kwargs):
defaults = {'widget': LocationWidget}
return super(LocationField, self).formfield(**defaults)