Опекун django, разрешения и расширение групп авторизации django на модели «организации»

Джанго стражhttps://github.com/lukaszb/django-guardianэто действительно хорошо написанное приложение с разрешениями уровня объекта -; и я на самом деле прочитал и использовал довольно много других приложений разрешений на уровне объекта django в различных проектах django.

В недавнем проекте, над которым я работаю, я решил использовать django guardian, но у меня есть вопрос о дизайне модели, касающийся плюсов и минусов двух возможных подходов и их соответствующих последствий для производительности sql-запросов:-

  1. используя django.contrib.auth.models.Groupи распространяя это на модели моего пользовательского приложения организации; или

  2. используя вместо этого django.contrib.auth.models.Userи создавая поле m2m для каждого типа организации в приложении моей организации.

Подход #1

# Organisation app's models.py

from django.contrib.auth.models import Group

class StudentClass(models.Model):
    name = models.CharField('Class Name', max_length=255)
    groups = models.ManyToManyField(Group, blank=True)
    size = models.IntegerField('Class Size', blank=True)

class SpecialInterestGroup(models.Model):
    name = models.CharField('Interest Group Name', max_length=255)
    groups = models.ManyToManyField(Group, blank=True)
    description = models.TextField('What our group does!', blank=True)

class TeachingTeam(models.Model):
    name = models.CharField('Teacher Team Name', max_length=255)
    groups = models.ManyToManyField(Group, blank=True)
    specialization = models.TextField('Specialty subject matter', blank=True)

При таком подходе, когда пользователь впервые добавляется в группу (django group ), объект группы создается и также назначается одному из этих трех классов:если этот групповой объект еще не принадлежит классу, в который он добавлен.

Это означает, что каждый объект StudentClass, sc_A, sc_Bи т. д., может содержать множество групп.

Это означает, что мне нужно выяснить, говорит ли конкретный пользователь (myuser)принадлежит определенной организации, я должен запросить все группы, к которым принадлежит пользователь, через groups_myuser_belongto = myuser.groups, а затем запросить все группы, связанные с интересующей меня организацией, через groups_studentclass = sc_A.groups.all(), и поскольку я теперь есть 2 списка, которые мне нужно сравнить, я могу сделать set(groups_myuser_belongto) && set(groups_studentclass), который вернет новый набор, который может содержать 1 или более пересекающихся групп. Если есть 1 или более групп, myuserдействительно является членом sc_A.

Таким образом, эта модель модели подразумевает, что мне придется пройти через множество проблем (и дополнительных запросов ), чтобы узнать, принадлежит ли пользователь организации.

И причина, по которой я использую m2m для групп, заключается в том, чтобы использовать функциональность разрешений на уровне группы, которую предоставляет django guardian.

Практичен ли такой дизайн модели?

Или мне лучше пойти с другим дизайном модели, как этот...

Подход #2

# Organisation app's models.py

from django.contrib.auth.models import User

class StudentClass(models.Model):
    name = models.CharField('Class Name', max_length=255)
    users = models.ManyToManyField(User, blank=True)
    size = models.IntegerField('Class Size', blank=True)

class SpecialInterestGroup(models.Model):
    name = models.CharField('Interest Group Name', max_length=255)
    users = models.ManyToManyField(User, blank=True)
    description = models.TextField('What our group does!', blank=True)

class TeachingTeam(models.Model):
    name = models.CharField('Teacher Team Name', max_length=255)
    users = models.ManyToManyField(User, blank=True)
    specialization = models.TextField('Specialty subject matter', blank=True)

Очевидно, что такой дизайн модели позволяет мне очень легко проверить, принадлежит ли пользовательский объект определенной организации или нет. Все, что мне нужно сделать, чтобы узнать, является ли пользователь johnчастью TeachingTeam maths_teachersили нет, это проверить:

user = User.objects.get(username='john')
maths_teachers = TeachingTeam.objects.get(name='Maths teachers')
if user in maths_teachers.users.all():
    print "Yes, this user is in the Maths teachers organization!"

Но этот дизайн модели подразумевает, что когда я добавляю пользовательский объект в группу(напомню, что я хочу использовать функцию групповых разрешений django guardian ), я должен убедиться, что вызов save()добавляет объект пользователя в группу «Учителя математики» вdjango.contrib.auth.models.GroupИ в объект моего пользовательского класса TeachingTeam«Учителя математики». И это не выглядит очень СУХИМ, не говоря уже о том, что я должен как-то гарантировать, что вызовы сохранения в обеих моделях выполняются в одном transaction.

Существует ли лучший способ проектирования моих моделей с учетом этого варианта использования/требования -использовать группы django и в то же время обеспечить способ «расширения» функциональности собственных групп django (почти так же, как мы расширяем пользовательскую модель django с помощью «user профильное приложение" )?

8
задан Calvin Cheng 23 April 2012 в 03:53
поделиться