在django 3.0中设置对象级权限

时间:2015-03-10 21:43:45

标签: python django django-cms

假设我有一个带有cms占位符的模型:

class Content(models.Model):
    placeholder = PlaceholderField('placeholder')
    published = models.BooleanField(default=False)

我希望占位符前端可编辑,具体取决于它是否已发布。即我希望它可以通过前端进行编辑,只要它未发布,但是一旦占位符发布,我希望它是不可编辑的。

我在admin.py中试过以下内容:

class ContentAdmin(admin.ModelAdmin):
    def has_change_permission(self, request, obj=None):
        if obj.published:
            return False
        else:
            return True

admin.site.register(Content, ContentAdmin)

但似乎没有任何影响。我也尝试过使用自定义后端。

def has_perm(self, user_obj, perm, obj=None):
        if isinstance(obj, Content):
            if obj.published:
                return False
            else:    
                return True
        return False

也没有效果。我没有收到任何错误,但占位符继续呈现为可编辑。我究竟做错了什么?我目前正在使用管理员进行测试,我只是不能拒绝超级用户权限吗?

使用django 1.6.1和django-cms 3.0.12

谢谢!

1 个答案:

答案 0 :(得分:0)

您可以覆盖get_readonly_fields中的ContentAdmin以检查您的内容对象是否已发布,并将placeholder设置为只读。

def get_readonly_fields(self, request, obj=None):
    if obj and obj.published:
        return ('placeholder')
    return ()

<强>更新

管理员readonly仅影响Django管理员。

您可以override the model's save method并检查placeholder是否是更新字段之一。如果是,并且Content实例已发布,则它将不执行任何操作。

def save(self, force_insert=False, force_update=False, using=None,
             update_fields=None):
    if self.published and 'placeholder' in update_fields:
        return
    super(Content, self).save(force_insert=force_insert,
        force_update=force_update, using=using, update_fields=update_fields)

这将忽略向前端placeholder字段提供的任何新值。

在前端,只需进行此更改即可保留原样。 (该字段仍将显示为可编辑,但编辑没有区别。)

否则,您可以修改render_placeholder(我假设是自定义标记)来检查Content对象的已发布字段,并将您呈现的输入设置为disabled

它看起来像这样

{% if obj.published %}
    Placeholder: <input disabled type="text" name="placeholder">
{% else %}
    Placeholder <input type="text" name="placeholder">
{% endif %}