Django表单保存时抛出expected string or bytes-like object错误排查
问题分析与解决办法
嘿,我一眼就揪出问题所在啦!
你遇到的「expected string or bytes-like object」错误,根源完全在你的clean_due_date方法上——这个方法是专门负责清理due_date单个字段的,但你最后返回的是一个元组(due_date, approved_status),而Django期望这个方法返回的是due_date字段的单个有效值(比如一个datetime.date对象)。
看你提供的局部变量信息,due_date的值是(datetime.date(2018, 6, 13),),已经变成了元组!当视图里把这个元组赋值给key_inst.due_back(数据库的日期字段)时,Django根本没法把元组转换成日期格式,自然就抛出错误了。
解决方案:修改表单的字段清理方法
把clean_due_date方法里多余的返回值去掉,只返回验证后的due_date就好——毕竟这个方法的职责就是验证和清理due_date字段,request_status的处理完全可以放在视图里(你已经在视图里正确获取它了)。
修改后的forms.py代码:
class UpdateKeyRequestForm(forms.Form): APPROVE_CHOICES = [ ('d', 'Deny this key request'), ('a', 'Approve this key request') ] request_status = forms.CharField(label='Please select to accept or deny this request.',widget=forms.Select(choices=APPROVE_CHOICES)) due_date = forms.DateField(help_text='Enter a date (YYYY-MM-DD) between now and 4 weeks (default 3). ') def clean_due_date(self): due_date = self.cleaned_data['due_date'] # 移除对request_status的获取,这个字段的逻辑交给视图处理即可 # Check date is not in past. if due_date < datetime.date.today(): raise ValidationError(_('Invalid date - renewal in past')) if due_date > datetime.date.today() + datetime.timedelta(weeks=4): raise ValidationError(_('Invalid date - renewal more than 4 weeks ahead')) # 只返回验证后的due_date return due_date
为什么之前相同逻辑正常?
大概率是你之前的clean_due_date方法只返回了due_date单个值,这次不小心把approved_status也加到返回值里了,才导致的问题。
这样修改后,form.cleaned_data['due_date']就会是正常的datetime.date对象,赋值给key_inst.due_back后就能正常保存啦!
内容的提问来源于stack exchange,提问作者UWGOOSE
相关产品推荐
相关产品推荐

