2012-12-26 79 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)