因此我添加了一个一对一字段来扩展 Django auth 用户模型:
class Employee(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
division = models.ForeignKey(Division, on_delete=models.CASCADE)
我想要实现的是每个员工都有权更改其他员工对象,但仅限于他们所属同一部门的员工对象。
我创建了一个“员工”权限组,有权添加/更改/删除用户和员工对象。
现在,每个员工都对所有员工对象和所有用户对象拥有“可以更改”权限。
我设法在 OneToOneField 上过滤 django 管理更改列表,因此每个员工只能在更改列表中看到自己部门的员工。
问题是,如果他们手动输入用于更改另一个部门的用户的 URL,他们就能够更改/删除该用户。同样,他们甚至可以更改/删除 super 用户(用户 1)。导航至:
http://localhost:8000/admin/auth/user/1/change/
就可以了。
我解决这个问题的想法是覆盖身份验证用户更改方法,添加“部门或 super 用户”检查,但这似乎很hacky。我更愿意根据划分来限制对更改 URL 的访问,但我还没有找到实现此目的的方法。
感谢您的建议!
最佳答案
您可以使用UserPassesTestMixin
在基于类的 View 中强制当前用户针对她/他尝试更改的员工部门进行测试。
假设以下示例的 change
方法是 POST
方法:
from django.contrib.auth.mixins import UserPassesTestMixin
class MyView(UserPassesTestMixin, View):
def test_func(self):
ch_user_division = Employee.objects.filter(
pk=self.request.POST.get('user_id')
).values('division')
return self.request.user.division == ch_user_division
现在,基于类的 MyView
检查用户是否与要更改的用户位于同一部门。
有关如何限制用户访问的更多信息:https://docs.djangoproject.com/en/1.11/topics/auth/default/#limiting-access-to-logged-in-users-that-pass-a-test
出于评论遗留原因留下以下内容:
您可以使用ForeignKey.limit_choices_to
关于模型定义的参数,其中:
Sets a limit to the available choices for this field when this field is rendered using a
ModelForm
or theadmin
.
尝试以下操作:
class Employee(models.Model):
user = models.OneToOneField(
User,
on_delete=models.CASCADE,
limit_choices_to={'division': division}
)
division = models.ForeignKey(Division, on_delete=models.CASCADE)
关于python - Django:基于一对一字段限制用户 "can change/delete"权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45141564/