我正在使用模型表单,我试图绕过某个特定字段的验证。
我已经确定我需要使用clean()方法绕过该字段。但是当我打印出已清理的数据时,assigned_subnets字段不在字典中,它就丢失了
动作: 我在forms.py中手动创建分配的子网字段。然后使用jquery我改变该表单字段并添加更多选择选项到它发布所有选项。发布的附加值不是原始字段选择的一部分,因此是错误。
打印输出:
{'site_data': None, 'switches': None, 'hostname': 'STR--RTR-01', 'template': <ConfigTemplates: STR-RTR-01>, 'model': <DeviceModel: Cisco - 4431>, 'install_date': datetime.date(2016, 5, 26), 'ospf_area': None, 'snmp_data': <SNMPData: XXXX>, 'available_subnets': <QuerySet []>}
forms.py
class DeviceForm(forms.ModelForm):
class Meta:
model = DeviceData
fields = ['site_data', 'switches', 'hostname', 'template', 'model', 'install_date','ospf_area','snmp_data']
def clean(self):
super(DeviceForm, self).clean()
print(self.cleaned_data)
if self.cleaned_data.get('assigned_subnets') in self._errors:
del self._errors['assigned_subnets']
return self.cleaned_data
def __init__(self, *args, **kwargs):
site_id = kwargs.pop('site_id', None)
device_id = kwargs.pop('device_id', None)
self.is_add = kwargs.pop("is_add", False)
super(DeviceForm, self).__init__(*args, **kwargs)
devicesubnet = Subnets.objects.filter(devicesubnets__device_id=device_id)
sitesubnet = Subnets.objects.filter(sitesubnets__site_id=site_id)
common_subnets = list(set(devicesubnet) & set(sitesubnet))
subnet_id_list = []
for s in common_subnets: subnet_id_list.append(s.id)
available_subnet_data = sitesubnet.exclude(id__in=subnet_id_list)
assigned_choices = []
devicesubnet_data = DeviceSubnets.objects.filter(device_id=device_id)
for choice in devicesubnet_data:
assigned_choices.append((choice.subnet.id,choice.subnet.subnet))
self.fields['available_subnets'] = forms.ModelMultipleChoiceField(
label='Available Subnets',
queryset=available_subnet_data,
widget = forms.SelectMultiple(
attrs = {'class': 'form-control', 'size' : '15'}
)
)
self.fields['assigned_subnets'] = forms.MultipleChoiceField(
label='Assigned Subnets',
choices=assigned_choices,
widget = forms.SelectMultiple(
attrs = {'class': 'form-control', 'size' : '15'}
)
)
self.fields['available_subnets'].required = False
self.fields['assigned_subnets'].required = False
self.helper = FormHelper(self)
self.helper.form_id = 'device_form'
self.helper.form_method = 'POST'
...
views.py
class EditDevice(UpdateView):
model = DeviceData
form_class = DeviceForm
template_name = "config/device_form.html"
@method_decorator(user_passes_test(lambda u: u.has_perm('config.edit_device')))
def dispatch(self, *args, **kwargs):
self.site_id = self.kwargs['site_id']
self.site = get_object_or_404(SiteData, pk=self.site_id)
return super(EditDevice, self).dispatch(*args, **kwargs)
def get_success_url(self, **kwargs):
return reverse_lazy("config:device_details", args=(self.site_id,))
def form_valid(self, form):
form.instance.site_data = self.site
assigned_subnets = form.cleaned_data['assigned_subnets']
print(assigned_subnets)
return super(EditDevice, self).form_valid(form)
def get_form_kwargs(self, *args, **kwargs):
kwargs = super().get_form_kwargs()
kwargs['site_id'] = self.site_id
kwargs['device_id'] = self.object.pk
return kwargs
...
修改 我想要做的就像在下面的图像。我有一个可用子网列表和一个选定(已分配)子网列表。 我不认为这个表单小部件存在于Django管理员之外?所以我手动创建了两个字段,并使用jquery将子网从可用移动到已分配。
然后我获得分配的子网并更新数据库。但是当我改变指定的字段时,我得到了错误