我正在使用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
)
当用户首次尝试登录时,我希望能够检查该数据库以查看它们是否符合任何条件。 目前,为用户使用post_save信号(我也尝试使用pre_save但没有骰子)以某种方式停止创建Django用户对象(如果它们不在UserState表上)。
这有可能吗?我目前停止创建用户实例的唯一方法是在post_save期间引发异常,这当然不是理想的。
对于广泛的问题感到抱歉,如果您需要任何具体信息,请告诉我们。提前谢谢!
答案 0 :(得分:0)
我认为最好的选择是使用user_pass_test函数或使用UserPassTestMixin作为类基本视图。
答案 1 :(得分:0)
结束为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."
感谢所有的建议!