背景
我正在为一个度假出租网站开发一个django应用程序。它将有两种类型的用户,出租人和物业经理。
我希望物业经理能够在Django管理处管理他们的租赁物业。然而,他们应该只能管理自己的财产。
我知道默认的django管理不支持这个。我想知道添加这个功能会有多少麻烦,如果它可行的话,处理它的最佳方法是什么。
目标
理想情况下,我想象它是这样工作的:auth
已经允许这样的权限:
假期租金可以增加租金
假期租金可以更改租金
假期租金可以删除租金
我想把这个改成:
假期租金可以增加任何租金
假期租金可以更改任何租金
假期租金可以删除任何租金
度假租赁可以增加自己的租金
度假出租可以更改自己的租金
假期租金可以删除自己的租金
可能的解决方案
框架如何决定租赁(或其他)是否属于用户?我想它会检查vacation.Rental
类,看看它是否有一个ForeignKey
toauth.User
(可能有一些特定的名称,比如“owner”)。
创建新的vacation.Rental
时,ForeignKey
字段的值将被强制为当前用户的ID。表单上不会显示ForeignKey
字段。
在列出租金时,只显示与当前用户匹配的租金。
在更改租金时,只显示与当前用户匹配的租金。ForeignKey
字段不会显示在表单上。
当然,这应该能够适用于任何具有适当ForeignKey
字段的模型,而不仅仅是我们的ForeignKey
模型。
到目前为止,这听起来可行吗,还是我应该朝着不同的方向走?
难题
现在,这是个棘手的问题,我不知道该如何处理。假设一个ForeignKey
可以有很多“rentalphotos”,一个vacation.Rental
可以有一个Rental
到RentalPhoto
。用户应该能够在自己的租赁中添加照片。但是,这些照片没有用户,因此无法直接查明照片的所有者。
是否可以通过框架中的一些技巧来解决这个问题,遵循ForeignKey
s,直到发现一个对象带有Rental
to-user?或者,我应该采取简单的方法,将自己的ForeignKey
给予相应的ForeignKey
吗?第二种方法将邀请不必要的冗余,第一种方法可能需要不必要的处理开销…
如果我完全误入歧途,请毫不犹豫地指出正确的方向。事先谢谢你的帮助。
最佳答案
我只需为每个模型添加一个方法,然后由模型决定它是否属于该用户。在大多数情况下,is_owned_by(user)
可以是基本模型类中的通用函数,在特殊情况下可以对其进行调整。例如
class RentalPhoto(BaseModel):
def is_owned_by(self, user):
return self.rental.is_owned_by(user)
这是足够通用的,并且明确地说,您将完全控制事物的行为。
要添加新权限,可以将其添加到模型中,例如
class Rental(models.Model):
# ...
class Meta:
permissions = (
("can_edit_any", "Can edit any rentals"),
)
我认为,不应该为
is_owned_by
和any
添加两个权限,而应该只添加own
权限,因此每个对象都已经有了own
可以作为用户来处理,只能编辑其对象,如果用户有权限,则可以编辑任何对象,而不仅仅是允许他编辑所有对象。使用此功能,我们可以通过添加自定义后端来扩展身份验证,例如
class PerObjectBackend(ModelBackend):
def has_perm(self, user_obj, perm, obj=None):
allowed = ModelBackend.has_perm(self, user_obj, perm)
if perm.find('any') >=0 :
return allowed
if perm.find('edit') >=0 or perm.find('delete') >=0:
if obj is None:
raise Exception("Perm '%s' needs an object"%perm)
if not obj.is_owned_by(user_obj):
return False
return allowed
这是一个非常快速的实现,实际上,您可以扩展权限对象以检查它是否需要和对象,例如
can_edit
而不是执行粗字符串搜索,但如果您有标准名称,这也应该有效。关于python - 向django admin添加每个对象的权限,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3674463/