默认值:

def multi_edit(request):
    form_class = formset_factory(MultiPermissionForm,extra=0) ##extra=0不额外生成
    if request.method == 'GET':
        formset = form_class(initial=[{'title':'xi','url':'xxx'}])  ####initial参数列表里放字典
        return render(request, 'multi_edit.html', locals())
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <style>

    </style>
</head>
<body>
<div class="container">
    <div class="col-md-offset-2">
        <form method="post">
        {% csrf_token %}
        {{ formset.management_form }}
            <table border="1">
                <thead border="2">
                <tr>
                    <td>title</td>
                    <td>url</td>
                    <td>name</td>
                    <td>menu_id</td>
                    <td>pid_id</td>
                </tr>
                </thead>
                <tbody>
                {% for form in formset %}
                    <tr>
                        {% for field in form %}
                            <td>{{ field }}<span style="color: red;float: right">{{ field.errors.0 }}</span></td>
                        {% endfor %}
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        <input type="submit" value="提交">
        </form>
    </div>
</div>
</body>
</html>

更新数据:

  form不能和添加的form一样 ===》 多一个id字段 用于判断更新哪条数据==》在前端渲染时隐藏id字段(不能让用户选择) forms.HiddenInput

class UpdateMultiPermissionForm(forms.Form):
    id = forms.IntegerField(
        widget=forms.HiddenInput(attrs={'class': 'form-control'})   ########新增加id字段 并且设置隐藏
    )
    title = forms.CharField(
        widget=forms.TextInput(attrs={'class':'form-control'})
    )
    url = forms.CharField(
        widget=forms.TextInput(attrs={'class': 'form-control'})
    )

    name = forms.CharField(
        widget=forms.TextInput(attrs={'class':'form-control'})
    )
    menu_id = forms.ChoiceField(
        choices=[(None,'------------')],
        widget=forms.Select(attrs={'class': 'form-control'}),
        required = False
    )
    pid_id = forms.ChoiceField(
        choices=[(None, '-----------')],
        widget=forms.Select(attrs={'class': 'form-control'}),
        required=False
    )
    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.fields['menu_id'].choices += Menu.objects.values_list('id','title')
        self.fields['pid_id'].choices += Permission.objects.filter(pid__isnull=True).exclude(
            menu__isnull = True
        ).values_list('id','title')
    {% for field in form %}                 #########第一个的话就不生成td 页面不会错开
       {% if forloop.first %}
          {{ field }}
       {% else %}
    <td>{{ field }}<span style="color: red;float: right">{{ field.errors.0 }}</span></td>
       {% endif %}
    {% endfor %}

 因为了id字段 所以后端传值要 加上id,然后用id来数据更新

  formset = form_class(initial=[{'id':1,'title':'xi','url':'xxx'}]) ##models.Permission,objects.all().values(xxx,xx,xx)

def multi_edit(request):
    form_class = formset_factory(UpdateMultiPermissionForm,extra=0)##################
    if request.method == 'GET':
        formset = form_class(initial=Permission.objects.all().values('id','title','url','name','menu_id','pid_id'))
        return render(request, 'multi_edit.html', locals())
    formset = form_class(data=request.POST)
    if formset.is_valid():
        post_row_list = formset.cleaned_data
        for i in range(0, formset.total_form_count()):
            try:
                Permission.objects.filter(id=post_row_list[i].get('id')).update(**post_row_list[i])
            except Exception as e:
                pass
    else:
        return render(request, 'multi_edit.html', locals())
    return render(request, 'multi_edit.html', locals())
 

  

01-23 14:45