Replace ForeignKey.field.rel.to --> field.model
rel.to dropped on Django 2.0
This commit is contained in:
parent
d863598d81
commit
7d975637d5
|
@ -175,7 +175,7 @@ def delete_related_services(modeladmin, request, queryset):
|
||||||
for model, objs in collector.model_objs.items():
|
for model, objs in collector.model_objs.items():
|
||||||
count = 0
|
count = 0
|
||||||
# discount main systemuser
|
# discount main systemuser
|
||||||
if model is modeladmin.model.main_systemuser.field.rel.to:
|
if model is modeladmin.model.main_systemuser.field.model:
|
||||||
count = len(objs) - 1
|
count = len(objs) - 1
|
||||||
# Discount account
|
# Discount account
|
||||||
elif model is not modeladmin.model and model in registered_services:
|
elif model is not modeladmin.model and model in registered_services:
|
||||||
|
|
|
@ -34,7 +34,7 @@ def create_account_creation_form():
|
||||||
fields[field_name] = forms.BooleanField(
|
fields[field_name] = forms.BooleanField(
|
||||||
initial=True, required=False, label=label, help_text=help_text)
|
initial=True, required=False, label=label, help_text=help_text)
|
||||||
create_related.append((model, key, kwargs, help_text))
|
create_related.append((model, key, kwargs, help_text))
|
||||||
|
|
||||||
def clean(self, create_related=create_related):
|
def clean(self, create_related=create_related):
|
||||||
""" unique usernames between accounts and system users """
|
""" unique usernames between accounts and system users """
|
||||||
cleaned_data = UserCreationForm.clean(self)
|
cleaned_data = UserCreationForm.clean(self)
|
||||||
|
@ -47,7 +47,7 @@ def create_account_creation_form():
|
||||||
# Previous validation error
|
# Previous validation error
|
||||||
return
|
return
|
||||||
errors = {}
|
errors = {}
|
||||||
systemuser_model = Account.main_systemuser.field.rel.to
|
systemuser_model = Account.main_systemuser.field.model
|
||||||
if systemuser_model.objects.filter(username=account.username).exists():
|
if systemuser_model.objects.filter(username=account.username).exists():
|
||||||
errors['username'] = _("A system user with this name already exists.")
|
errors['username'] = _("A system user with this name already exists.")
|
||||||
for model, key, related_kwargs, __ in create_related:
|
for model, key, related_kwargs, __ in create_related:
|
||||||
|
@ -62,11 +62,11 @@ def create_account_creation_form():
|
||||||
params={'type': verbose_name})
|
params={'type': verbose_name})
|
||||||
if errors:
|
if errors:
|
||||||
raise ValidationError(errors)
|
raise ValidationError(errors)
|
||||||
|
|
||||||
def save_model(self, account):
|
def save_model(self, account):
|
||||||
enable_systemuser=self.cleaned_data['enable_systemuser']
|
enable_systemuser=self.cleaned_data['enable_systemuser']
|
||||||
account.save(active_systemuser=enable_systemuser)
|
account.save(active_systemuser=enable_systemuser)
|
||||||
|
|
||||||
def save_related(self, account):
|
def save_related(self, account):
|
||||||
for model, key, related_kwargs, __ in settings.ACCOUNTS_CREATE_RELATED:
|
for model, key, related_kwargs, __ in settings.ACCOUNTS_CREATE_RELATED:
|
||||||
model = apps.get_model(model)
|
model = apps.get_model(model)
|
||||||
|
@ -76,14 +76,14 @@ def create_account_creation_form():
|
||||||
key: eval(value, {'account': account}) for key, value in related_kwargs.items()
|
key: eval(value, {'account': account}) for key, value in related_kwargs.items()
|
||||||
}
|
}
|
||||||
model.objects.create(account=account, **kwargs)
|
model.objects.create(account=account, **kwargs)
|
||||||
|
|
||||||
fields.update({
|
fields.update({
|
||||||
'create_related_fields': list(fields.keys()),
|
'create_related_fields': list(fields.keys()),
|
||||||
'clean': clean,
|
'clean': clean,
|
||||||
'save_model': save_model,
|
'save_model': save_model,
|
||||||
'save_related': save_related,
|
'save_related': save_related,
|
||||||
})
|
})
|
||||||
|
|
||||||
return type('AccountCreationForm', (UserCreationForm,), fields)
|
return type('AccountCreationForm', (UserCreationForm,), fields)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ def validate_contact(request, bill, error=True):
|
||||||
message = msg.format(relation=_("Related"), account=account, url=url)
|
message = msg.format(relation=_("Related"), account=account, url=url)
|
||||||
send(request, mark_safe(message))
|
send(request, mark_safe(message))
|
||||||
valid = False
|
valid = False
|
||||||
main = type(bill).account.field.rel.to.objects.get_main()
|
main = type(bill).account.field.model.objects.get_main()
|
||||||
if not hasattr(main, 'billcontact'):
|
if not hasattr(main, 'billcontact'):
|
||||||
account = force_text(main)
|
account = force_text(main)
|
||||||
url = reverse('admin:accounts_account_change', args=(main.id,))
|
url = reverse('admin:accounts_account_change', args=(main.id,))
|
||||||
|
|
|
@ -12,7 +12,7 @@ from .models import List
|
||||||
|
|
||||||
class RelatedDomainSerializer(AccountSerializerMixin, RelatedHyperlinkedModelSerializer):
|
class RelatedDomainSerializer(AccountSerializerMixin, RelatedHyperlinkedModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = List.address_domain.field.rel.to
|
model = List.address_domain.field.model
|
||||||
fields = ('url', 'id', 'name')
|
fields = ('url', 'id', 'name')
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,14 +26,14 @@ class ListSerializer(AccountSerializerMixin, SetPasswordHyperlinkedSerializer):
|
||||||
'This value may contain any ascii character except for '
|
'This value may contain any ascii character except for '
|
||||||
' \'/"/\\/ characters.'), 'invalid'),
|
' \'/"/\\/ characters.'), 'invalid'),
|
||||||
])
|
])
|
||||||
|
|
||||||
address_domain = RelatedDomainSerializer(required=False)
|
address_domain = RelatedDomainSerializer(required=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = List
|
model = List
|
||||||
fields = ('url', 'id', 'name', 'password', 'address_name', 'address_domain', 'admin_email', 'is_active',)
|
fields = ('url', 'id', 'name', 'password', 'address_name', 'address_domain', 'admin_email', 'is_active',)
|
||||||
postonly_fields = ('name', 'password')
|
postonly_fields = ('name', 'password')
|
||||||
|
|
||||||
def validate_address_domain(self, address_name):
|
def validate_address_domain(self, address_name):
|
||||||
if self.instance:
|
if self.instance:
|
||||||
address_domain = address_domain or self.instance.address_domain
|
address_domain = address_domain or self.instance.address_domain
|
||||||
|
|
|
@ -44,7 +44,7 @@ class Mailbox(models.Model):
|
||||||
def active(self):
|
def active(self):
|
||||||
try:
|
try:
|
||||||
return self.is_active and self.account.is_active
|
return self.is_active and self.account.is_active
|
||||||
except type(self).account.field.rel.to.DoesNotExist:
|
except type(self).account.field.model.DoesNotExist:
|
||||||
return self.is_active
|
return self.is_active
|
||||||
|
|
||||||
def disable(self):
|
def disable(self):
|
||||||
|
|
|
@ -8,17 +8,17 @@ from .models import Mailbox, Address
|
||||||
|
|
||||||
class RelatedDomainSerializer(AccountSerializerMixin, RelatedHyperlinkedModelSerializer):
|
class RelatedDomainSerializer(AccountSerializerMixin, RelatedHyperlinkedModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Address.domain.field.rel.to
|
model = Address.domain.field.model
|
||||||
fields = ('url', 'id', 'name')
|
fields = ('url', 'id', 'name')
|
||||||
|
|
||||||
|
|
||||||
class RelatedAddressSerializer(AccountSerializerMixin, serializers.HyperlinkedModelSerializer):
|
class RelatedAddressSerializer(AccountSerializerMixin, serializers.HyperlinkedModelSerializer):
|
||||||
domain = RelatedDomainSerializer()
|
domain = RelatedDomainSerializer()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Address
|
model = Address
|
||||||
fields = ('url', 'id', 'name', 'domain', 'forward')
|
fields = ('url', 'id', 'name', 'domain', 'forward')
|
||||||
#
|
#
|
||||||
# def from_native(self, data, files=None):
|
# def from_native(self, data, files=None):
|
||||||
# queryset = self.opts.model.objects.filter(account=self.account)
|
# queryset = self.opts.model.objects.filter(account=self.account)
|
||||||
# return get_object_or_404(queryset, name=data['name'])
|
# return get_object_or_404(queryset, name=data['name'])
|
||||||
|
@ -26,7 +26,7 @@ class RelatedAddressSerializer(AccountSerializerMixin, serializers.HyperlinkedMo
|
||||||
|
|
||||||
class MailboxSerializer(AccountSerializerMixin, SetPasswordHyperlinkedSerializer):
|
class MailboxSerializer(AccountSerializerMixin, SetPasswordHyperlinkedSerializer):
|
||||||
addresses = RelatedAddressSerializer(many=True, read_only=True)
|
addresses = RelatedAddressSerializer(many=True, read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Mailbox
|
model = Mailbox
|
||||||
fields = (
|
fields = (
|
||||||
|
@ -44,11 +44,11 @@ class RelatedMailboxSerializer(AccountSerializerMixin, RelatedHyperlinkedModelSe
|
||||||
class AddressSerializer(AccountSerializerMixin, serializers.HyperlinkedModelSerializer):
|
class AddressSerializer(AccountSerializerMixin, serializers.HyperlinkedModelSerializer):
|
||||||
domain = RelatedDomainSerializer()
|
domain = RelatedDomainSerializer()
|
||||||
mailboxes = RelatedMailboxSerializer(many=True, required=False) #allow_add_remove=True
|
mailboxes = RelatedMailboxSerializer(many=True, required=False) #allow_add_remove=True
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Address
|
model = Address
|
||||||
fields = ('url', 'id', 'name', 'domain', 'mailboxes', 'forward')
|
fields = ('url', 'id', 'name', 'domain', 'mailboxes', 'forward')
|
||||||
|
|
||||||
def validate(self, attrs):
|
def validate(self, attrs):
|
||||||
attrs = super(AddressSerializer, self).validate(attrs)
|
attrs = super(AddressSerializer, self).validate(attrs)
|
||||||
if not attrs['mailboxes'] and not attrs['forward']:
|
if not attrs['mailboxes'] and not attrs['forward']:
|
||||||
|
|
|
@ -15,7 +15,7 @@ def cancel_orders(sender, **kwargs):
|
||||||
if sender._meta.app_label not in settings.ORDERS_EXCLUDED_APPS:
|
if sender._meta.app_label not in settings.ORDERS_EXCLUDED_APPS:
|
||||||
instance = kwargs['instance']
|
instance = kwargs['instance']
|
||||||
# Account delete will delete all related orders, no need to maintain order consistency
|
# Account delete will delete all related orders, no need to maintain order consistency
|
||||||
if isinstance(instance, Order.account.field.rel.to):
|
if isinstance(instance, Order.account.field.model):
|
||||||
return
|
return
|
||||||
if type(instance) in services:
|
if type(instance) in services:
|
||||||
for order in Order.objects.by_object(instance).active():
|
for order in Order.objects.by_object(instance).active():
|
||||||
|
|
|
@ -42,7 +42,7 @@ def clean_custom_url(saas):
|
||||||
)
|
)
|
||||||
except Website.DoesNotExist:
|
except Website.DoesNotExist:
|
||||||
# get or create domain
|
# get or create domain
|
||||||
Domain = Website.domains.field.rel.to
|
Domain = Website.domains.field.model
|
||||||
try:
|
try:
|
||||||
domain = Domain.objects.get(name=url.netloc)
|
domain = Domain.objects.get(name=url.netloc)
|
||||||
except Domain.DoesNotExist:
|
except Domain.DoesNotExist:
|
||||||
|
@ -51,7 +51,7 @@ def clean_custom_url(saas):
|
||||||
})
|
})
|
||||||
if domain.account != account:
|
if domain.account != account:
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
'custom_url': _("Domain %s does not belong to account %s, it's from %s.") %
|
'custom_url': _("Domain %s does not belong to account %s, it's from %s.") %
|
||||||
(url.netloc, account, domain.account),
|
(url.netloc, account, domain.account),
|
||||||
})
|
})
|
||||||
# Create new website for custom_url
|
# Create new website for custom_url
|
||||||
|
@ -110,7 +110,7 @@ def create_or_update_directive(saas):
|
||||||
account=account,
|
account=account,
|
||||||
)
|
)
|
||||||
except Website.DoesNotExist:
|
except Website.DoesNotExist:
|
||||||
Domain = Website.domains.field.rel.to
|
Domain = Website.domains.field.model
|
||||||
domain = Domain.objects.get(name=url.netloc)
|
domain = Domain.objects.get(name=url.netloc)
|
||||||
# Create new website for custom_url
|
# Create new website for custom_url
|
||||||
tgt_server = Server.objects.get(name='web.pangea.lan')
|
tgt_server = Server.objects.get(name='web.pangea.lan')
|
||||||
|
|
|
@ -61,7 +61,7 @@ class SystemUser(models.Model):
|
||||||
def active(self):
|
def active(self):
|
||||||
try:
|
try:
|
||||||
return self.is_active and self.account.is_active
|
return self.is_active and self.account.is_active
|
||||||
except type(self).account.field.rel.to.DoesNotExist:
|
except type(self).account.field.model.DoesNotExist:
|
||||||
return self.is_active
|
return self.is_active
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
|
|
|
@ -13,23 +13,23 @@ from .validators import validate_domain_protocol
|
||||||
|
|
||||||
class RelatedDomainSerializer(AccountSerializerMixin, RelatedHyperlinkedModelSerializer):
|
class RelatedDomainSerializer(AccountSerializerMixin, RelatedHyperlinkedModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Website.domains.field.rel.to
|
model = Website.domains.field.model
|
||||||
fields = ('url', 'id', 'name')
|
fields = ('url', 'id', 'name')
|
||||||
|
|
||||||
|
|
||||||
class RelatedWebAppSerializer(AccountSerializerMixin, RelatedHyperlinkedModelSerializer):
|
class RelatedWebAppSerializer(AccountSerializerMixin, RelatedHyperlinkedModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Content.webapp.field.rel.to
|
model = Content.webapp.field.model
|
||||||
fields = ('url', 'id', 'name', 'type')
|
fields = ('url', 'id', 'name', 'type')
|
||||||
|
|
||||||
|
|
||||||
class ContentSerializer(serializers.ModelSerializer):
|
class ContentSerializer(serializers.ModelSerializer):
|
||||||
webapp = RelatedWebAppSerializer()
|
webapp = RelatedWebAppSerializer()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Content
|
model = Content
|
||||||
fields = ('webapp', 'path')
|
fields = ('webapp', 'path')
|
||||||
|
|
||||||
def get_identity(self, data):
|
def get_identity(self, data):
|
||||||
return '%s-%s' % (data.get('website'), data.get('path'))
|
return '%s-%s' % (data.get('website'), data.get('path'))
|
||||||
|
|
||||||
|
@ -38,10 +38,10 @@ class DirectiveSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = WebsiteDirective
|
model = WebsiteDirective
|
||||||
fields = ('name', 'value')
|
fields = ('name', 'value')
|
||||||
|
|
||||||
def to_representation(self, instance):
|
def to_representation(self, instance):
|
||||||
return {prop.name: prop.value for prop in instance.all()}
|
return {prop.name: prop.value for prop in instance.all()}
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
@ -50,12 +50,12 @@ class WebsiteSerializer(AccountSerializerMixin, HyperlinkedModelSerializer):
|
||||||
domains = RelatedDomainSerializer(many=True, required=False)
|
domains = RelatedDomainSerializer(many=True, required=False)
|
||||||
contents = ContentSerializer(required=False, many=True, source='content_set')
|
contents = ContentSerializer(required=False, many=True, source='content_set')
|
||||||
directives = DirectiveSerializer(required=False)
|
directives = DirectiveSerializer(required=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Website
|
model = Website
|
||||||
fields = ('url', 'id', 'name', 'protocol', 'domains', 'is_active', 'contents', 'directives')
|
fields = ('url', 'id', 'name', 'protocol', 'domains', 'is_active', 'contents', 'directives')
|
||||||
postonly_fields = ('name',)
|
postonly_fields = ('name',)
|
||||||
|
|
||||||
def validate(self, data):
|
def validate(self, data):
|
||||||
""" Prevent multiples domains on the same protocol """
|
""" Prevent multiples domains on the same protocol """
|
||||||
# Validate location and directive uniqueness
|
# Validate location and directive uniqueness
|
||||||
|
@ -87,14 +87,14 @@ class WebsiteSerializer(AccountSerializerMixin, HyperlinkedModelSerializer):
|
||||||
if errors:
|
if errors:
|
||||||
raise ValidationError(errors)
|
raise ValidationError(errors)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
directives_data = validated_data.pop('directives')
|
directives_data = validated_data.pop('directives')
|
||||||
webapp = super(WebsiteSerializer, self).create(validated_data)
|
webapp = super(WebsiteSerializer, self).create(validated_data)
|
||||||
for key, value in directives_data.items():
|
for key, value in directives_data.items():
|
||||||
WebsiteDirective.objects.create(webapp=webapp, name=key, value=value)
|
WebsiteDirective.objects.create(webapp=webapp, name=key, value=value)
|
||||||
return webap
|
return webap
|
||||||
|
|
||||||
def update_directives(self, instance, directives_data):
|
def update_directives(self, instance, directives_data):
|
||||||
existing = {}
|
existing = {}
|
||||||
for obj in instance.directives.all():
|
for obj in instance.directives.all():
|
||||||
|
@ -112,13 +112,13 @@ class WebsiteSerializer(AccountSerializerMixin, HyperlinkedModelSerializer):
|
||||||
directive.save(update_fields=('value',))
|
directive.save(update_fields=('value',))
|
||||||
for to_delete in set(existing.keys())-posted:
|
for to_delete in set(existing.keys())-posted:
|
||||||
existing[to_delete].delete()
|
existing[to_delete].delete()
|
||||||
|
|
||||||
def update_contents(self, instance, contents_data):
|
def update_contents(self, instance, contents_data):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def update_domains(self, instance, domains_data):
|
def update_domains(self, instance, domains_data):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def update(self, instance, validated_data):
|
def update(self, instance, validated_data):
|
||||||
directives_data = validated_data.pop('directives')
|
directives_data = validated_data.pop('directives')
|
||||||
domains_data = validated_data.pop('domains')
|
domains_data = validated_data.pop('domains')
|
||||||
|
|
|
@ -7,24 +7,24 @@ import inspect
|
||||||
|
|
||||||
|
|
||||||
class Permission(object):
|
class Permission(object):
|
||||||
"""
|
"""
|
||||||
Base class used for defining class and instance permissions.
|
Base class used for defining class and instance permissions.
|
||||||
Enabling an ''intuitive'' interface for checking permissions:
|
Enabling an ''intuitive'' interface for checking permissions:
|
||||||
|
|
||||||
# Define permissions
|
# Define permissions
|
||||||
class NodePermission(Permission):
|
class NodePermission(Permission):
|
||||||
def change(self, obj, cls, user):
|
def change(self, obj, cls, user):
|
||||||
return obj.user == user
|
return obj.user == user
|
||||||
|
|
||||||
# Provide permissions
|
# Provide permissions
|
||||||
Node.has_permission = NodePermission()
|
Node.has_permission = NodePermission()
|
||||||
|
|
||||||
# Check class permission by passing it as string
|
# Check class permission by passing it as string
|
||||||
Node.has_permission(user, 'change')
|
Node.has_permission(user, 'change')
|
||||||
|
|
||||||
# Check class permission by calling it
|
# Check class permission by calling it
|
||||||
Node.has_permission.change(user)
|
Node.has_permission.change(user)
|
||||||
|
|
||||||
# Check instance permissions
|
# Check instance permissions
|
||||||
node = Node()
|
node = Node()
|
||||||
node.has_permission(user, 'change')
|
node.has_permission(user, 'change')
|
||||||
|
@ -35,7 +35,7 @@ class Permission(object):
|
||||||
# call interface: has_permission(user, 'perm')
|
# call interface: has_permission(user, 'perm')
|
||||||
def call(user, perm):
|
def call(user, perm):
|
||||||
return getattr(self, perm)(obj, cls, user)
|
return getattr(self, perm)(obj, cls, user)
|
||||||
|
|
||||||
# has_permission.perm(user)
|
# has_permission.perm(user)
|
||||||
for func in inspect.getmembers(type(self), predicate=inspect.ismethod):
|
for func in inspect.getmembers(type(self), predicate=inspect.ismethod):
|
||||||
if not isinstance(self, func[1].__self__.__class__):
|
if not isinstance(self, func[1].__self__.__class__):
|
||||||
|
@ -45,7 +45,7 @@ class Permission(object):
|
||||||
# self methods
|
# self methods
|
||||||
setattr(call, func[0], functools.partial(func[1], self, obj, cls))
|
setattr(call, func[0], functools.partial(func[1], self, obj, cls))
|
||||||
return call
|
return call
|
||||||
|
|
||||||
def _aggregate(self, obj, cls, perm):
|
def _aggregate(self, obj, cls, perm):
|
||||||
""" Aggregates cls methods to self class"""
|
""" Aggregates cls methods to self class"""
|
||||||
for method in inspect.getmembers(perm, predicate=inspect.ismethod):
|
for method in inspect.getmembers(perm, predicate=inspect.ismethod):
|
||||||
|
@ -68,7 +68,7 @@ class AllowAllPermission(object):
|
||||||
""" Fake object that always returns True """
|
""" Fake object that always returns True """
|
||||||
def __call__(self, *args):
|
def __call__(self, *args):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
return lambda n: True
|
return lambda n: True
|
||||||
|
|
||||||
|
@ -76,13 +76,13 @@ class AllowAllPermission(object):
|
||||||
class RelatedPermission(Permission):
|
class RelatedPermission(Permission):
|
||||||
"""
|
"""
|
||||||
Inherit permissions of a related object
|
Inherit permissions of a related object
|
||||||
|
|
||||||
The following example will inherit permissions from sliver_iface.sliver.slice
|
The following example will inherit permissions from sliver_iface.sliver.slice
|
||||||
SliverIfaces.has_permission = RelatedPermission('sliver.slices')
|
SliverIfaces.has_permission = RelatedPermission('sliver.slices')
|
||||||
"""
|
"""
|
||||||
def __init__(self, relation):
|
def __init__(self, relation):
|
||||||
self.relation = relation
|
self.relation = relation
|
||||||
|
|
||||||
def __get__(self, obj, cls):
|
def __get__(self, obj, cls):
|
||||||
""" Hacking object internals to provide means for the mentioned interface """
|
""" Hacking object internals to provide means for the mentioned interface """
|
||||||
# Walk through FK relations
|
# Walk through FK relations
|
||||||
|
@ -90,17 +90,17 @@ class RelatedPermission(Permission):
|
||||||
if obj is None:
|
if obj is None:
|
||||||
parent = cls
|
parent = cls
|
||||||
for relation in relations:
|
for relation in relations:
|
||||||
parent = getattr(parent, relation).field.rel.to
|
parent = getattr(parent, relation).field.model
|
||||||
else:
|
else:
|
||||||
parent = functools.reduce(getattr, relations, obj)
|
parent = functools.reduce(getattr, relations, obj)
|
||||||
|
|
||||||
# call interface: has_permission(user, 'perm')
|
# call interface: has_permission(user, 'perm')
|
||||||
def call(user, perm):
|
def call(user, perm):
|
||||||
return parent.has_permission(user, perm)
|
return parent.has_permission(user, perm)
|
||||||
|
|
||||||
# method interface: has_permission.perm(user)
|
# method interface: has_permission.perm(user)
|
||||||
for name, func in parent.has_permission.__dict__.items():
|
for name, func in parent.has_permission.__dict__.items():
|
||||||
if not name.startswith('_'):
|
if not name.startswith('_'):
|
||||||
setattr(call, name, func)
|
setattr(call, name, func)
|
||||||
|
|
||||||
return call
|
return call
|
||||||
|
|
Loading…
Reference in New Issue