2014-05-04 14 views
10

Obecnie tworzę strukturę, w której mam pracowników należących do firmy. W ramach tej firmy muszę mieć możliwość tworzenia kilku grup. Szanse, jeśli będziesz. Możesz przydzielić mniej uprawnień, aby obniżyć stopnie i więcej uprawnień do wyższych rang.Grupy na obiekt przy użyciu uprawnień do obiektów Django i django-guardian

Chcę przejść do uprawnień na poziomie obiektu i zauważyłem, że projekt django-guardian dał mi dokładnie to, czego potrzebowałem. Działa z natywnymi obiektami User i Group, więc teraz próbuję znaleźć sposób na implementację natywnego obiektu grupy w obiekcie firmy.

Problemy, które napotykam, to to, że nazwa w grupie jest niepowtarzalna. Jeśli więc dwie firmy dodadzą tę samą grupę, pojawią się błędy.

Znalazłem implementację, która działa w pewien sposób, ale wydaje mi się dość "hacky" do mnie. W mojej firmie oświadczyłem zmienną grupy, która odwołuje Grupa:

class Company(models.Model): 
    ... 
    groups = models.ManyToManyField(Group, through='CompanyRole') 

CompanyRole zasadzie mieści się nazwę grupy i odniesienie do Spółki i Grupy

class CompanyRole(models.Model): 
    group = models.ForeignKey(Group) 
    company = models.ForeignKey(Company) 
    real_name = models.CharField(max_length=60, verbose_name=_('Real name')) 

    objects = CompanyGroupManager() 

utworzonego niestandardowego menedżera z wygodnym sposobem, aby dodać nowa "grupa firmowa"

class CompanyGroupManager(models.Manager): 
    def create_group(self, company, group_name): 
     un_group_name = str(company.id) + '#' + group_name 
     group = Group.objects.create(name=un_group_name) 
     company_group = self.model(
      real_name=group_name, 
      company=company, 
      group=group 
     ) 

     company_group.save(using=self._db) 
     return company_group 

Oto część, której naprawdę nie czuję się komfortowo. Aby zmienić problem z unikalną nazwą w modelu Grupy, użyłem kombinacji identyfikatora firmy, znaku hash i rzeczywistej nazwy grupy, aby uniknąć konfliktów.

Teraz moje pytanie brzmi: czy istnieją lepsze metody w moim scenariuszu, czy brakuje mi czegoś lub czy jest to dobry sposób na osiągnięcie tego, czego potrzebuję?

+0

Czy możesz używać niestandardowych uprawnień w modelu Firmy zamiast grup? – Fiver

+0

Zasadniczo chcę to zrobić. W firmie powinieneś być w stanie tworzyć działy, w których możesz udzielać globalnych uprawnień i uprawnień do obiektów. Załóżmy, że masz dział zwany młodszymi programistami, chcę mieć możliwość udzielania im pełnych uprawnień do niektórych projektów, ale na całym świecie dawać im bardzo małe uprawnienia do innych tworzonych projektów. Jest to możliwe teraz, ale moje rozwiązanie wydaje się raczej hacky. Co masz na myśli przez twarde, połączone uprawnienia niestandardowe? –

+1

Cześć Jeffrey, mam na myśli użycie atrybutu Meta 'permissions' do zdefiniowania własnych uprawnień, które można sprawdzić. Wspomniałeś kilka innych modeli, których nie ma w opublikowanym kodzie, projektach i działach, więc jestem trochę niejasny w twojej strukturze modelu. Ale myślę, że widzę, co chcesz osiągnąć. Dodam odpowiedź za pomocą konfiguracji, z której korzystałem w przeszłości. Czy możesz podać przykładową listę uprawnień/ról, które chcesz mieć dla użytkowników? – Fiver

Odpowiedz

2

Niestety nie ma możliwości poruszania się unikalnym wymogu, to dlatego, że to pole jest używany jako identyfikator: https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.Field.unique

Twoje opcje są następujące:

1) Mocking modelu.

Zasadniczo wystarczy utworzyć nowy model grupy, który nie ma wyjątkowych wymagań. Wadą jest to, że musisz go używać wszędzie, więc jeśli wymaga to aktualizacji aplikacji innych firm, może nie być tego wart.

2) utwórz unikatową nazwę. (Tak jak Ty)

Upewnij się, że dobrze dokumentujesz swoją konwencję, aby wszyscy przyszli koderowie wiedzieli, na co patrzą. Coś takiego jak "nazwa firmy" # "nazwa grupy" może mieć bardziej intuicyjny sens niż identyfikator . Jeśli hash może się pojawić, użyj bardziej określonego separatora ("__" jest stosunkowo popularnym sposobem łączenia powiązanych pojęć w django, mógłbym pójść po to).

Zalecam dodanie następujących elementów, aby ułatwić dostęp do nazwiska.

def get_name(self): 
    # Explain how you get the group name from your uniqueified name 
    return self.name.split('#')[1] 

Group.add_to_class('get_name', get_name) 

Po uzyskaniu dostępu nazwę swojej grupy w aplikacji, po prostu zrobić:

my_group.get_name() 

kupili także umieścić generujący nazwę uniqueified się z zastąpiona wersja save().Da Ci to lepszy podział między modelem a widokiem ...

+0

Dokładnie to samo zakończyłem. :) Jednak wadą tego rozwiązania jest to, co następuje: Na przykład masz model: MyModel. Z uprawnieniami: view_mymodel, change_mymodel, add_mymodel, delete_mymodel. Aby wyświetlić, zmienić i usunąć uprawnienia, dodaj je do obiektu i sprawdź uprawnienia (user.has_perm ('view_mymodel', obj)). Ale dla dodania nie możesz i będziesz używał user.has_perm ('add_mymodel'). Co się stanie, jeśli użytkownik jednej organizacji znajduje się w grupie z uprawnieniami do dodawania, a w drugiej organizacji użytkownik jest w grupie? – gabn88