我有一个看起来像这样的表格:
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来显示查询结果,但是如何在两者之间传递表单数据?
提前致谢。
更新:我知道如何查询我的模型来过滤结果。我只是不知道如何使用表单和基于类的视图正确组合,以便我可以访问我的过滤器的cleaning_data。 e.g:
流程应该是:
1)在get上显示表单 2)在帖子上提交表格并验证(地理编码地址) 3)运行查询并显示结果
address = form.cleaned_data['address']
point = address['coord']
qs = model.objects.filter(point__distance_lte=(point, distance)
答案 0 :(得分:3)
这类似于这里提出的问题,或者我会说两个问题的组合。
请查看以上问题及其答案,如果您还有任何疑问,请回复此答案。
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 :(得分:2)
好的,这是基于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)