From b95ea4d6ce3e586d5d56aae3e5351cba6d79fd67 Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Fri, 29 Mar 2019 16:30:39 +0100 Subject: [PATCH] wip add auth_levels --- mellon/models.py | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/mellon/models.py b/mellon/models.py index 20aba33..b89e7f4 100644 --- a/mellon/models.py +++ b/mellon/models.py @@ -1,5 +1,8 @@ +import django from django.contrib.auth.models import Group from django.db import models +from django.db.models.fields.related_descriptors import ReverseOneToOneDescriptor +from django.db.transaction import atomic from django.utils.translation import ugettext_lazy as _ from django.conf import settings @@ -23,8 +26,47 @@ class UserSAMLIdentifier(models.Model): unique_together = (('issuer', 'name_id'),) +class AutoSingleRelatedObjectDescriptor(ReverseOneToOneDescriptor): + """From https://github.com/skorokithakis/django-annoying + Temporary, we will write a migration after testing""" + + @atomic + def __get__(self, instance, instance_type=None): + model = getattr(self.related, 'related_model', self.related.model) + + try: + return ( + super(AutoSingleRelatedObjectDescriptor, self) + .__get__(instance, instance_type) + ) + except model.DoesNotExist: + # Using get_or_create instead() of save() or create() as it better handles race conditions + obj, _ = model.objects.get_or_create(**{self.related.field.name: instance}) + + # Update Django's cache, otherwise first 2 calls to obj.relobj + # will return 2 different in-memory objects + if django.VERSION >= (2, 0): + self.related.set_cached_value(instance, obj) + self.related.field.set_cached_value(obj, instance) + else: + setattr(instance, self.cache_name, obj) + setattr(obj, self.related.field.get_cache_name(), instance) + return obj + + +class AutoOneToOneField(models.OneToOneField): + """From https://github.com/skorokithakis/django-annoying""" + + def contribute_to_related_class(self, cls, related): + setattr( + cls, + related.get_accessor_name(), + AutoSingleRelatedObjectDescriptor(related) + ) + + class AuthenticationLevel(models.Model): - group = models.OneToOneField(Group, related_name='auth_level') + group = AutoOneToOneField(Group, related_name='auth_level') # ou plutot laisser blanc pour qu'il y ait une erreur si on # a pas recu les niveaux ? value = models.PositiveSmallIntegerField(default=1)