首页 > 解决方案 > Django 组表单上的自定义权限

问题描述

我为我的 Post 模型添加了一些自定义权限。

我还创建了一个表单来添加/编辑仅具有此自定义权限的组:

class GroupFornm(forms.ModelForm):
    permissions = forms.MultipleChoiceField(choices=Post._meta.permissions)

    class Meta:
        model = Group
        fields = '__all__'

它之所以有效,是因为我只能看到并选择我的自定义权限,但是当我尝试保存表单时出现错误:

基数为 10 的 int() 的无效文字:'can_view'

我究竟做错了什么?似乎此表单字段等待 (int, str) 对,但文档说通常, (str, str) 应该可以工作。

编辑

Post._meta.permissions:

(('can_view', 'Can see tickets'), ('can_edit', 'Can edit tickets'), ('can_delete', 'Can delete tickets'), ('can_create', 'Can add new tickets'))

标签: pythondjango

解决方案


问题与表单本身并不真正相关,而是您需要以某种方式将它们permissions转换为Permission应该存储在Group实例中的对象(这ModelForm是管理的对象)。

我认为显示选项不是问题。但是,如果用户稍后使用选项(如)执行POST请求,can_write那么问题是Form应该如何将这些转换为Permission对象(或对象的主键Permission)。

在这种情况下,您需要强制对象的权限名称Permission或对象id的名称Permission。例如,我们可以使用 aTypedMultipleChoiceField和强制:

def get_permission_from_name(name):
    return Permission.objects.get(name=name)

class GroupFornm(forms.ModelForm):
    permissions = forms.TypedMultipleChoiceField(
        choices=Post._meta.permissions,
        coerce=get_permission_from_name,
    )

    class Meta:
        model = Group
        fields = '__all__'

请注意,上面的实现并不是一个非常有效的实现,因为它需要对每个发送的值进行查询。此外,如果不存在具有该名称的权限,则会引发错误。

如果您想动态构建Permissions(以防这些尚未构建),那么您可以将函数更改为:

def get_permission_from_name(name):
    return Permission.objects.get_or_create(
        name=name,
        defaults={
            'content_type': ContentType.objects.get_for_model(Post),
            'codename': name
        }
    )

推荐阅读