gpt4 book ai didi

python - Django:属性和查询集注释之间的重复逻辑

转载 作者:行者123 更新时间:2023-12-03 14:20:20 25 4
gpt4 key购买 nike

当我想定义我的业务逻辑时,我正在努力寻找正确的方法来做到这一点,因为我经常需要一个属性和一个自定义查询集来获取相同的信息。最后,逻辑重复了。
让我解释...
首先,在定义我的类之后,我自然而然地开始为我需要的数据编写一个简单的属性:

class PickupTimeSlot(models.Model):

@property
def nb_bookings(self) -> int:
""" How many times this time slot is booked? """
return self.order_set.validated().count()
然后,我很快意识到在处理查询集中的许多对象时调用此属性会导致重复查询并降低性能(即使我使用预取,因为再次调用过滤)。所以我解决了用注释编写自定义查询集的问题:
class PickupTimeSlotQuerySet(query.QuerySet):

def add_nb_bookings_data(self):
return self.annotate(db_nb_bookings=Count('order', filter=Q(order__status=Order.VALIDATED)))
问题
然后,我最终遇到了两个问题:
  • 我写了两次相同的业务逻辑(“如何查找预订数量”),这可能会导致功能错误。
  • 我需要找到两个不同的属性名称以避免冲突,因为显然,设置 nb_bookings对于属性和注释都不起作用。这迫使我在使用我的对象时考虑 怎么样生成数据,调用正确的属性名称(比方说 pickup_slot.nb_bookings(属性)或 pickup_slot.db_nb_bookings(注释))

  • 这对我来说似乎设计得很差,我很确定有办法做得更好。我需要一种方法来始终写 pickup_slot.nb_bookings并有一个高效的答案,总是使用相同的业务逻辑。
    我有一个想法,但我不确定...
    我正在考虑完全删除该属性并仅保留自定义查询集。然后,对于单个对象,将它们包装在查询集中只是为了能够在其上调用添加注释数据。就像是: pickup_slot = PickupTimeSlot.objects.add_nb_bookings_data().get(pk=pickup_slot.pk)对我来说似乎很hacky和不自然。你怎么认为?

    最佳答案

    我不认为这里有 Elixir 。但是对于这种情况,我在我的项目中使用了这种模式。

    class PickupTimeSlotAnnotatedManager(models.Manager):
    def with_nb_bookings(self):
    return self.annotate(
    _nb_bookings=Count(
    'order', filter=Q(order__status=Order.VALIDATED)
    )
    )

    class PickupTimeSlot(models.Model):
    ...
    annotated = PickupTimeSlotAnnotatedManager()

    @property
    def nb_bookings(self) -> int:
    """ How many times this time slot is booked? """
    if hasattr(self, '_nb_bookings'):
    return self._nb_bookings
    return self.order_set.validated().count()
    在代码中
    qs = PickupTimeSlot.annotated.with_nb_bookings()
    for item in qs:
    print(item.nb_bookings)
    这样我总是可以使用属性,如果它是带注释的查询集的一部分,它将使用带注释的值,否则它将计算它。这种方法保证我将通过使用所需的值对其进行注释来完全控制何时使查询集“更重”。如果我不需要这个,我就使用普通的 PickupTimeSlot.objects. ...此外,如果有很多这样的属性,您可以编写装饰器来包装属性并简化代码。它将作为 cached_property 工作装饰器,但如果存在,它将使用带注释的值。

    关于python - Django:属性和查询集注释之间的重复逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64259054/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com