(Django) 如何创建引用两个模型的验证混合?

(Django) How to create a verification mixin that references two models?

我有两个 classes OrganisationStaff 除了 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 OrganisationStaff 模型来检查用户是否是给定组织的具有管理员角色的员工?

如有任何帮助,我们将不胜感激!

非常感谢,

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