1

「アドレス」という単一のフィールドで構成される非常に単純な Django フォームがあります。

class AddressSearchForm(forms.Form):
    """
        A form that allows a user to enter an address to be geocoded
    """
    address = forms.CharField()

このデータは保存していないので、おそらくフォームを使用する必要さえありません。検索で使用するためにデータを収集しているだけです。しかし、検証を実行したい:

def clean_address():
    data = self.cleaned_data
    g = geocoders.Google()
    try:
        place, (lat,lng) = g.geocode(data['address'])
    except (GQueryError):
        raise forms.ValidationError('Please enter a valid address')
    except (GeocoderResultError, GBadKeyError, GTooManyQueriesError):
        raise forms.ValidationError('There was an error geocoding your address. Please      try again')
    except:
        raise forms.ValidationError('An unknown error occured. Please try again')

さらに、このジオコーディングされた結果を使用して、Point オブジェクトをビューに渡したいと考えています。

from django.contrib.gis.geos import Point
point = Point(lng, lat)

私の質問は、住所とポイント データの両方をビューに渡す方法です。住所を渡してビューで再ジオコーディングすることもできますが、それはコードを複製することになります。では、フォームからポイント オブジェクトを渡すにはどうすればよいでしょうか。非表示フィールドを使用する必要がありますか? 他の提案?前もって感謝します。

4

1 に答える 1

2

私はジャンゴの専門家ではありませんが、これは私がやったことです:

 def clean_homeaddress(self):
        in_address = self.cleaned_data['homeaddress']        
        place, self.cleaned_data['homelocation'] = address_to_latlng(in_address, True)
        return place

ところで、下のラッパーを見てください。geocoders.Google は Unicode 文字列を適切に処理しません。以下に、すべての非ASCII文字を削除する簡単なハックがあります。私はまだより良い解決策を見つける時間がありませんでした。

def address_to_latlng(address, return_address = False):
    """ returns GoeDjango POINT string value for given location (address)
        if return_address is true, it'll return 2-tuple: (address, point)
        otherwise it returns point
    """ 
    g = geocoders.Google()
    try:
        #TODO: not really replace, geocode should use unicode strings
        address = address.encode('ascii', 'replace')            
        place, latlng = g.geocode(address)            
    except Exception as e:            
        raise ValidationError(_(u"Incorrect location provided"))
    point = 'POINT(%f %f)' % tuple(reversed(latlng))
    if return_address:
        return (place, point)    
    return point

リクエストに応じて、完全なコードがあります。これは場所を出力コンソールに出力し、フォームが表示されるたびにユーザーに表示するために、セッション内の「クリーンな」(Google から返された) アドレスを保持します。

class GeoForm(forms.Form):
    address = forms.CharField()    

    def clean_address(self):
        in_address = self.cleaned_data['address']        
        place, self.cleaned_data['location'] = address_to_latlng(in_address, True)
        return place

class GeoView(FormView):
    form_class = GeoForm
    template_name = 'geoview.html'
    success_url = '/sandbox/geo'
    def get_initial(self):
        if '_address' in self.request.session:
            return {'address': self.request.session['_address']}
        return {}
    def form_valid(self,form):
        print form.cleaned_data['location']
        self.request.session['_address'] = form.cleaned_data['address']
        return super(GeoView, self).form_valid(form)
于 2013-01-20T18:07:44.427 に答える