Django如何在Queryset中调整尝试次数

q9yhzks0  于 2023-06-25  发布在  Go
关注(0)|答案(1)|浏览(98)

我有这样的模型:

class Order(models.Model):
    order_id = models.CharField(max_length=100)
    title = models.TextField(max_length=600)
    title_2 = models.TextField(max_length=100)
    attempts = models.ForeignKey('self', blank=True, null=True, on_delete=models.PROTECT)
    driver = models.ForeignKey(Driver, blank=True, null=True, on_delete=models.SET_NULL)
    updated_at = models.DateTimeField(blank=True, default=datetime.datetime.now())

我想在我的anotation实现我需要一些尝试的基础上旧的updated_at值。但活跃的顺序有attempts=None。我怎样才能正确地计算尝试次数?

5fjcxozz

5fjcxozz1#

首先,如果有一个与self相关的fk,您的数据库中将有一些严重的数据重复。因为您必须重新创建Order及其值,并设置与第一个相关的attempt。要避免重复的字段,请创建另一个表来保存这些DeliveryAttempts
请注意,您可以在DateTimeField上使用.auto_now.auto_now_add而不是default
models.py

class Order(models.Model):
    order_id = models.CharField(max_length=100)
    title = models.TextField(max_length=600)
    title_2 = models.TextField(max_length=100)
    driver = models.ForeignKey(Driver, null=True, on_delete=models.SET_NULL)
    updated_at = models.DateTimeField(blank=True, default=datetime.datetime.now())

class DeliveryAttempts(models.Model):
    order = models.ForeignKey(Order, related_name='attempts', on_delete=models.CASCADE)
    attempted_at = models.DateTimeField(auto_now_add=True)

你不一定需要annotate你的QuerySet你可以实现一个SerializerMethodField和计数相关的对象,这是更简单的方式。但是,既然你问了,这里有一种方法可以做到这一点:
views.py

class OrderListAPIView(ListAPIView):
    queryset = Order.objects.all()
    serializer_class = OrderSerializer

    def get_queryset(self):
        qs = (
            super().get_queryset()
            .prefetch_related('attempts')
            .annotate(attempts_count=Count('attempts'))
        )
        return qs

serialiers.py

class OrderSerializer(serializers.ModelSerializer):
    attempts = serializers.IntegerField(source='attempts_count')

    class Meta:
        model = Order
        fields = ['order_id', 'title', 'title_2', 'updated_at', 'attempts']

相关问题