Changeset 355

Show
Ignore:
Timestamp:
07/07/08 14:55:41 (5 years ago)
Author:
ged
Message:

- Added support for viewonly relationships (OneToMany and OneToOne).

Location:
elixir/trunk
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • elixir/trunk/CHANGES

    r354 r355  
    2222  any). 
    2323- Added on_reconstitute event/method decorator. Only works with SA 0.5. 
     24- Added support for viewonly relationships (OneToMany and OneToOne). 
    2425 
    2526Changes: 
  • elixir/trunk/elixir/relationships.py

    r350 r355  
    413413 
    414414        kwargs.update(self.get_prop_kwargs()) 
     415 
    415416        self.property = relation(self.target, **kwargs) 
    416417        self.add_mapper_property(self.name, self.property) 
     
    451452 
    452453    def is_inverse(self, other): 
    453         return other is not self and \ 
     454        # viewonly relationships shouldn't match as inverse of anything (so 
     455        # that no backref is created -- which doesn't make sense in that case) 
     456        viewonly = self.kwargs.get('viewonly', False) or \ 
     457                   other.kwargs.get('viewonly', False) 
     458        return not viewonly and \ 
     459               other is not self and \ 
    454460               self.match_type_of(other) and \ 
    455461               self.entity == other.target and \ 
     
    612618 
    613619    def create_keys(self, pk): 
     620        # When using a viewonly relationship, you are on your own: Elixir 
     621        # doesn't check that a corresponding ManyToOne relationship exists. 
     622        if self.kwargs.get('viewonly', False): 
     623            return 
     624 
    614625        # make sure an inverse relationship exists 
    615626        if self.inverse is None: 
     
    637648            kwargs['remote_side'] = self.inverse.foreign_key 
    638649 
    639         if self.inverse.primaryjoin_clauses: 
    640             kwargs['primaryjoin'] = and_(*self.inverse.primaryjoin_clauses) 
     650        # viewonly relationships do not have any inverse (and they provide  
     651        # their primaryjoin argument manually anyway). 
     652        if not self.kwargs.get('viewonly', False): 
     653            if self.inverse.primaryjoin_clauses: 
     654                kwargs['primaryjoin'] = and_(*self.inverse.primaryjoin_clauses) 
    641655 
    642656        kwargs.update(self.kwargs) 
  • elixir/trunk/tests/test_o2m.py

    r349 r355  
    44 
    55from elixir import * 
     6from sqlalchemy import and_ 
     7from sqlalchemy.ext.orderinglist import ordering_list 
    68 
    79def setup(): 
     
    105107        print root 
    106108 
     109    def test_viewonly(self): 
     110        class User(Entity): 
     111            two_blurbs = OneToMany('Blurb', primaryjoin=lambda: 
     112                and_(Blurb.user_id == User.id, Blurb.position < 2), 
     113                viewonly=True 
     114            ) 
     115            blurbs = OneToMany('Blurb', 
     116                               collection_class=ordering_list('position'), 
     117                               order_by='position') 
     118 
     119        class Blurb(Entity): 
     120            user = ManyToOne('User') 
     121            position = Field(Integer) 
     122            blurb = Field(Unicode(255)) 
     123 
     124            def __init__(self, blurb, **kwargs): 
     125                super(Blurb, self).__init__(blurb=blurb, **kwargs) 
     126 
     127            def __repr__(self): 
     128                return 'Blurb(%r, %r)' % (self.position, self.blurb) 
     129 
     130        setup_all(True) 
     131 
     132        user = User(blurbs=[Blurb(u'zero'), Blurb(u'one'), Blurb(u'two')]) 
     133 
     134        session.commit() 
     135        session.clear() 
     136 
     137        user = User.get(1) 
     138        assert len(user.two_blurbs) == 2 
     139        assert user.two_blurbs[0].blurb == 'zero' 
     140        assert user.two_blurbs[1].blurb == 'one' 
     141 
    107142    def test_has_many_syntax(self): 
    108143        class Person(Entity):