1

i'm making a website, using pyramid, sqlalchemy and chameleon... on the view.py i send the sqlalchemy:

@view_config(route_name='entity_subpage')
def entity_subpage_view(request):
    dbsession = DBSession()
    User = dbsession.query(Users).filter_by(id=0).first()
    return render_to_response('page.pt', User=User, request=request)

and chameleon:

<a tal:condition="user.minions.filter_by(dead=0).count() > 1">Prev</a>
<a tal:condition="user.minions.filter_by(dead=0).count() > 1">Next</a>
<repeat tal:omit-tag="" tal:repeat="_page user.minions">
    <condition tal:omit-tag="" tal:condition="not minion.dead"> 
        <li>
             ${minion.name}
        </li>
    </condition>
</repeat>

but the sqlalchemy "user.minions.count()" runs twice, so i added this on models:

class Users(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(convert_unicode=True))
    minions = dynamic_loader("Minions", backref="User")
    _NumFixedMinions = None

    @property
    def NumAliveMinions(self):
        if not self._NumFixedMinions:
            self._NumFixedMinions = self.minions.filter_by(dead=0).count()
        return self._NumFixedMinions

and started using "NumFixedMinions" instead of the ".count()", but this made the _NumFixedMintions defined until i restarted the server, am i missing something? or is there any way to make a simple "cache" only during the request..

ps:this is not the real code, it's harder to know when somethin will be used twice as the website is modular

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Joaolvcm
  • 1,983
  • 3
  • 20
  • 24

1 Answers1

2

Just call count() once in your template:

<tal:links tal:condition="user.minions.filter_by(dead=0).count() > 1">
    <a>Prev</a>
    <a>Next</a>
</tal>

For information you want to use perhaps in a request, I'd use a request property; if you set reify to True then it'll only calculated once and only when used:

def entity_subpage_view(request):
    dbsession = DBSession()
    User = dbsession.query(Users).filter_by(id=0).first()

    def dead_minion_count(request):
        return User.minions.filter_by(dead=0).count()

    request.set_property(dead_minion_count, 'dead_minion_count', reify=True)

    return render_to_response('page.pt', User=User, request=request)

then

<tal:links tal:condition="request.dead_minion_count > 1">
    <a>Prev</a>
    <a>Next</a>
</tal>
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • in this case yes... but as my website is modular, the user can personlize multiple widgets and pages, inside the same page, so it's hard to know how many times that "count" will be called, and sometimes it may be allot of times... or none – Joaolvcm Mar 23 '13 at 16:02
  • that's closer to what i need, i wanted something more direct, but if have to do like that it may not be that bad – Joaolvcm Mar 23 '13 at 17:24