【问题标题】:Django permissions in checkbox form复选框形式的 Django 权限
【发布时间】:2025-12-01 18:05:02
【问题描述】:

我有一个模板,我可以在其中编辑模型用户的所有基本字段。

现在我想要一个表单,其中将以类似复选框的样式显示所有可用权限。应该已经检查了已经分配给用户的那些。

我有一个form.py,有一个用于编辑用户的表单,但还没有完成权限表单。

class UserSettingsForm(forms.ModelForm):
class Meta:
    model = User
    fields = (
        'username',
        'first_name',
        'last_name',
        'email',
        'urnik',
        'ure_na_teden',
        'rfid',
        'oddelek',
        'status_zaposleni',
    )

def __init__(self, *args, **kwargs):
    self.request = kwargs.pop("request")
    super(UserSettingsForm, self).__init__(*args, **kwargs)
    instance = getattr(self, 'instance', None)
    self.fields['username'].disabled = True

def save(self):
    user = super(UserSettingsForm, self).save()
    return user

class UserPermissonsForm(forms.ModelForm):
class Meta:
    model = Permission
    fields = (
        'name',
        'content_type',
        'codename',
    )

还有一个views.py:

@login_required
def uporabnik_uredi(request, username=None):
user = get_object_or_404(User, username=username)
uporabnik_form = UserSettingsForm(request.POST or None,request=request, instance=user)
permissions = [(p.id, p.name) for p in Permission.objects.filter(user=user)]
data = {
    'uporabnik' : user,
    'form' : uporabnik_form,
    'from': request.GET.get('from', None),
    'permissions' : permissions,
}

if request.POST:
    if uporabnik_form.is_valid():
        user = uporabnik_form.save()
        next = request.GET.get('next', None)
        return redirect(next)
return render(request, "sifranti/uporabniki/uredi.html", data)

还有一个模板,只是为了查看当前给用户分配了哪些权限:

<div class="">
    {% for id, name in permissions %}
        {{ id }} - {{ name }} <br>
    {% endfor %}
</div>

【问题讨论】:

    标签: python django django-models django-forms django-views


    【解决方案1】:

    我就是这样做的,但我使用的是 MultipleSelect,我想你可以将其中的一些应用于复选框。

    class EditUserForm(forms.ModelForm):
    
    def __init__(self, *args, **kwargs):
        super(EditUserForm, self).__init__(*args, **kwargs)
    
        def get_label(obj):
            permission_name = str(obj).split('|')[2].strip()
            model_name = permission_name.split(' ')[2].strip()
            return '%s | %s' % (model_name.title(), permission_name)
    
        User = get_user_model()
        content_type = ContentType.objects.get_for_model(User)
        self.fields['user_permissions'].queryset = Permission.objects.filter(content_type=content_type)
        self.fields['user_permissions'].widget.attrs.update({'class': 'permission-select'})
        self.fields['user_permissions'].help_text = None
        self.fields['user_permissions'].label = "Label"
        self.fields['user_permissions'].label_from_instance = get_label
    
    def save(self, commit=True):
        user_instance = super(EditUserForm, self).save(commit)
        user_instance.save()
        user_instance.user_permissions.set(self.cleaned_data.get('user_permissions'))
        return user_instance
    
    class Meta:
        model = get_user_model()
        fields = ['email', 'first_name', 'last_name', 'user_permissions']
    
        widgets = {
            'email': forms.EmailInput(attrs={'class': 'form-control', 'style': 'width: 300px;'}),
            'first_name': forms.TextInput(attrs={'class': 'form-control', 'style': 'width: 300px;'}),
            'last_name': forms.TextInput(attrs={'class': 'form-control', 'style': 'width: 300px;'}),
            'user_permissions': forms.SelectMultiple(attrs={'style': 'width: 350px; height: 200px;'})
        }
    

    希望这有帮助,祝你好运!

    【讨论】: