Django车辆服务记录添加时Workshop字段类型错误求助
问题:无法为车辆创建ServiceRecord,触发TypeError错误
开发个人车辆在线服务手册项目,涉及Vehicle、Workshop、Filter、ServiceRecord模型,尝试为已添加车辆创建ServiceRecord时失败,报错信息及相关代码如下:
相关代码
forms.py
class ServiceRecordCreateForm(forms.ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) all_workshops = Workshop.objects.exclude(name="Other Workshop") workshop_choices = [(workshop.id, workshop.name) for workshop in all_workshops] workshop_choices.insert(0, (0, 'Other Workshop')) self.fields['workshop'].widget = forms.Select(choices=workshop_choices) self.fields['workshop'].choices = workshop_choices all_filters = Filter.objects.all() filter_choices = [(filter.id, filter.name) for filter in all_filters] self.fields['filters_changed'].widget = forms.CheckboxSelectMultiple() self.fields['filters_changed'].choices = filter_choices def clean_workshop(self): workshop_id = self.cleaned_data.get('workshop') if workshop_id == 0: # 处理"Other Workshop"情况 workshop = Workshop.objects.filter(name="Other Workshop").first() if not workshop: raise forms.ValidationError("Other Workshop is not available.") else: workshop = Workshop.objects.get(id=workshop_id) return workshop class Meta: model = ServiceRecord fields = ['workshop', 'date', 'mileage_at_service', 'filters_changed'] widgets = { 'date': forms.DateInput(attrs={'type': 'date'}), }
views.py
class ServiceRecordCreateView(LoginRequiredMixin, CreateView): model = ServiceRecord form_class = ServiceRecordCreateForm template_name = 'create_service_record.html' def get_success_url(self): vehicle_id = self.kwargs['vehicle_id'] return reverse_lazy('service_record_list', kwargs={'vehicle_id': vehicle_id}) def form_valid(self, form): service_record = form.save(commit=False) service_record.vehicle_id = self.kwargs['vehicle_id'] service_record.save() form.save_m2m() return redirect(self.get_success_url())
错误信息
TypeError at /create_service_record/2/ Field 'id' expected a number but got <Workshop: Worksh1 (ALALALA)>. Request Method: POST Request URL: http://127.0.0.1:8000/create_service_record/2/ Django Version: 4.2.11 Exception Type: TypeError Exception Value: Field 'id' expected a number but got <Workshop: Worksh1 (ALALALA)>. Exception Location: /home/kamil/.local/lib/python3.10/site-packages/django/db/models/fields/__init__.py, line 2055, in get_prep_value Raised during: servicebook.views.ServiceRecordCreateView Python Executable: /usr/bin/python3 Python Version: 3.10.12 Python Path: ['/home/kamil/workspace/car_care_log', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/home/kamil/.local/lib/python3.10/site-packages', '/usr/local/lib/python3.10/dist-packages', '/usr/lib/python3/dist-packages']
解决方案
问题根源
clean_workshop方法返回的是Workshop对象,但Django ModelForm的外键字段期望清理后的值是主键ID(数字类型)。当对象被传入外键字段时,Django会尝试将其当作ID处理,从而触发类型错误。
修复步骤
修改clean_workshop方法,返回Workshop对象的ID而非对象本身:
def clean_workshop(self): workshop_id = self.cleaned_data.get('workshop') if workshop_id == 0: # 处理"Other Workshop"情况 workshop = Workshop.objects.filter(name="Other Workshop").first() if not workshop: raise forms.ValidationError("Other Workshop is not available.") workshop_id = workshop.id # 获取实际主键ID else: # 可选:验证ID对应的Workshop是否存在,避免无效值 try: Workshop.objects.get(id=workshop_id) except Workshop.DoesNotExist: raise forms.ValidationError("Invalid workshop selected.") return workshop_id
额外检查
确认ServiceRecord模型中的workshop字段是ForeignKey类型关联到Workshop模型,确保字段定义正确:
class ServiceRecord(models.Model): workshop = models.ForeignKey(Workshop, on_delete=models.CASCADE) # 其他字段...
内容的提问来源于stack exchange,提问作者Kamil_Kruczkowski
相关产品推荐
相关产品推荐

