2012-03-14 2 views
3

Я пытаюсь создать пользовательское поле модели и виджет для отображения карты google maps api v3 и щелчка по выбору точки и ее сохранение.Поле пользовательской формы Django неверно отображает значение

Значение в базе данных должна быть в следующем формате: LAT, LONG, FORMATTED_ADDRESS_BY_GOOGLE_REVERSE_GEOCODER

Вот мой fields.py:

from django.db import models 

class LatLong(object): 

    def __init__(self, *args, **kwargs): 
     self.lat = kwargs.get('lat',0) 
     self.long = kwargs.get('long',0) 
     self.addr = kwargs.get('addr','') 

class CoordField(models.Field): 

    description = 'Coordinates field' 
    __metaclass__ = models.SubfieldBase 

    def __unicode__(self): 
     return 'LatLong obj' 

    def __init__(self, *args, **kwargs): 
     kwargs['max_length'] = 255 
     super(CoordField, self).__init__(*args, **kwargs) 

    def db_type(self, connection): 
     return 'varchar(%s)' % self.max_length 

    def get_prep_value(self, value): 
     return '%s,%s,%s' % (value.lat, value.long, value.addr) 

    def to_python(self, value): 
     if isinstance(value, LatLong): 
      return value 

     try: 
      x = value.split(',') 
     except: 
      return LatLong(lat=0,long=0,addr='') 

     return LatLong(lat=x[0], long=x[1], addr=','.join(x[2:])) 

И мой widgets.py:

from django.forms import Widget, TextInput 

from django.template.loader import render_to_string 

from django.utils.safestring import mark_safe 

from settings import GMAPS_API_KEY 


class LatLongWidget(TextInput): 

    class Media: 
     css = { 
      'all':('testing.css',) 
     } 
     js = ( 
      'resource/js/coord.js', 
     ) 

    def __init__(self, attrs=None): 
     default_attrs = {} 

     if attrs: 
      default_attrs.update(attrs) 

     super(LatLongWidget, self).__init__(default_attrs) 

    def render(self, *args, **kwargs): 
     output = super(LatLongWidget, self).render(*args, **kwargs) 

     output += render_to_string('maps/coord.html', 
            {'GMAPS_API_KEY':GMAPS_API_KEY, 
            'latlong': args[1]}) 

     return mark_safe(output) 

Насколько я понимаю, определение to_python() из поля должно всегда возвращать объект python, а get_prep_value() должен делать совершенно противоположное.

Как видно из скриншота ниже, результат поля в форме не является 3 значениями, разделенными запятой, а строковым представлением объекта LatLong, возвращаемого to_python().

Это автоматически происходит в моем виджете, когда я называю output = super(LatLongWidget, self).render(*args, **kwargs)

Скриншот: http://imgur.com/qnuSu

Что я здесь отсутствует? Должен ли я выполнять больше функций? Я сделал это совершенно неправильно?

Любая помощь будет оценена по достоинству. Благодарю.

+1

Строка, которая появляется в форме, представляет собой строковое представление объекта LatLong, а не трехзначное обозначение. – sm0ke21

+1

Вопрос кажется мне простым. Понятия не имею, почему вы получили вниз. –

ответ

3

Я изменил мой виджет визуализации() метод для проверки типа параметра значения, переданного и преобразовать его в LatLong объекта, если это необходимо, как, например:

def render(self, name, value, attrs=None): 
    if not isinstance(value, LatLong): 
     value = value.split(',') 
     value = LatLong(lat=value[0], long=value[1], addr=value[2:]) 

    output = super(LatLongWidget, self).render(name, '%s,%s,%s' % (value.lat, value.long, value.addr), attrs) 

    output += render_to_string('maps/coord.html', 
           {'GMAPS_API_KEY':GMAPS_API_KEY, 
           'latlong': value, 
           'id':attrs['id'],}) 

    return mark_safe(output) 

Это, похоже, закрепилась мою проблему, так как Параметр «значение», передаваемый в render(), является либо строкой unicode (при отправке формы), либо объектом LatLong при отображении формы.

Смежные вопросы