Skip to content

Commit

Permalink
Remove the attr argument from ManyRelation
Browse files Browse the repository at this point in the history
Closes #3
  • Loading branch information
daisylb committed Jul 18, 2019
1 parent 64eea99 commit c309bee
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 18 deletions.
4 changes: 2 additions & 2 deletions bridgekeeper/rule_many_relation_tests.py
Expand Up @@ -12,7 +12,7 @@ def test_many_relation_to_user():
u1 = UserFactory(profile__branch__store=s1)
u2 = UserFactory(profile__branch__store=s2)
user_branch_in_store = ManyRelation(
'branch_set', 'branch', Is(lambda u: u.profile.branch))
'branch', Is(lambda u: u.profile.branch))

assert user_branch_in_store.check(u1, s1)
assert user_branch_in_store.check(u2, s2)
Expand All @@ -33,5 +33,5 @@ def test_many_relation_to_user():
def test_many_relation_never_global():
user = UserFactory()
user_branch_in_store = ManyRelation(
'branch_set', 'branch', Is(lambda u: u.profile.branch))
'branch', Is(lambda u: u.profile.branch))
assert not user_branch_in_store.check(user)
26 changes: 10 additions & 16 deletions bridgekeeper/rules.py
Expand Up @@ -475,16 +475,8 @@ class ManyRelation(Rule):
across a :class:`~django.db.models.ManyToManyField`, or the remote
end of a :class:`~django.db.models.ForeignKey`.
:param attr: Name of a many-object relationship to check. This is
the accessor name; the name that you access on a model
instance to get a manager for the other side of the
relationship. If you are on the reverse side of the relationship
(the side where the field is *not* defined), this is typically
``mymodel_set``, where ``mymodel`` is the lowercased model name,
unless you've set
:attr:`~django.db.models.ForeignKey.related_name`.
:type attr: str
:param query_attr: Query name to use; that is, the name that you
:param query_attr: Name of a many-object relationship to check. This
This is the name that you
use when filtering this relationship using ``.filter()``.
If you are on the side of the relationship where the field
is defined, this is typically the lowercased model name (e.g.
Expand All @@ -500,18 +492,17 @@ class ManyRelation(Rule):
relationship with their agency::
perms['foo.view_customer'] = ManyRelation(
'agency_set', 'agency', Is(lambda user: user.agency))
'agency', Is(lambda user: user.agency))
"""

def __init__(self, attr, query_attr, rule):
def __init__(self, query_attr, rule):
# TODO: add support for 'all' as well as 'exists'
self.attr = attr
self.query_attr = query_attr
self.rule = rule

def __repr__(self):
return "ManyRelation({!r}, {!r}, {!r})".format(
self.attr, self.query_attr, self.rule)
return "ManyRelation({!r}, {!r})".format(
self.query_attr, self.rule)

def query(self, user):
# Unfortunately you can't use Q objects on a relation, only proper
Expand All @@ -527,5 +518,8 @@ def check(self, user, instance=None):
related_q = self.rule.query(user)
if related_q is UNIVERSAL or related_q is EMPTY:
return related_q
related_manager = getattr(instance, self.attr)
attr = instance.__class__._meta.get_field(
self.query_attr,
).get_accessor_name()
related_manager = getattr(instance, attr)
return related_manager.filter(related_q).exists()
1 change: 1 addition & 0 deletions docs/changelog.rst
Expand Up @@ -5,6 +5,7 @@ dev
---

- **Breaking change:** :class:`~bridgekeeper.rules.Relation` and :class:`~bridgekeeper.rules.ManyRelation` no longer require the model class on the other side of the relation to be passed in as an argument.
- **Breaking change:** :class:`~bridgekeeper.rules.ManyRelation` removes the ``attr`` argument, requiring only ``query_attr``.
- **Breaking change:** Python 3.4 and Django 1.11 are no longer supported.

0.7
Expand Down

0 comments on commit c309bee

Please sign in to comment.