我知道这个问题已在其他主题中提出/解决,例如this。但是,出于某种原因,建议的解决方案对我不起作用。
我创建了一个Django应用程序来管理我们实验室的菌株。我的目标是只允许在菌株数据库或超级用户中创建条目的用户更改所述条目。
我在models.py中有以下模型:
class strain (models.Model):
name = models.CharField("Name", max_length = 150, blank=False)
[...more fields here...]
user = models.ForeignKey(User)
def __unicode__(self):
return str(self.id)
以下admin.py:
class StrainAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'mating_type', 'parental_strain', 'user_id')
list_display_links = ('id', )
search_fields = ('id', 'name')
list_per_page = 25
list_filter = ('user', )
def get_form(self, request, *args, **kwargs):
form = super(StrainAdmin, self).get_form(request, *args, **kwargs)
form.base_fields['user'].initial = request.user
return form
def dispatch(self, request, *args, **kwargs):
handler = super(StrainAdmin, self).dispatch(request, *args, **kwargs)
if self.object.user_id != request.user:
return HttpResponseForbidden("Can't touch this.")
handler
从我在Stack Overflow上看到的内容(见上文)和其他地方,我认为实现目标的最佳方法是扩展调度处理程序:
def dispatch(self, request, *args, **kwargs):
handler = super(StrainAdmin, self).dispatch(request, *args, **kwargs)
if self.object.user_id != request.user:
return HttpResponseForbidden("Can't touch this.")
handler
但是,此解决方案似乎并没有做任何事情:用户仍然可以更改其记录和其他用户创建的记录。
我正在使用Django 1.9。什么是解决这个问题的最佳方法?
提前谢谢。
尼古拉
答案 0 :(得分:1)
你对基于类的观点感到困惑; ModelAdmin不使用dispatch
方法;
在管理员中,最好的办法是覆盖has_change_permission
并检查obj.user_id
答案 1 :(得分:0)
我已经能够解决上面提出的问题,正如@ daniel-rosman所建议的那样
def has_change_permission(self, request, obj=None):
if obj is not None:
if request.user.is_superuser:
return True
else:
if obj.user != request.user:
return False
else:
return True
这是因为如果用户试图访问另一个用户的记录,他/她将获得403 Forbidden页面。但是,实现此解决方案将阻止访问/ {灰色显示strain
的列表视图(即显示模型记录的表)。对于超级用户也是如此!这有些出乎意料的后果。
另外,我想知道是否可能有另一种方法允许用户查看记录但不改变它,除非他/她创建它。如果记录的用户与创建记录的用户不同,那么可能不是那么优雅的方法可以隐藏/change/
视图中的“保存”按钮。也许通过覆盖change_view
。但是,从change_view
中获取对象(即应变)的属性似乎是不可能的。