Django含外键对象无法编辑:修改时新建对象问题
编辑含外键的TimeSlot对象时新建而非更新的问题解决
编辑包含外键的TimeSlot对象时,执行修改操作并未更新原有对象,而是新建了一个新对象。无外键的模型对象可正常编辑,推测问题与外键有关。
models.py 代码
class Room(models.Model): class Meta: ordering = ['room_number'] room_number = models.PositiveSmallIntegerField( validators=[MaxValueValidator(1000), MinValueValidator(1)], primary_key=True ) ROOM_CATEGORIES = ( ('Regular', 'Regular'), ('Executive', 'Executive'), ('Deluxe', 'Deluxe'), ('King', 'King'), ('Queen', 'Queen'), ) category = models.CharField(max_length=9, choices=ROOM_CATEGORIES) ROOM_CAPACITY = ( (1, '1'), (2, '2'), (3, '3'), (4, '4'), ) capacity = models.PositiveSmallIntegerField( choices=ROOM_CAPACITY, default=2 ) advance = models.PositiveSmallIntegerField() room_manager = models.CharField(max_length=30) class TimeSlot(models.Model): room = models.ForeignKey(Room, on_delete=models.CASCADE) available_from = models.TimeField() available_till = models.TimeField()
views.py 代码
def edit_time_slots(request, pk): if pk: try: time_slot_obj = TimeSlot.objects.get(pk=pk) except Exception: return HttpResponse("Bad request.") else: return HttpResponse("Bad request.") if request.method == 'POST': form = AddTimeSlotForm(request.POST, instance=time_slot_obj) if form.is_valid(): try: Room.objects.get(room_number=time_slot_obj.room.room_number, room_manager=request.user.username) except Exception: return HttpResponse("Bad request.") time_slot = TimeSlot(room=time_slot_obj.room, available_from=request.POST['available_from'], available_till=request.POST['available_till']) time_slot.save() # Implemented Post/Redirect/Get. return redirect(f'../../view_time_slots/{time_slot_obj.room.room_number}/') else: context = { 'form': form, 'username': request.user.username } return render(request, 'add_time_slots.html', context) context = { 'form': AddTimeSlotForm(instance=time_slot_obj), 'username': request.user.username } return render(request, 'edit_time_slots.html', context)
问题原因与修复
问题和外键无关,核心错误是在POST处理逻辑中手动新建了TimeSlot实例,没有对获取到的原有time_slot_obj进行更新。
代码中已经正确初始化了带instance=time_slot_obj的表单,直接调用form.save()就能完成原有对象的更新,无需重新构造TimeSlot对象。
修改后的POST处理代码如下:
if request.method == 'POST': form = AddTimeSlotForm(request.POST, instance=time_slot_obj) if form.is_valid(): try: Room.objects.get(room_number=time_slot_obj.room.room_number, room_manager=request.user.username) except Exception: return HttpResponse("Bad request.") # 直接保存表单,自动更新原有实例 form.save() return redirect(f'../../view_time_slots/{time_slot_obj.room.room_number}/')
另外,避免直接从request.POST取值,表单已完成数据验证和清洗,使用form.save()是更安全、符合Django开发规范的做法。
内容的提问来源于stack exchange,提问作者Anshul Gupta
相关产品推荐
相关产品推荐

