Annotate возвращает нулевое значение для несуществующих значений, и я хочу преобразовать это значение в пустую строку - PullRequest
1 голос
/ 17 октября 2019

У меня есть две модели, Клиент и Покупка. Я хочу вернуть последний магазин, в котором покупатель приобрел товар, и заказать его.

Я могу успешно отобразить этот список, показывая последний магазин, в котором покупатель приобрел товар, и возможность сделать заказ по названию магазина, используя следующиемодели, запрос / подзапрос.

# models
class Customer(models.Model):

    name = models.CharField(max_length=30)

class Purchase(models.Model):

    store = models.CharField(max_length=30)
    amount = models.DecimalField(decimal_places=2,max_digits=6)
    customerID = models.ForeignKey(Customer, on_delete=models.CASCADE, 
                                   related_name='purchases')
    order_date = models.DateField()

#viewset

#subquery
purchase_qs = Purchase.objects.filter(customerID=OuterRef("pk")).order_by("-order_date")

queryset = Customer.objects.all().annotate(last_purchase=Subquery(purchase_qs.values('store')[:1]))

ordering_fields = ['last_purchase']

Мой текущий вывод для клиентов с нулевыми покупками:.

"last_purchase": null

Я хочу иметь

"last_purchase": ""

1 Ответ

0 голосов
/ 17 октября 2019

ForeignKey поля автоматически добавляют _id к имени поля модели, поэтому вам нужно будет использовать customerId_id для ссылки на ForeignKey. Ясно, что это не то, что вам нужно, поэтому я бы рекомендовал вместо этого переименовать поле в customer, и я думаю, именно поэтому ваш запрос пуст.

С учетом сказанного, вы на самом деле недля этого нужно Subquery или OuterRef. Вместо этого вы можете использовать обратное отношение вашей Customer модели вместе с Max:

from django.db.models import Max

Customer.objects.select_related('Purchase').annotate(
    last_purchase = Max('purchases__order_date')
)

Наконец, ключ null по умолчанию имеет значение False, поэтому нет необходимостискажем null=False, и не имеет смысла иметь blank=True, но null=False. См. этот вопрос для превосходного объяснения различия между null и blank.

Обновление

CoalesceПохоже, что функция идеально подходит для этого сценария:

from django.db.models import Max, Coalesce, Value

Customer.objects.select_related('Purchase').annotate(
    last_purchase = Coalesce(Max('purchases__order_date', Value(''))
)
...