django 1.8-如果表单条目查询结果与数据库不匹配,则在同一页面上显示警告消息,而不是"无"或引发异常页面

Hél*_*éna 7 python django

我很感谢下面的答案,但很抱歉,我仍然没有解决这个问题,也许我没有正确理解它们.因此,我为此付了一笔赏金,以便更清楚地回答.

用户在表单中输入一些信息后,这些信息作为查询来过滤数据库以获得结果,如果数据库中没有相应的记录,我怎么能在当前页面上显示警报或重定向页面警告用户"没有相应的数据".

在此输入图像描述

举例如图:如果用户输入"EU"和"India",确定数据库中没有相应的记录.表单允许用户将字段留空.

我以前使用raise ValidationError,如果查询结果与数据库不匹配,它将转到黄色的"异常"页面,这不是用户友好的.我想在提交后立即在SAME表单页面上显示错误消息:

views.py

from django.contrib import messages

class InputFormView(FormView):
template_name = 'entryform.html'
form_class = EntryForm

def get_success_url(self):
    params = {
        'department': self.request.POST.get('company'),
        'person': self.request.POST.get('region')
    }
    return ''.join([reverse('final'), '?', urllib.urlencode(params.items())])

class FinalView(ListView):
    context_object_name = 'XXX'
    template_name = 'XXX.html'
    model = Final

    def get_queryset(self):
        form = InputForm(self.request.GET)        
        if form.is_valid():
            department = form.cleaned_data['department']
            person = form.cleaned_data['person']

            if department !="" and person !="":
                if Final.objects.filter(department=department,person=person).exists():
                    queryset=Final.objects.filter(department=department,person=person)
                    return queryset
                else:
                    msg="no corresponding data exists!"
                    form.add_error('department', msg)
                    form.add_error('person', msg)

            elif department =="" and person !="":
                if Final.objects.filter(person=person).exists():
                    queryset=Final.objects.filter(person=person)
                    return queryset
                else:
                    msg="no corresponding data exists!"
                    form.add_error('department', msg)
                    form.add_error('person', msg)

            elif ........


        else:     #if form not valid
            messages.error(request, "Error")

    def get_context_data(self,**kwargs):
        query_set = self.get_queryset()
        if query_set is not None:
            context["sales"] = self.get_queryset().aggregate(Sum('sales'))
Run Code Online (Sandbox Code Playgroud)

HTML

 <form method="post">{% csrf_token %}
        {% csrf_token %}
      {{ formset.management_form }}
      {{ formset.errors }}
      {{ formset.non_field_errors }}
      {{ formset.non_form_errors }}
      {{ form.non_field_errors }}     
     ......                   
        <!--select department-->
        <div class="field" >
            <label> Select department:
            {{ form.department }}
                {% for department in form.department.choices %}                    
                     <option value="department" name= "department" id="id_department">{{department}} </option>
                {% endfor %}
            </label>
        </div>     

..........same for person.....                    

        <!--submit-->
        <div class="button" id="btnShow"><input type="submit" value="Submit" /></div>

        </div>
 </form>
Run Code Online (Sandbox Code Playgroud)

如果我不使用ValidationError方法,它将重定向到结果页面,显示所有内容为"无".但我想显示一条警告信息.我看到网上有一个ajax示例,这有点复杂.有没有更简单的方法来实现它?

提前致谢.

谢谢.

Dan*_*man 2

如果我理解正确的话 FinalView 应该只过滤 GET 参数?

如果是这种情况,您真的需要该表格吗?我看起来你想呈现“不存在相应的数据!” 如果没有结果呢?通用 Listview 自动从 get_queryset 填充 self.object_list (或 context_object_name ),因此在代码或模板中进行简单的检查 object_list.exists() 应该足以呈现错误消息...

为了做一个简单的过滤器,我将提供一个我通常为您的示例使用转换的技术的示例:

class FinalView(ListView):

    def get_queryset(self):
        qs = super(FinalView, self).get_queryset()
        filter_fields = ('department', 'person')  # the fields to filter on
        query_dict = {}  # filter query
        for param in self.request.GET:  # iterate all params
            if param in filter_fields:  # is param a filter we want to use?
                value = self.request.GET.get(param)
                if value:  # Have value? otherwise ignore
                    query_dict[param] = value
        return qs.filter(**query_dict)  # Execute filter

    def get_context_data(self, **kwargs):
        kwargs = super(FinalView, self).get_context_data(**kwargs)
        if self.object_list.exists():  # Did we get objects? (this can also be done directly in template)
           kwargs['error_msg'] = 'no corresponing data exist!'
       else:
           kwargs["sales"] = self.object_list.aggregate(Sum('sales'))
       # Re-populate form if we want that
       kwargs['form'] = InputForm(initial=self.request.GET)
       return kwargs
Run Code Online (Sandbox Code Playgroud)

不知道是否符合你的要求。但这是一个替代解决方案。

django 中表单的详细阐述: django 中的表单(除其他外)用于验证输入数据并从字段创建适当的 python 类型。(即 IntegerField 将是整数等)。表单的角色

在这种情况下,数据用于过滤查询集。数据本身是有效的,但使用数据得出的结果却不是。

ListView 和表单的“角色”很重要:视图过滤查询集,django 表单验证输入数据。

如果我们对执行过滤器后的结果不满意,视图应该处理,如果输入数据错误,django 表单应该处理。(即格式错误、空字段或部门不能为空(如果人员已满)等)。

根据这个问题,我们知道 FinalView 的输入将是字符串或空。( self.request.GET 始终是字符串或空),这里需要 django 表单可能会让事情变得复杂?