Есть ли способ вставить пустое поле datetime из другой таблицы? - PullRequest
1 голос
/ 04 мая 2020
class Customer(models.Model):

    last_purchase = models.DateTimeField(blank=True, null=True)

У меня есть пустой DateTimeField, который будет постоянно обновляться с последним измененным DateTimeField в соответствующей таблице.

class Order(models.Model):
    customer = models.ForeignKey(Customer, null=True, on_delete= models.SET_NULL)
    date_created = models.DateTimeField(auto_now_add=True, null=True)


Как это будет выглядеть при просмотре?

1 Ответ

0 голосов
/ 04 мая 2020

Пожалуйста, сделайте , а не дублирующиеся данные. Хранение одних и тех же данных или совокупностей данных часто является анти-паттерном. Оказывается, что хранить данные в syn c сложнее, чем можно ожидать. Это означает, что если Order создан, обновлен, удален или изменен с Customer, вы должны обновить связанный Customer. Легко пропустить несколько случаев, чтобы достичь несогласованности.

Что часто лучше, так это использовать .annotate(..) для аннотирования набора запросов. Таким образом, если вы удалите поле last_purchase у клиента, а Order имеет ForeignKey для клиента:

class Customer(models.Model):
    # …

class Order(models.Model):
    date_created = models.DateTimeField(auto_now_add=True)
    customer = models.ForeignKey(Customer, null=True, on_delete=models.SET_NULL)

, тогда мы можем сделать QuerySet, который выглядит следующим образом:

from django.db.models import Max

Customer.objects.annotate(
    last_purchase=Max('order__date_created')
)

Это будет None (NULL), если Customer не сделал ни одного заказа.

Если вам это нужно часто, вы можете определить logi c в a Manager:

from django.db import models
from django.db.models import Max

class CustomerManager(models.Manager):

    def get_queryset(self):
        return super().get_queryset(*args, **kwargs).annotate(
            last_purchase=Max('order__date_created')
        )

class Customer(models.Model):
    # …
    <b>objects = CustomerManager()</b>

class Order(models.Model):
    date_created = models.DateTimeField(auto_now_add=True)
    customer = models.ForeignKey(Customer, null=True, on_delete=models.SET_NULL)

Теперь он будет автоматически аннотировать объекты при использовании Customer.objects.

. Это сделает запрос, который выглядит следующим образом:

SELECT customer.*
       <b>MAX(order.date_created) AS last_purchase</b>
FROM   customer

Вы, конечно, можете выполнить дополнительную фильтрацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...