2015-03-31 87 views
0

上周我遇到了一个与Django中的listView和Forms有关的任务,我想知道在ListView中实现搜索表单的最佳方式(+ Pythonic)是什么,在我读12之后,我得到了一个主要想法,所以我实施了第一个解决方案,我希望收到您的反馈。这里的目标是通过代码字段执行查询并保留查询集以便将其与分页同步。在Django ListView中实现查询表单的最佳方式是什么?

forms.py

class InscriptionQueryForm(forms.Form): 
    query_inscription = forms.CharField(label=_('Code'), required=False) 

models.py

class Inscription(models.Model): 
    code = models.CharField(max_length=10, unique=True) 
    start_on = models.DateField() 
    finish_on = models.DateField() 
    active = models.BooleanField(default=False) 

views.py

class InscriptionListView(ListView, FormMixin): 
    model = Inscription 
    paginate_by = 4 
    context_object_name = 'inscriptions' 
    form_class = InscriptionQueryForm 
    form = None 
    object_list = None 
    search = False 

    def get_queryset(self): 
     form = self.form_class(self.request.POST) 

     if form.is_valid() and self.request.method == 'POST': 
      self.request.session['query_inscription'] = \ 
       form.cleaned_data['query_inscription'] 
      return self.model.objects.filter(
       code__icontains=form.cleaned_data['query_inscription']).\ 
       order_by('-active') 

     if self.request.method == 'GET' and \ 
       'query_inscription' in self.request.session: 

      return self.model.objects.filter(
       code__icontains=self.request.session.get(
        'query_inscription', '')).order_by('-active') 

     return self.model.objects.all().order_by('-active') 

    def get(self, request, *args, **kwargs): 
     # From ProcessFormMixin 
     self.form = self.get_form(self.form_class) 

     # From BaseListView 
     if self.request.GET.get('page', False) or self.search: 
      self.object_list = self.get_queryset() 
     else: 
      self.search = False 
      self.object_list = self.model.objects.all().order_by('-active') 
      if 'query_inscription' in self.request.session: 
       del self.request.session['query_inscription'] 

     context = self.get_context_data(
      object_list=self.object_list, form=self.form) 
     return self.render_to_response(context) 

    def post(self, request, *args, **kwargs): 
     self.search = True 
     return self.get(request, *args, **kwargs) 

你怎么看摹呃,我相信还有很多其他更好的方法。

+1

为什么使用会话?即使在页面之间进行页面调整,GET参数中是否仍然存在query_inscription? – schillingt 2015-03-31 20:07:13

+0

我通过邮寄发送表单,所以我只有第一次使用query_inscription参数。我将query_inscription保存在会话变量中以保持正确的分页。我使用get的唯一参数是'page'。 – jorlugaqui 2015-04-01 13:18:09

回答

1

上周我遇到了类似的问题。我的模型是一个普通的django用户。然而,这里也可以使用相同的方法。

我想你想使用搜索字段搜索你的铭文,并分页你的结果。当你浏览网页时,你会看到搜索查询的结果。

您的models.py保持原样。我们要修改forms.py,因为它可以初始化搜索请求

class InscriptionQueryForm(forms.Form): 
query_inscription = forms.CharField(label='Code', required=False) 

def __init__(self, query_inscription): 
    super(InscriptionQueryForm, self).__init__() 
    self.fields['query_inscription'].initial = query_inscription 

现在让我们来看看views.py。您不需要将他的请求值存储在会话中,因为他的评论中提到了schillingt。所有你需要的是用搜索请求初始化你的表单。

class InscriptionListView(ListView): 
model = Inscription 
paginate_by = 4 
context_object_name = 'inscriptions' 
query_inscription = '' 

def get_context_data(self, **kwargs): 
    context = super(InscriptionListView, self).get_context_data(**kwargs) 
    context['form'] = InscriptionQueryForm(self.query_inscription) 
    # this parameter goes for the right pagination 
    context['search_request'] = ('query_inscription=' + 
           unicode(self.query_inscription)) 
    return context 

def get(self, request, *args, **kwargs): 
    self.query_inscription = request.GET.get('query_inscription', '') 
    return super(InscriptionListView, self).get(request, *args, **kwargs) 

def get_queryset(self): 
    if not self.query_inscription: 
     inscription_list = Inscription.objects.all() 
    else: 
     inscription_list = Inscription.objects.filter(
      code__icontains=self.query_inscription) 

    return inscription_list.order_by('-active') 

而且提的最后一件事是分页 inscription_list.html

<form action=""> 
{{ form.as_p }} 
<input type="submit" value="search"/> 
</form> 
<hr/> 
{% if inscriptions %} 
    {% for inscription in inscriptions %} 
     {{ inscription.code }} {{ inscription.start_on }} {{ inscription.finish_on }} 
     <hr/> 
    {% endfor %} 
    {% if is_paginated %} 
     <div class="pagination"> 
      <span class="page-links"> 
       {% if page_obj.has_previous %} 
        <a href="?{{ search_request }}&page={{ page_obj.previous_page_number }}">previous</a> 
       {% endif %} 
       <span class="page-current"> 
        Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }} 
       </span> 
       {% if page_obj.has_next %} 
        <a href="?{{ search_request }}&page={{ page_obj.next_page_number }}">next</a> 
       {% endif %} 
      </span> 
     </div> 
    {% endif %} 
{% endif %} 

这就是它!

+0

感谢@BernarditoLuis,我只是想避免在分页的链接中传递搜索查询。但是你的解决方案非常清晰:) – jorlugaqui 2015-04-17 13:39:08

相关问题