【问题标题】:Problem with save method overriding attribute value保存方法覆盖属性值的问题
【发布时间】:2021-03-27 09:19:04
【问题描述】:

我有一个名为“Trip”的模型,它带有一个指向“Destination”的外键。 Destination 模型在其 'max_passengers' 属性中指定了最大乘客数量。

旅行

class Trip(models.Model):

    destination = models.ForeignKey(
        Destination,
        null=True,
        blank=False,
        on_delete=models.SET_NULL,
        related_name="trips",
    )
    date = models.DateTimeField()
    seats_available = models.IntegerField(
        null=False, blank=False, editable=False
    )
    trip_ref = models.CharField(
        max_length=32, null=True, editable=True, blank=True
    )

目的地

class Destination(Product):

    max_passengers = models.IntegerField(null=True, blank=True)
    duration = models.CharField(max_length=20, blank=True)
    addons = models.ManyToManyField(AddOn)
    min_medical_threshold = models.IntegerField(
        default=0, null=False, blank=False
    )

    def __str__(self):
        return self.name

回到 Trip 模型,我重写了模型 save 方法,以便在创建旅行对象时,将该实例的“seats_available”设置为相关目的地的“max_passengers”:

def save(self, *args, **kwargs):

    if not self.trip_ref:
        date = (self.date).strftime("%m%d-%y")
        self.trip_ref = self.destination.pk + "-" + date

    if not self.seats_available:
        self.seats_available = self.destination.max_passengers
    super().save(*args, **kwargs)

我还有其他用于预订和乘客的模型。创建预订时,会发送 post_save 信号,调用我的 Trips 模型 def update_seats_avaialable() 上的模型方法:

def update_seats_available(self):

    reservations = (
        self.bookings.aggregate(num_passengers=Count("passengers"))
        ["num_passengers"]
    )
    self.seats_available = self.destination.max_passengers - reservations
    self.save() <---- PROBLEM

问题是当所有座位最终都被占用时,即。乘客人数 = max_passengers 和可用座位 = 0。当 self.save 触发保存方法时,if not self.seats_available = true 并且运行这行代码:self.seats_available = self.destination.max_passengers 将可用座位设置回它开始的位置。还有另一种初始化模型对象的方法吗?我的理解是不建议使用 init 方法...

【问题讨论】:

  • 您可以在.save 覆盖上添加self.id 检查。因此if not self.id and not self.seats_available:。因为一个对象在保存之前没有设置 id。
  • post_save 信号和 self.save() 是否会导致保存循环?

标签: django model init


【解决方案1】:

好的,我想出了一个解决方案:

def update_seats_available(self):

    reservations = (
        self.bookings.aggregate(num_passengers=Count("passengers"))
        ["num_passengers"])
    self.save(reservations=reservations)

def save(self, *args, **kwargs):


    if not self.trip_ref:
        date = (self.date).strftime("%m%d-%y")
        self.trip_ref = self.destination.pk + "-" + date

    reservations = kwargs.pop('reservations', 0)
    self.seats_available = self.destination.max_passengers - reservations
    super().save(*args, **kwargs)

这里我将保留的值传递给 save 方法并在那里进行计算。

【讨论】:

    猜你喜欢
    • 2013-05-09
    • 2019-07-25
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-13
    • 2016-07-26
    相关资源
    最近更新 更多