有条件地注册内部 Django 站点



我正在使用Django(带有python-social-auth(来验证内部学生信息系统的用户。 我们目前有一个外部 SQL 表,该表根据用户的 Google Apps 电子邮件地址跟踪用户是:管理员、教职员工还是学生。

当前post_save功能

@receiver(post_save, sender=User)
def create_student_or_staff(sender, instance, created, **kwargs):
if created:
try:
state = UserState.objects.get(
email=instance.email
)
except UserState.DoesNotExist:
# if exception is raised here, user is not created but site crashes
# if no exception is raised, a user is created but no admin, staff or student instance
pass
if state.staff:
if state.is_admin:
Admin.objects.create(
user=instance
)
else:
Staff.objects.create(
user=instance
)
else:
class_instance = None
if state.year and state.band and state.set:
class_model = apps.get_model('class_groups.ClassGroup')
class_instance = class_model.objects.get(
year=state.year,
band=state.band,
set=state.set
)
Student.objects.create(
user=instance,
class_group=class_instance
)

当用户第一次尝试登录时,我希望能够检查该数据库以查看它们是否满足任何条件。 目前,如果用户不在 UserState 表上,则使用用户的 post_save 信号(我也尝试使用 pre_save 但没有骰子(以某种方式停止创建 Django 用户对象。

这可能吗?我目前可以停止创建用户实例的唯一方法是在post_save期间引发异常,这当然并不理想。

很抱歉这个问题很宽泛,如果您需要任何细节,请告诉我。提前感谢!

我认为最好的选择是使用user_pass_test函数或使用UserPassTestMixin作为类基础视图。

最终为 python-social 添加了一个新的管道,用于检查传入的电子邮件地址是否已在 UserState 数据库中。 检索社交详细信息后添加的管道。

settings.py

# adding all the pipelines in for the time being, can adjust later
SOCIAL_AUTH_PIPELINE = (
'social.pipeline.social_auth.social_details',
# custom pipeline
'sis_users.pipeline.user_state_exists',
'social.pipeline.user.user_details',
...
)

pipeline.py

def user_state_exists(backend, details, response, *args, **kwargs):
email = details['email']
try:
UserState.objects.get(
email=email
)
except UserState.DoesNotExist:
raise UserStateDoesNotExistException(backend)

exceptions.py

from social_core.exceptions import AuthException
class UserStateDoesNotExistException(AuthException):
def __str__(self):
return "You must be an administrator, staff member or a student to sign in. Please contact the school for more assistance."

感谢您的所有建议!

最新更新