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