4

次のようなフォームがあります。

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

この値は保存していませんが、住所をジオコーディングして有効であることを確認しています。

def clean_address(self):
    address = self.cleaned_data["address"]
    return geocode_address(address, True)

ジオコード関数は次のようになります。

def geocode_address(address, return_text = False):
    """ returns GeoDjango Point object for given address
        if return_text is true, it'll return a dictionary: {text, coord}
        otherwise it returns {coord}
    """ 
    g = geocoders.Google()
    try:
        #TODO: not really replace, geocode should use unicode strings
        address = address.encode('ascii', 'replace')            
        text, (lat,lon) = g.geocode(address)
        point = Point(lon,lat)
   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')

    if return_text:
         address = {'text':text, 'coord':point}
    else:
        address = {'coord':point}

    return address

ここで行う必要があるのは、住所データを使用してモデルをクエリし、結果をフィルター処理するビューを作成することです。これを行う方法がわからなくて困っています。できればCBVを使いたいです。FormView を使用してフォームを表示し、ListView を使用してクエリ結果を表示できますが、2 つの間でフォーム データを渡すにはどうすればよいでしょうか。

前もって感謝します。

更新: モデルにクエリを実行して結果をフィルタリングする方法を知っています。フィルターのcleaned_dataにアクセスできるように、フォームとクラスベースのビューを使用して適切に組み合わせる方法がわかりません。例えば:

プロセスは次のとおりです。

1) 取得時にフォームを表示する 2) フォームを送信し、投稿時に (ジオコード アドレス) を検証する 3) クエリを実行して結果を表示する

address = form.cleaned_data['address']
point = address['coord']
qs = model.objects.filter(point__distance_lte=(point, distance)
4

2 に答える 2

4

わかりました、psjinx の指示に基づいて最終的に機能したものの一般的なバージョンを次に示します。

from django.views.generic.base import TemplateResponseMixin, View
from django.views.generic.edit import FormMixin
from django.views.generic.list import MultipleObjectMixin

class SearchView(FormMixin, MultipleObjectMixin, TemplateResponseMixin, View):
    """
     A View which takes a queryset and filters it via a validated form submission
    """
    queryset = {{ initial queryset }} # you can use a model here too eg model=foo
    form_class = {{ form }}

    def get(self, request, *args, **kwargs):
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        return self.render_to_response(self.get_context_data(form=form))

    def post(self, request, *args, **kwargs):
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)    

    def form_valid(self, form):
        queryset = self.get_queryset()
        search_param = form.cleaned_data['{{ form field }}']
        object_list = queryset.filter({{ filter operation }}=search_param)
        context = self.get_context_data(object_list=object_list, form=form, search_param=search_param)
        return self.render_to_response(context) 
于 2013-01-22T05:59:34.517 に答える
3

これは、ここで尋ねられた質問に似ています。または、2 つの質問の組み合わせについて説明します。

  1. Django: クラス ベースの ListView の検索フォーム
  2. サードパーティアプリなしでdjangoモデルの複数フィールドを検索
  3. マルチフィールド検索へのdjangoのシンプルなアプローチ(モデルがこの質問で言及されているものに似ている場合)

上記の質問とその回答をご覧ください。まだ質問がある場合は、この回答へのコメントで返信してください。


更新 1

from django.views.generic.base import TemplateResponseMixin, View
from django.views.generic.edit import FormMixin
from django.views.generic.list import MultipleObjectMixin

class SearchView(FormMixin, MultipleObjectMixin, TemplateResponseMixin, View):
    model = SomeModel
    form_class = AddressSearchForm
    template = "search.html"

    def get_queryset():
        ## Override it here
        pass

    def post():
        ## If your form is invalid then request won't reach here
        ## because FormMixin is in left most position
        ## do something
        ## call self.render_to_response()

    def form_valid():
        ## Your form is valid do something
        ## if form is invalid then next method will be called
        pass

    def form_invalid(self):
        ## form is not valid
        ## render to some template

便利なリンク:

  1. https://github.com/django/django/blob/1.4.3/django/views/generic/base.py
  2. https://github.com/django/django/blob/1.4.3/django/views/generic/edit.py
  3. https://github.com/django/django/blob/1.4.3/django/views/generic/list.py

関連する質問:

  1. Django - ListView と CreateView の混合
于 2013-01-21T18:32:10.033 に答える