1

次のようなコントローラーとメソッドを指定します。

import genshi
from pylons import  tmpl_context, request, url
import re
from tg import expose, flash
from tg.controllers import  redirect
from tg.decorators import validate
import tw.forms as twf
from tw.forms.datagrid import DataGrid
from tg.decorators import paginate
from tg.i18n import ugettext as _
from repoze.what.predicates import has_permission
from interlock.lib.base import BaseController
assigned_seller_product_grid = DataGrid(fields=[
    ('Product Name', 'name'),
    ('Producer', 'producer'),
])

unassigned_seller_product_grid = DataGrid(fields=[
    ('Product Name', 'name'),
    ('Producer', 'producer'),
])


class SellerController(BaseController):
    allow_only = has_permission('manage')

    @paginate("unassigned", items_per_page=5, use_prefix=True)
    @paginate("assigned",   items_per_page=5, use_prefix=True)
    @expose('demo.templates.sellers.products')
    def products(self, uid = None, **kw):
        seller = uid is not None and DBSession.query(SellerModel).filter_by(uid=uid, deleted=False).first()
        if uid is not None and not seller:
            flash(_('No Seller ID Defined'), 'warning')
            redirect('/seller/')
        unassigned = DBSession.query(ProductModel).filter(~ProductModel.sellers.any(SellerModel.uid == seller.uid)).filter(ProductModel.deleted == False)
        assigned = DBSession.query(ProductModel).filter(ProductModel.sellers.any(SellerModel.uid == seller.uid)).filter(ProductModel.deleted == False)

        return dict(seller=seller,
                    assigned=assigned,
                    unassigned = unassigned,
                    assigned_grid=assigned_seller_product_grid,
                    unassigned_grid=unassigned_seller_product_grid,
                    page='seller')

そして、次のようなテンプレート:

<h1>Assigned Products</h1>
<div py:if="assigned">${assigned_grid(assigned)}</div>
<div>${tmpl_context.paginators.assigned.pager(page_param='assigned_page')}</div>
<h1>Unassigned Products</h1>
    <div py:if="unassigned">${unassigned_grid(unassigned)}</div>
    <div>${tmpl_context.paginators.unassigned.pager(page_param='unassigned_page')}</div>

TG2 がページネーション リンクを正しく生成していることがわかりますが、ページネーションは最初のデコレータだけを使用してページを変更し、2 番目のデコレータは無視します。以前にこの問題に直面した人はいますか?

ありがとう。

4

2 に答える 2

1

TGの現在の@paginateデコレータでは、同じページで複数のパギネータを処理することはできません。デコレータの新しいバージョンは、次のリリースから利用できるようになります。それまでの間、 @ paginateデコレータを次の実装に置き換えることができます(myproject.lib.paginateとして保存し、tg.decorators.paginateの代わりにインポートします)。

from tg.decorators import Decoration
from tg.paginate import Page
from tg.util import Bunch, partial
from tg import request

class paginate(object):
    def __init__(self, name, use_prefix=False,
        items_per_page=10, max_items_per_page=0):
        self.name = name
        prefix = use_prefix and name + '_' or ''
        self.page_param = prefix + 'page'
        self.items_per_page_param = prefix + 'items_per_page'
        self.items_per_page = items_per_page
        self.max_items_per_page = max_items_per_page

    def __call__(self, func):
        decoration = Decoration.get_decoration(func)
        decoration.register_hook('before_validate', self.before_validate)
        decoration.register_hook('before_render', self.before_render)
        return func

    def before_validate(self, remainder, params):
        page_param = params.pop(self.page_param, None)
        if page_param:
            try:
                page = int(page_param)
                if page < 1:
                    raise ValueError
            except ValueError:
                page = 1
        else:
            page = 1

        try:
            paginators_data = request.paginators
        except:
            paginators_data = request.paginators = {'_tg_paginators_params':{}}

        paginators_data['_tg_paginators_params'][self.page_param] = page_param
        paginators_data[self.name] = paginator = Bunch()

        paginator.paginate_page = page or 1
        items_per_page = params.pop(self.items_per_page_param, None)
        if items_per_page:
            try:
                items_per_page = min(
                    int(items_per_page), self.max_items_per_page)
                if items_per_page < 1:
                    raise ValueError
            except ValueError:
                items_per_page = self.items_per_page
        else:
            items_per_page = self.items_per_page
        paginator.paginate_items_per_page = items_per_page
        paginator.paginate_params = params.copy()
        paginator.paginate_params.update(paginators_data['_tg_paginators_params'])
        if items_per_page != self.items_per_page:
            paginator.paginate_params[self.items_per_page_param] = items_per_page

    def before_render(self, remainder, params, output):
        if not isinstance(output, dict) or not self.name in output:
            return

        paginator = request.paginators[self.name]
        collection = output[self.name]
        page = Page(collection, paginator.paginate_page,
            paginator.paginate_items_per_page, controller='/')
        page.kwargs = paginator.paginate_params
        if self.page_param != 'name':
            page.pager = partial(page.pager, page_param=self.page_param)
        if not getattr(tmpl_context, 'paginators', None):
            tmpl_context.paginators = Bunch()
        tmpl_context.paginators[self.name] = output[self.name] = page
于 2011-12-22T17:01:22.153 に答える