在 Django 中提交表单后更改模型数据

Change Model data after form submission in Django

提问人:Essiprog 提问时间:11/10/2023 更新时间:11/10/2023 访问量:54

问:

我正在使用 ModelForms 在 Django 中编写一个预订系统,我想在表单保存时更改 ForeginKey 模型中布尔字段的值。

models.py

class AvailableHours(models.Model):
    free_date = models.ForeignKey(AvailableDates, null=True, blank=True,on_delete=models.CASCADE)
    free_hours_from = models.CharField(max_length=10,null=True, blank=True)
    free_hours_to = models.CharField(max_length=10,null=True, blank=True)
    status = models.BooleanField(null=True,default=True)

class Bookings(models.Model):   
...
    booked_time = models.ForeignKey(AvailableHours, on_delete=models.CASCADE,related_name='booked_time')
   

views.py

@login_required()
def booking_form(request):
    form = forms.BookingForm()
    if request.method == 'POST':
        form = forms.BookingForm(request.POST)
        if form.is_valid():
            book = form.save(commit=False)
            book.user = request.user
            form.save()
            return HttpResponseRedirect(reverse('creator:login'))
    return render(request, 'account/book.html', {'form': form})

forms.py

class BookingForm(forms.ModelForm):
    class Meta:
        model = Bookings
        exclude = ('user','booking_code','confirmed',)

由于我希望每个 AvailableHours 只能预订一次,因此我需要表单将 AvailableHours status 的值更改为 False,以便我可以在模板中过滤它。

谁能建议解决这个问题的方法?

我试过类似的东西

form.booked_time.status = False

在我看来,但它没有用

django django 模型 视图 django 表单

评论


答:

3赞 Muhammad Hammad 11/10/2023 #1

Django Forms 类有自己的 save 方法,用于保存数据并与实例一起返回。若要在保存后更改数据,只需为 Form 类创建自定义保存方法。保存窗体时将调用此方法。

...
def save(self, commit=True):
  
    instance = super(BookingForm, self).save(commit)
    instance.booked_time.status = False
    instance.save()
    return instance

要了解有关自定义保存方法的更多信息,请参阅此处

评论

0赞 Essiprog 11/10/2023
感谢您的回复。但你的答案不起作用。booked_time.status 的值仍为 True
0赞 nigel239 11/10/2023
因为您保存了错误的对象。您需要保存 .instance.booked_time
0赞 Muhammad Hammad 11/10/2023
这是因为您传递的是 commit=False,在这种情况下,实例值会更新并且不会返回最新的实例值。非常简单的解决方案,让 thia 传递提交值 True。
3赞 Bubble 11/10/2023 #2

你可以使用 Django 信号,它提供了一种处理事件的便捷方式。

from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Bookings

@receiver(post_save, sender=Bookings)
def update_available_hours_status(sender, instance, created, **kwargs):
    if created:
        # If a new Booking is created
        booked_time = instance.booked_time
        booked_time.status = False
        booked_time.save()

参考