Django获取登录用户所有预订及关联User实例错误排查
问题解决步骤
1. 修复Customer.user赋值错误
错误Cannot assign 'leonie': 'Customer.user' must be a 'User' instance的核心原因:你给外键字段customer.user赋值了字符串类型的用户名(request.user.username),但外键字段要求接收User模型的实例,直接传入request.user即可。
修改customer_booking视图中的对应代码:
# 原错误代码 customer.user = request.user.username # 修改后 customer.user = request.user
2. 修正模型关联逻辑
当前模型设计存在逻辑矛盾:Booking直接关联User,但同时存在Customer模型关联User,导致查询登录用户预订时逻辑混乱。正确的关联关系应为:
- 一个
User对应一个Customer(用OneToOneField更合理) - 一个
Customer对应多个Booking
更新models.py:
from django.db import models from django.contrib.auth.models import User BOOKING_STATUS = ((0, '待确认'), (1, '已确认'), (2, '已拒绝')) class Customer(models.Model): first_name = models.CharField(max_length=80) last_name = models.CharField(max_length=80) email = models.EmailField() phone_number = models.CharField(max_length=20) # 一对一关联User,确保一个用户仅对应一个客户信息 user = models.OneToOneField(User, on_delete=models.CASCADE) def __str__(self): return f"{self.user.username} - {self.first_name} {self.last_name}" class Booking(models.Model): booking_date = models.DateField() booking_time = models.TimeField() number_attending = models.IntegerField(default=2) booking_status = models.IntegerField(choices=BOOKING_STATUS, default=0) # 关联Customer模型,而非直接关联User customer = models.ForeignKey(Customer, on_delete=models.CASCADE) def __str__(self): return f"{self.customer.user.username}的预订 - {self.booking_date} {self.booking_time}"
3. 修正预订记录查询逻辑
更新display_booking视图,通过当前登录用户找到对应Customer,再查询该客户的所有预订:
def display_booking(request): # 获取当前用户绑定的Customer实例,不存在则返回404 customer = get_object_or_404(Customer, user=request.user) # 查询该客户的全部预订 bookings = Booking.objects.filter(customer=customer) context = { 'bookings': bookings, } return render(request, 'booking.html', context)
额外优化:避免重复创建客户信息
如果用户已创建过客户信息,无需重复填写,可在customer_booking视图中增加判断逻辑:
def customer_booking(request): # 尝试获取当前用户的Customer实例 try: customer = Customer.objects.get(user=request.user) except Customer.DoesNotExist: customer = None if request.method == 'POST': # 若已有客户信息,用instance填充表单 customer_form = CustomerForm(request.POST, prefix='customer', instance=customer) booking_form = BookingForm(request.POST, prefix='booking') if customer_form.is_valid() and booking_form.is_valid(): customer = customer_form.save(commit=False) customer.user = request.user customer.save() booking = booking_form.save(commit=False) booking.customer = customer booking.save() # 重置表单,保留已填写的客户信息 customer_form = CustomerForm(prefix='customer', instance=customer) booking_form = BookingForm(prefix='booking') else: # 初始化表单时填充已有客户信息 customer_form = CustomerForm(prefix='customer', instance=customer) booking_form = BookingForm(prefix='booking') context = { 'customer_form': customer_form, 'booking_form': booking_form, } return render(request, 'booking.html', context)
内容的提问来源于stack exchange,提问作者Leonie
相关产品推荐
相关产品推荐

