2012-03-14 8 views
3

Googleマップの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つの値ではなく、to_python()によって返されたLatLongオブジェクトの文字列reprです。

私が呼ぶときには、自動的に自分のウィジェットに起こるoutput = super(LatLongWidget, self).render(*args, **kwargs)

スクリーンショット:http://imgur.com/qnuSu

私がここで行方不明ですか?より多くの機能を実装する必要がありますか?私はこれを完全に間違っていますか?

ご協力いただければ幸いです。ありがとう。

+1

フォームに表示される文字列は、3つのカンマ表記ではなくLatLongオブジェクトの文字列表現です。 – sm0ke21

+1

質問はわかりやすいようです。あなたがなぜ落選したのか分かりません。 –

答えて

3

私は私のウィジェットは、render()メソッド渡された値のパラメータの型をチェックし、そのように必要に応じて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()に渡される 'value'パラメータは、フォームを表示するときにUnicode文字列(フォームを送信するとき)またはLatLongオブジェクトのいずれかです。

関連する問題