You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django的forms.py中基于Permission模型创建权限布尔字段表单?

动态生成权限表单的实现方案

要匹配模板里的动态权限复选框,我们需要在表单中动态生成对应字段——因为app名称(比如ticket、users)是从Permission模型中来的,无法提前硬编码。具体实现步骤如下:

1. 编写动态表单类

在forms.py中创建表单,通过重写__init__方法,根据Permission模型中的app动态添加四个BooleanField:

from django import forms
from .models import Permission

class PermissionForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 获取所有唯一的app名称,避免重复处理同一个app
        app_list = Permission.objects.values_list('app', flat=True).distinct()
        
        for app in app_list:
            # 为每个app添加四个权限字段,字段名和模板中的name属性严格对应
            self.fields[f"{app}_add"] = forms.BooleanField(
                label=f"{app} - 添加",
                required=False,
                widget=forms.CheckboxInput(attrs={'class': 'form-check-input', 'id': f"{app}ManagementWrite"})
            )
            self.fields[f"{app}_read"] = forms.BooleanField(
                label=f"{app} - 读取",
                required=False,
                widget=forms.CheckboxInput(attrs={'class': 'form-check-input', 'id': f"{app}ManagementRead"})
            )
            self.fields[f"{app}_update"] = forms.BooleanField(
                label=f"{app} - 更新",
                required=False,
                widget=forms.CheckboxInput(attrs={'class': 'form-check-input', 'id': f"{app}ManagementUpdate"})
            )
            self.fields[f"{app}_delete"] = forms.BooleanField(
                label=f"{app} - 删除",
                required=False,
                widget=forms.CheckboxInput(attrs={'class': 'form-check-input', 'id': f"{app}ManagementDelete"})
            )
            
            # 编辑场景下设置初始值(示例:从Permission模型读取已有权限)
            if self.initial:
                perm_obj = Permission.objects.filter(app=app).first()
                if perm_obj:
                    self.fields[f"{app}_add"].initial = perm_obj.add
                    self.fields[f"{app}_read"].initial = perm_obj.read
                    self.fields[f"{app}_update"].initial = perm_obj.update
                    self.fields[f"{app}_delete"].initial = perm_obj.delete

2. 视图中使用表单

在视图里,先获取Permission模型的对象列表传递给模板(和现有模板逻辑一致),同时实例化表单处理请求:

from django.shortcuts import render
from .forms import PermissionForm
from .models import Permission

def permission_management(request):
    permissions = Permission.objects.all()
    if request.method == 'POST':
        form = PermissionForm(request.POST)
        if form.is_valid():
            # 处理表单提交的权限数据
            for app in Permission.objects.values_list('app', flat=True).distinct():
                # 提取每个app的四个权限值
                add_perm = form.cleaned_data.get(f"{app}_add", False)
                read_perm = form.cleaned_data.get(f"{app}_read", False)
                update_perm = form.cleaned_data.get(f"{app}_update", False)
                delete_perm = form.cleaned_data.get(f"{app}_delete", False)
                # 更新Permission模型中的权限记录
                Permission.objects.filter(app=app).update(
                    add=add_perm,
                    read=read_perm,
                    update=update_perm,
                    delete=delete_perm
                )
            # 这里可以添加跳转或提示信息
    else:
        # 初始化表单初始值(编辑场景)
        initial_data = {}
        for perm in permissions:
            initial_data[f"{perm.app}_add"] = perm.add
            initial_data[f"{perm.app}_read"] = perm.read
            initial_data[f"{perm.app}_update"] = perm.update
            initial_data[f"{perm.app}_delete"] = perm.delete
        form = PermissionForm(initial=initial_data)
    
    return render(request, 'your_template.html', {'permissions': permissions, 'form': form})

3. 模板适配(可选优化)

如果想减少模板硬编码,可以把手动写的input标签替换为Django表单的渲染方式,自动关联字段属性:

{% for item in permissions %}
<tr>
  <td class="text-nowrap">{{ item.app }}</td>
  <td>
    <div class="d-flex">
      <div class="form-check me-3 me-lg-5 mb-0 mt-0">
        {{ form[item.app+'_add'] }}
        <label class="form-check-label" for="{{ item.app }}ManagementWrite">add</label>
      </div>
      <div class="form-check me-3 me-lg-5 mb-0 mt-0">
        {{ form[item.app+'_read'] }}
        <label class="form-check-label" for="{{ item.app }}ManagementRead">read</label>
      </div>
      <div class="form-check me-3 me-lg-5 mb-0 mt-0">
        {{ form[item.app+'_update'] }}
        <label class="form-check-label" for="{{ item.app }}ManagementUpdate">update</label>
      </div>
      <div class="form-check mb-0 mt-0">
        {{ form[item.app+'_delete'] }}
        <label class="form-check-label" for="{{ item.app }}ManagementDelete">delete</label>
      </div>
    </div>
  </td>
</tr>
{% endfor %}

这样表单和模板就能完全对应,既保留了原有UI样式,又能利用Django表单的验证、初始化功能。

内容的提问来源于stack exchange,提问作者Alireza javanpour

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 13:26:04