django中ModelForm解决多表单组合显示问题
一、多表单组合显示问题
在项目中用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)]