From 14a694445c9ce5493d644002a42261b39591d228 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Thu, 18 Mar 2010 00:11:49 -0400 Subject: [PATCH] Normalized the implementation of tags --- bluechips/controllers/spend.py | 5 +++-- bluechips/model/__init__.py | 15 ++++++++++----- bluechips/model/expenditure.py | 14 +++++--------- bluechips/model/tag.py | 20 +++++++++++++++----- 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/bluechips/controllers/spend.py b/bluechips/controllers/spend.py index 9caa1b3..ddd0a3c 100644 --- a/bluechips/controllers/spend.py +++ b/bluechips/controllers/spend.py @@ -112,7 +112,7 @@ class SpendController(BaseController): share = shares_by_user.get(user, '') c.values['shares-%d.amount' % ii] = share - c.values['tags'] = ', '.join([tag.tag for tag in c.expenditure.tags]) + c.values['tags'] = ', '.join(c.expenditure.tags) return render('/spend/index.mako') @@ -146,7 +146,8 @@ class SpendController(BaseController): split_dict[user] = amount split_text_dict[user] = amount_text e.split(split_dict, split_text_dict) - e.tag(tags) + e.tags.clear() + e.tags |= tags meta.Session.commit() diff --git a/bluechips/model/__init__.py b/bluechips/model/__init__.py index 11fb0e5..fa8d7a8 100644 --- a/bluechips/model/__init__.py +++ b/bluechips/model/__init__.py @@ -56,10 +56,15 @@ splits = sa.Table('splits', meta.metadata, tags = sa.Table('tags', meta.metadata, sa.Column('id', sa.types.Integer, primary_key=True), - sa.Column('expenditure_id', sa.types.Integer, - sa.ForeignKey('expenditures.id'), nullable=False), - sa.Column('tag', sa.Text, nullable=False)) + sa.Column('name', sa.Text)) +tag_to_expense_map = sa.Table('tag_to_expense_map', meta.metadata, + sa.Column('tag_id', sa.types.Integer, + sa.ForeignKey('tags.id'), + primary_key=True), + sa.Column('expenditure_id', sa.types.Integer, + sa.ForeignKey('expenditures.id'), + primary_key=True)) subitems = sa.Table('subitems', meta.metadata, sa.Column('id', sa.types.Integer, primary_key=True), @@ -96,8 +101,8 @@ orm.mapper(Expenditure, expenditures, properties={ 'splits': orm.relation(Split, backref='expenditure', cascade='all, delete'), - 'tags': orm.relation(Tag, backref='expenditure', - cascade='all, delete'), + '_tags': orm.relation(Tag, secondary=tag_to_expense_map, + collection_class=set, cascade='all, delete'), 'subitems': orm.relation(Subitem, backref='expenditure', cascade='all, delete') }) diff --git a/bluechips/model/expenditure.py b/bluechips/model/expenditure.py index 6b3b1cb..d732fbe 100644 --- a/bluechips/model/expenditure.py +++ b/bluechips/model/expenditure.py @@ -1,8 +1,10 @@ +from sqlalchemy.ext.associationproxy import association_proxy + from bluechips.model.user import User from bluechips.model.split import Split from bluechips.model import meta from bluechips.model.types import Currency -from bluechips.model.tag import Tag +from bluechips.model.tag import create_tag from decimal import Decimal from datetime import datetime import random @@ -16,6 +18,8 @@ class Expenditure(object): if self.date == None: self.date = datetime.now() + tags = association_proxy('_tags', 'name', creator=create_tag) + def __repr__(self): return '' % (self.spender, self.amount) @@ -75,14 +79,6 @@ class Expenditure(object): s = Split(self, user, share, split_text_dict[user]) meta.Session.add(s) - def tag(self, tags): - map(meta.Session.delete, - meta.Session.query(Tag).filter_by(expenditure_id=self.id)) - - for tag in tags: - t = Tag(self, tag) - meta.Session.add(t) - def involves(self, user): "Returns True if ``user`` is involved in this expenditure." return (any((split.user == user) and (split.share != 0) diff --git a/bluechips/model/tag.py b/bluechips/model/tag.py index c6a3661..e2d2ef4 100644 --- a/bluechips/model/tag.py +++ b/bluechips/model/tag.py @@ -1,10 +1,20 @@ +from bluechips.model import meta + class Tag(object): - def __init__(self, expenditure=None, tag=u""): - self.expenditure = expenditure - self.tag = tag + def __init__(self, name=u""): + self.name = name def __repr__(self): - return '' % (self.expenditure, - self.tag) + return '' % (self.name) + +def create_tag(name): + if not isinstance(name, unicode): + raise TypeError('%r is not a unicode object' % type(name).__name__) + t = meta.Session.query(Tag).filter_by(name=name).first() + if t is None: + t = Tag(name) + + return t + __all__ = ['Tag'] -- 2.45.2