# -*- 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 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') # 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 = ''' ''' % 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 += '
' % ( name) html += '
' % (name, self.map_width, self.map_height) html += '
%s' % (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) from south.modelsinspector import add_introspection_rules add_introspection_rules([ ( [EnumField], # Class(es) these apply to [], # Positional arguments (not used) { # Keyword argument "values": ["values", {'default': None}], }, ), ], ["^functions\.custom_fields\.EnumField", "^functions\.custom_fields\.LocationField"])