├── __init__.py ├── models-example.py ├── LICENSE ├── README ├── field.py └── templates └── coordinates_form.html /__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /models-example.py: -------------------------------------------------------------------------------- 1 | """ 2 | An example location model with one CoordinatesField 3 | 4 | You need to specify two settings: 5 | ``MAP_API`` is one of the following: google, yahoo or yahooflash 6 | ``MAP_API_KEY`` is the API key provided by Google or Yahoo 7 | 8 | """ 9 | 10 | from django.db import models 11 | from django.utils.translation import gettext_lazy as _ 12 | from field import CoordinatesField 13 | 14 | class Location (models.Model): 15 | name = models.CharField(maxlength=100) 16 | gps = CoordinatesField(_('GPS coordinates'), help_text=_("Please click on the marker.")) 17 | 18 | def __str__(self): 19 | return self.name 20 | 21 | class Admin: 22 | pass -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007, Jannis Leidel 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following 12 | disclaimer in the documentation and/or other materials provided 13 | with the distribution. 14 | * Neither the name of the author nor the names of other 15 | contributors may be used to endorse or promote products derived 16 | from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Coordinates Form Field for Django Admin 2 | ======================================= 3 | 4 | This is the first approach to give admins a nice interface for geographical 5 | data. With the included CoordinatesFormField it is possible to add and edit 6 | GPS coordinates using one of the popular map services from Google and Yahoo. 7 | 8 | Since most of the work is done via Javascript it has a nice fallback with 9 | a default TextField. The javascript code is written with generalisation in 10 | mind to handle the differences between the map systems. 11 | 12 | How to use it in your own django application 13 | ============================================ 14 | 15 | 1. Copy "coordinates_form.html" to a folder where it can be found by the 16 | template loader (hint: ``TEMPLATE_DIRS`` in your settings.py) 17 | 18 | 2. Set in your settings.py: 19 | 20 | ``MAP_API`` to "google", "yahoo" or "yahooflash" 21 | ``MAP_API_KEY`` to the API key provided by Google or Yahoo 22 | 23 | 3. Copy field.py to your django application folder, next to its models.py file 24 | 25 | 4. At the top of your applications's models.py file add the following line: 26 | from field import CoordinatesField 27 | 28 | 5. Change the model of one of the form fields of you model, for example: 29 | 30 | OLD: gps = models.CharField(maxlength=75) 31 | NEW: gps = CoordinatesField() 32 | 33 | 34 | What? Hm, doesn't work here. || Aaah nice, BUT... 35 | ================================================= 36 | 37 | Please leave your questions and messages on the designated Google Code site: 38 | 39 | http://code.google.com/p/django-coordinatesfield/ 40 | 41 | 42 | Feel free to join the development. We still need a form widget for the future 43 | "oldforms-removal" era. --Jannis -------------------------------------------------------------------------------- /field.py: -------------------------------------------------------------------------------- 1 | """ 2 | A form field that defines a character database field, rendered in the Django 3 | admin interface as one of the following popular maps: 4 | 5 | Google Maps 6 | Yahoo Maps (Ajax) 7 | Yahoo Maps (Flash) 8 | 9 | You need to set two setting in your settings.py: 10 | 11 | ``MAP_API`` is one of the following: "google", "yahoo" or "yahooflash" 12 | ``MAP_API_KEY`` is the API key provided by Google or Yahoo 13 | 14 | """ 15 | 16 | from django.db.models.fields import CharField 17 | from django import oldforms 18 | from django import newforms as forms 19 | from django.utils.text import capfirst 20 | from django.utils.html import escape 21 | from django.template import loader, Context 22 | from django.conf import settings 23 | 24 | class CoordinatesFormField(oldforms.TextField): 25 | """ 26 | Defines a custom admin form field and renders as an interactive map if 27 | Javascript is available. Otherwise a normal input text field is shown. 28 | """ 29 | def render(self, data): 30 | if data is None: 31 | data = '' 32 | maxlength = '' 33 | if self.maxlength: 34 | maxlength = 'maxlength="%s" ' % self.maxlength 35 | if isinstance(data, unicode): 36 | data = data.encode(settings.DEFAULT_CHARSET) 37 | map_api = settings.MAP_API or None 38 | if map_api in ("google", "yahoo", "yahooflash"): 39 | template = loader.get_template("coordinates_form.html") 40 | context = Context({ 41 | 'field_name': self.field_name, 42 | 'input_type': self.input_type, 43 | 'map_id': self.get_id(), 44 | 'class_name': self.__class__.__name__, 45 | 'is_required': self.is_required and ' required' or '', 46 | 'data': escape(data), 47 | 'length': self.length, 48 | 'maxlength': maxlength, 49 | 'api': map_api, 50 | 'api_key': settings.MAP_API_KEY or "" 51 | }) 52 | return template.render(context) 53 | 54 | class CoordinatesField(CharField): 55 | """ 56 | Defines the form field which wraps around the custom CoordinatesFormField. 57 | Should also get a Widget for the future "oldforms-removal" era. 58 | """ 59 | def __init__(self, *args, **kwargs): 60 | kwargs['maxlength'] = 70 61 | CharField.__init__(self, *args, **kwargs) 62 | 63 | def get_manipulator_field_objs(self): 64 | return [CoordinatesFormField] 65 | 66 | def formfield(self, **kwargs): 67 | defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text} 68 | defaults.update(kwargs) 69 | return forms.CharField(**defaults) 70 | 71 | def get_internal_type(self): 72 | return 'CharField' -------------------------------------------------------------------------------- /templates/coordinates_form.html: -------------------------------------------------------------------------------- 1 | 2 | {% ifequal api "google" %}{% endifequal %} 3 | {% ifequal api "yahoo" %}{% endifequal %} 4 | {% ifequal api "yahooflash" %}{% endifequal %} 5 | --------------------------------------------------------------------------------