我有一个表格,在输入信息后,根据信息过滤数据库并进行一些计算,最后将结果显示给重定向的网址。
我确实可以重定向到另一个网址并成功显示结果。但问题在于它无法显示用户提交的任何数据,只显示每个字段的内容,结果不是基于fitered queryset。让我们说总和,它只是总结数据库中的所有列,而不使用过滤结果。
我怀疑查询集没有将过滤后的结果传递给def get_context_data,因此get_context_data中的查询集不起作用。
如果你解决了我的疑问,真的非常感谢你。
(我根据建议结合2个类制作了EDIT版本,希望有人能纠正这个EDIT版本,谢谢)
urls.py
url(r'^result_list/$',ResultView.as_view(),name='result'),
url(r'^input/$',InputFormView.as_view(),name='input'),
views.py
class InputFormView(request):
#class InputFormView(FormView):
template_name = 'inputform.html'
form_class = InputForm
response = HttpResponse( 'result' )
request_form_data = request.POST #you need to sanitize/clear this data
response.set_cookie('form_data', request_form_data)
#redirect to result page with submitted form information
def get_success_url(self):
return ''.join(
[
reverse('result'),
'?company=',self.request.POST.get('company'), <--do I need to change "POST" into "USER"?
'®ion=',self.request.POST.get('region')
]
)
#class ResultView(ListView):
class ResultView(request):
context_object_name = 'result_list'
template_name = 'result_list.html'
model = Result
def get_context_data(self, **kwargs):
context = super(ResultView, self).get_context_data(**kwargs)
context["sales"] = self.get_queryset().aggregate(Sum('sales'))
context["company"] = self.request.POST.get("company")
context["region"] = self.request.POST.get("region")
return context
def get_queryset(self):
if self.request.method == 'POST':
form = InputForm(self.request.POST)
if form.is_valid():
company = form.cleaned_data['company']
region = form.cleaned_data['region']
queryset=Result.objects.filter(region=region)
return queryset
return Result.objects.all()
if request.COOKIES.has_key('form_data'):
value = request.COOKIES['form_data'] #this data also should be sanitized
HTML
<div class="basicinfo"> <!--Entry Form information submitted by user-->
<table border="1" cellpadding="1">
<tr>
<td align="left">Company</td>
<td>{{ company }}</td>
</tr>
<tr>
<td align="left">Region</td>
<td>{{ region }}</td>
</tr>
</table>
</div>
<!--Showing the filtered result in database-->
<td><table border="0" cellspacing="10" cellpadding="10">
<tr><b>Sales</b></tr>
<td bgcolor="#F0F0F0"> {{ sales.sales__sum }}</td>
</tr>
<tr><b>Employee</b></tr>
<tr>
<td bgcolor="#F0F0F0"> {{ employee.employee__sum }}</td>
</table>
编辑 - 合并2个课程视图
import urllib
#@csrf_exempt
class ResultView(ListView):
context_object_name = 'result_list'
template_name = 'result_list.html'
model = Result
def get_queryset(self):
form = InputForm(self.request.GET)
if form.is_valid():
company = form.cleaned_data['company']
region = form.cleaned_data['region']
queryset=Result.objects.filter(region=region)
return queryset
return Result.objects.all()
def get_success_url(self):
params = {
'company': self.request.POST.get('company'),
'region': self.request.POST.get('region')
}
return ''.join([reverse('result'), '?', urllib.urlencode(params.items())])
def get_context_data(self,**kwargs):
context = super(ResultView, self).get_context_data(**kwargs)
context["sales"] = self.get_queryset().aggregate(Sum('sales'))
context["company"] = self.request.GET.get("company")
context["region"] = self.request.GET.get("region")
return context
** EDIT- urls.py **
url(r'^result_list/$',ResultView.as_view(),name='result'),----for the result page
url(r'^input/$',result.views.get_success_url,name='input') -----for the form, I am not sure if this line correct or not?
答案 0 :(得分:3)
如果您将get_queryset
方法更改为:
def get_queryset(self):
# You are sending GET params here, not POST
form = InputForm(self.request.GET)
if form.is_valid():
company = form.cleaned_data['company']
region = form.cleaned_data['region']
queryset=Result.objects.filter(region=region)
return queryset
return Result.objects.all()
和您的get_context_data
方法:
def get_context_data(self, **kwargs):
context = super(ResultView, self).get_context_data(**kwargs)
context["sales"] = self.get_queryset().aggregate(Sum('sales'))
# Your variables are in GET, not POST
context["company"] = self.request.GET.get("company")
context["region"] = self.request.GET.get("region")
return context
那就是说,你的代码可以做一些重构。你真的需要接受POST请求的FormView
吗?您可以使用通过GET直接提交到结果视图的表单。
使用您当前的方法,您实际上是在处理表单两次 - 在每个视图中处理一次。
编辑:另外,他们生成重定向网址的方式并不安全。你应该这样:
import urllib
def get_success_url(self):
params = {
'company': self.request.POST.get('company'),
'region': self.request.POST.get('region')
}
return ''.join([reverse('result'), '?', urllib.urlencode(params.items())])
答案 1 :(得分:1)
如果您发出POST请求,之后您正在重定向用户,则下一个请求将具有空POST(因为现在它是另一个请求)。所以,这并不是一个令人惊讶的行为。 如果要在会话之间保存此数据,可以将其保存在用户会话中,例如。
您可以通过添加以下代码来修改您的某些视图(我相信会进行重定向):
设置cookie:
def your_view_which_makes_redirect(request):
#.. here is your code
response = HttpResponse( 'blah' )
request_form_data = request.POST #you need to sanitize/clear this data
response.set_cookie('form_data', request_form_data)
获取cookie:
def your_view_which_renders_page_after_rediret(request):
if request.COOKIES.has_key('form_data'):
value = request.COOKIES['form_data'] #this data also should be sanitized
1)此外,您可以将此cookie的名称移动到设置,因为现在它们是硬编码的,现在是非常好的做法。像settings.SAVED_FORM_NAME_COOIKE_TOKEN之类的东西 2)您还必须清理request.POST和request.COOKIES中的数据,因为用户可以放置一些恶意数据(SQL注入等)。