在Django ListView中实现Query Form的最佳方法是什么?

时间:2015-03-31 19:43:25

标签: django listview django-class-based-views django-1.7

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

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 个答案:

答案 0 :(得分: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 %}

那就是它!