2015-03-31 85 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

相關問題