(Django) 如何创建引用两个模型的验证混合?
(Django) How to create a verification mixin that references two models?
我有两个 classes Organisation 和 Staff 除了 Userclass。我想创建一个名为“UserIsAdminMixin”的 mixin,用于检查登录的用户在特定组织中是否具有角色“admin”。
classes(简体)
class Organisation(models.Model):
name = models.CharField(max_length=50)
class Staff(models.Model):
class Role(models.TextChoices):
ADMIN = 'ADMIN', "Admin"
STAFF = 'STAFF', "Staff"
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, db_index=True, related_name="staff_profiles", on_delete=models.SET_NULL)
organisation = models.ForeignKey('organisations.Organisation', db_index=True, related_name="staff", on_delete=models.CASCADE)
role = models.CharField(max_length=10, choices=Role.choices, default=Role.STAFF)
然后我现在为我的 UserIsAdmin mixin 准备了这个:
class UserIsAdminMixin:
def dispatch(self, request, *args, **kwargs):
if self.request.user.staff_profiles.filter(organisation=self.get_object(), role=Staff.Role.ADMIN):
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
这对这个视图非常有用:
organisations.views.py(URL:组织/)
class OrganisationDetail(LoginRequiredMixin, UserIsAdminMixin, generic.DetailView):
model = Organisation
template_name= "organisations/detail.html"
login_url = "login"
但我也希望它也适用于此视图,在这种情况下,它显然不是 self.get_object() returns 一个 Staff 对象,当它期待一个 Organization对象:
staff.views.py (URL: 组织//staff/)
class StaffDetail(LoginRequiredMixin, UserIsAdminMixin, generic.DetailView):
model = Staff
template_name="staff/detail.html"
login_url = "login"
我能够对 mixin 进行更改以使其在第二种情况下工作,但不是第一种情况:
class UserIsAdminMixin:
def dispatch(self, request, *args, **kwargs):
if self.request.user.staff_profiles.filter(organisation__pk=self.kwargs['pk_alt']), role=Staff.Role.ADMIN):
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
那么我有什么办法可以更改 mixin,使其适用于 both Organisation 和 Staff 模型来检查用户是否是给定组织的具有管理员角色的员工?
如有任何帮助,我们将不胜感激!
非常感谢,
GoingRoundInCircles
嗯,一个可能的解决方案是在你的两个视图中都有一个 get_organisation_id()
方法。
你的混入:
class UserIsAdminMixin:
def dispatch(self, request, *args, **kwargs):
organisation_id = self.get_organisation_id()
if self.request.user.staff_profiles.filter(organisation_pk=organisation_id, role=Staff.Role.ADMIN):
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
员工详情:
class StaffDetail(LoginRequiredMixin, UserIsAdminMixin, generic.DetailView):
model = Staff
template_name="staff/detail.html"
login_url = "login"
def get_organisation_id(self):
return self.kwargs.get('pk_alt')
组织详细信息:
class OrganisationDetail(LoginRequiredMixin, UserIsAdminMixin, generic.DetailView):
model = Organisation
template_name= "organisations/detail.html"
login_url = "login"
def get_organisation_id(self):
return self.get_object().id
我有两个 classes Organisation 和 Staff 除了 Userclass。我想创建一个名为“UserIsAdminMixin”的 mixin,用于检查登录的用户在特定组织中是否具有角色“admin”。
classes(简体)
class Organisation(models.Model):
name = models.CharField(max_length=50)
class Staff(models.Model):
class Role(models.TextChoices):
ADMIN = 'ADMIN', "Admin"
STAFF = 'STAFF', "Staff"
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, db_index=True, related_name="staff_profiles", on_delete=models.SET_NULL)
organisation = models.ForeignKey('organisations.Organisation', db_index=True, related_name="staff", on_delete=models.CASCADE)
role = models.CharField(max_length=10, choices=Role.choices, default=Role.STAFF)
然后我现在为我的 UserIsAdmin mixin 准备了这个:
class UserIsAdminMixin:
def dispatch(self, request, *args, **kwargs):
if self.request.user.staff_profiles.filter(organisation=self.get_object(), role=Staff.Role.ADMIN):
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
这对这个视图非常有用:
organisations.views.py(URL:组织/
class OrganisationDetail(LoginRequiredMixin, UserIsAdminMixin, generic.DetailView):
model = Organisation
template_name= "organisations/detail.html"
login_url = "login"
但我也希望它也适用于此视图,在这种情况下,它显然不是 self.get_object() returns 一个 Staff 对象,当它期待一个 Organization对象:
staff.views.py (URL: 组织/
class StaffDetail(LoginRequiredMixin, UserIsAdminMixin, generic.DetailView):
model = Staff
template_name="staff/detail.html"
login_url = "login"
我能够对 mixin 进行更改以使其在第二种情况下工作,但不是第一种情况:
class UserIsAdminMixin:
def dispatch(self, request, *args, **kwargs):
if self.request.user.staff_profiles.filter(organisation__pk=self.kwargs['pk_alt']), role=Staff.Role.ADMIN):
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
那么我有什么办法可以更改 mixin,使其适用于 both Organisation 和 Staff 模型来检查用户是否是给定组织的具有管理员角色的员工?
如有任何帮助,我们将不胜感激!
非常感谢,
GoingRoundInCircles
嗯,一个可能的解决方案是在你的两个视图中都有一个 get_organisation_id()
方法。
你的混入:
class UserIsAdminMixin:
def dispatch(self, request, *args, **kwargs):
organisation_id = self.get_organisation_id()
if self.request.user.staff_profiles.filter(organisation_pk=organisation_id, role=Staff.Role.ADMIN):
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
员工详情:
class StaffDetail(LoginRequiredMixin, UserIsAdminMixin, generic.DetailView):
model = Staff
template_name="staff/detail.html"
login_url = "login"
def get_organisation_id(self):
return self.kwargs.get('pk_alt')
组织详细信息:
class OrganisationDetail(LoginRequiredMixin, UserIsAdminMixin, generic.DetailView):
model = Organisation
template_name= "organisations/detail.html"
login_url = "login"
def get_organisation_id(self):
return self.get_object().id