2012-12-26 160 views
4

我有一个模型formset,我想一次使用Django的Paginator显示10个表单,但它不能像paginator = Paginator(formset, 10)那样完成。如果有办法,那么做到这一点的正确方法是什么?Paginate Django formset

回答

13

这是我发现我的问题的解决方案的通用例子:

forms.py文件:

class MyForm(ModelForm): 
    class Meta: 
     model = MyModel 
     fields = ('description',) 

views.py文件:

FormSet = modelformset_factory(MyModel, form=MyForm, extra=0) 
if request.method == 'POST': 
    formset = FormSet(request.POST, request.FILES) 
    # Your validation and rest of the 'POST' code 
else: 
    query = MyModel.objects.filter(condition) 
    paginator = Paginator(query, 10) # Show 10 forms per page 
    page = request.GET.get('page') 
    try: 
     objects = paginator.page(page) 
    except PageNotAnInteger: 
     objects = paginator.page(1) 
    except EmptyPage: 
     objects = paginator.page(paginator.num_pages) 
    page_query = query.filter(id__in=[object.id for object in objects]) 
    formset = FormSet(queryset=page_query) 
    context = {'objects': objects, 'formset': formset} 
    return render_to_response('template.html', context, 
           context_instance=RequestContext(request)) 

您需要创建在当前页面中包含对象的formset,否则,当您在POST方法中尝试执行formset = FormSet(request.POST, request.FILES)时,Django引发MultiValueDictKeyError错误。

template.html文件:

{% if objects %} 
    <form action="" method="post"> 
     {% csrf_token %} 
     {{ formset.management_form }} 
     {% for form in formset.forms %} 
      {{ form.id }} 
      <!-- Display each form --> 
      {{ form.as_p }} 
     {% endfor %} 
     <input type="submit" value="Save" /> 
    </form> 

    <div class="pagination"> 
     <span class="step-links"> 
      {% if objects.has_previous %} 
       <a href="?page={{ objects.previous_page_number }}">Previous</a> 
      {% endif %} 

      <span class="current"> 
       Page {{ objects.number }} of {{ objects.paginator.num_pages }} 
      </span> 

      {% if objects.has_next %} 
       <a href="?page={{ objects.next_page_number }}">next</a> 
      {% endif %} 
     </span> 
    </div> 
{% else %} 
    <p>There are no objects.</p> 
{% endif %} 
1

更正确的方式来使用这个

... 
formset = FormSet(queryset=page_query.object_list) 
... 
+0

你能详细说明一下吗?看起来很有趣。 –

+0

这是行不通的,因为'BaseModelFormSet'需要'QuerySet'对象,并且会失败并带有'list' –

+1

这导致出现以下错误:'一旦切片已被采用,就无法过滤查询。'@GillBates:'object_list'返回一个'QuerySet',而不是'list'。所以使用@菲利的答案! – Caumons

0

在这里的问题是,您使用的上下文品牌(一个Page)这是期待QuerySet 。所以,我们需要那该死的QuerySet。你是正确的,但很多代码。

在源代码中,我们有:

class Page(collections.Sequence): 

    def __init__(self, object_list, number, paginator): 
     self.object_list = object_list 
     self.number = number 
     self.paginator = paginator 
     ... 

所以,我们在self.object_list属性查询集,只是用它!

formset = SomeModelFormSet(queryset=objects.object_list)