一、多表单组合显示问题

在项目中用ModelForm生成页面时

当有多表单组合显示时,会显示全部的关联表单数据。

 

而在实际项目中可能会出现只想让用户选择部分数据,这时候这样的显示就有问题。

二、问题解决方案

views.py

实例化Form对象时注意把当前登录用户对象传到Form中

class Add_Edit_ConsultRecord(View):
    def get(self, request, edit_id=None):
        if edit_id is None:
            # 新增get,# 实例化一个包含当前销售的跟进记录
            consult_obj = ConsultRecord(consultant=request.user)
        else:
            # 编辑get,
            consult_obj = ConsultRecord.objects.filter(pk=edit_id).first()
        form_obj = ConsultRecordForm(instance=consult_obj)
        return render(request, "consultrecord_change.html", {'form_obj': form_obj, 'edit_id': edit_id})

    def post(self, request, edit_id=None):
        if edit_id is None:
            # 新增post,# 实例化一个包含当前销售的跟进记录
            consult_obj = ConsultRecord(consultant=request.user)
        else:
            # 编辑post,
            consult_obj = ConsultRecord.objects.filter(pk=edit_id).first()
        form_obj = ConsultRecordForm(request.POST, instance=consult_obj)
        if form_obj.is_valid():
            # 通过数据校验
            form_obj.save()
            return redirect(reverse("consult_records", args=('0')))

 

相比较BaseForm,BaseModelForm多了instance参数,它等价于Model模型的一个实例
ModelForm中传递了initial也一样可以生效,同时还会设置到Model中

 form.py

class BootForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)  
        for field in self.fields.values():
            field.widget.attrs.update({'class': 'form-control'})
            field.error_messages = {"required": "该字段不能为空"}
# 跟进记录Form
class ConsultRecordForm(BootForm):
    class Meta:
        model = ConsultRecord
        fields = "__all__"

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 清除delete_status字段的样式
        self.fields['delete_status'].widget.attrs.pop('class')

        # 当前登录的用户(销售)对象
        # print(self.instance.consultant)
        # self.fields['customer'].choices = [('', '---------'), (2, '239966930011'),]
        """
        相比较BaseForm,BaseModelForm多了instance参数,它等价于Model模型的一个实例
         ModelForm中传递了initial也一样可以生效,同时还会设置到Model中
        # self.instance.consultant.customers.all()
        先得到当前登录对象,再通过销售对象反向查询客户对象
        通过列表生成式生成choices结构[('', '---------'),(1,'2399669300'), (2, '239966930011'),]
        """
        # 限制添加和编辑时多选框显示的所咨询客户只能是自己跟进的,
        customer_choices = [(i.pk, str(i)) for i in self.instance.consultant.customers.all()]
        customer_choices.insert(0, ('', '---------'))# insert 列表插入数据,默认选择框
        # 将原本的客户对像替换掉
        self.fields['customer'].choices = customer_choices
        # 限制添加和编辑时多选框显示的跟进人只能是当前登录人,
        # print(list(self.fields['customer'].widget.choices))
        self.fields['consultant'].choices = [(self.instance.consultant.pk, self.instance.consultant.username)]