Django Rest Framework中创建关联模型的Booking对象实例赋值错误解决
解决方案
问题根源
- 模型字段命名混淆:Django的
ForeignKey字段应命名为关联对象的名称(如customer),而非customer_id——字段本身存储的是对象实例,Django会自动在数据库生成customer_id列,当前命名导致赋值逻辑混乱。 - 视图拼写错误:视图中
barberb_id是笔误,应与模型字段名barber_id一致。 - 赋值方式错误:
ForeignKey字段需传入对应模型实例,而非直接传ID(除非使用字段名_id的格式赋值,但当前字段名已占用该命名)。
修复步骤
步骤1:修正Booking模型的字段命名(推荐,符合Django最佳实践)
将ForeignKey字段名改为关联对象名称,避免与自动生成的数据库列名混淆:
from django.db import models from django.contrib.auth.models import User class Booking(models.Model): customer = models.ForeignKey(User, on_delete=models.CASCADE) barber = models.ForeignKey(Barber, on_delete=models.CASCADE) timeslot = models.DateTimeField('appointment') def __str__(self): return f"{self.customer} {self.barber} {self.timeslot}"
步骤2:修正createBooking视图逻辑
- 修正拼写错误
- 先通过ID获取User和Barber实例,避免直接传ID导致的类型错误
- 加入异常处理,防止ID不存在的情况
from django.http import Response from django.contrib.auth.models import User from .models import Booking, Barber from .serializers import BookingSerializer from rest_framework import status def createBooking(request): data = request.data # 验证用户和理发师是否存在 try: customer = User.objects.get(id=data['customer_id']) barber = Barber.objects.get(id=data['barber_id']) except (User.DoesNotExist, Barber.DoesNotExist): return Response({"error": "指定的用户或理发师不存在"}, status=status.HTTP_404_NOT_FOUND) # 创建Booking实例 booking = Booking.objects.create( customer=customer, barber=barber, timeslot=data['timeslot'], ) serializer = BookingSerializer(booking, many=False) return Response(serializer.data)
替代方案(不修改模型字段名)
如果不想修改模型字段名,需传入对应实例而非ID:
def createBooking(request): data = request.data try: customer = User.objects.get(id=data['customer_id']) barber = Barber.objects.get(id=data['barber_id']) except (User.DoesNotExist, Barber.DoesNotExist): return Response({"error": "指定的用户或理发师不存在"}, status=status.HTTP_404_NOT_FOUND) booking = Booking.objects.create( customer_id=customer, # 传入User实例 barber_id=barber, # 传入Barber实例 timeslot=data['timeslot'], ) serializer = BookingSerializer(booking, many=False) return Response(serializer.data)
额外注意事项
- 确保前端传入的
customer_id和barber_id是整数类型,而非数组或字符串(错误信息中的["customer_id"]提示可能是前端传值格式错误,需确认请求数据格式)。 - 建议使用Django REST Framework的序列化器验证功能,在创建前先验证数据合法性,减少异常处理代码。
内容的提问来源于stack exchange,提问作者Süleyman Eminbəyli
相关产品推荐
相关产品推荐

