如何限制记录的编辑记录Django的所有者?

时间:2016-01-31 18:12:43

标签: python django

我知道这个问题已在其他主题中提出/解决,例如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。什么是解决这个问题的最佳方法?

提前谢谢。

尼古拉

2 个答案:

答案 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中获取对象(即应变)的属性似乎是不可能的。

相关问题