Как использовать timedelta со столбцом в моем запросе Django ORM? - PullRequest
0 голосов
/ 22 января 2019

Я использую Django и Python 3.7.У меня есть две нижеприведенные модели ...

class Article(models.Model):
    ...
    publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE, related_name="articles",)
    created_on = models.DateTimeField(default=datetime.now)

class WebPageStat(models.Model):
    ...
    publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE, related_name="stats", )

    elapsed_time_in_seconds = models.FloatField(default=0)
    score = models.BigIntegerField(default=0)

class Publisher(models.Model):
   name = models.CharField(max_length=100)

   def __str__(self):
       return self.name

Я хочу написать запрос Django ORM, в котором указаны издатель и истекшее время в секундах (запись WebPageStat), я нахожу все статьи, чей "made_on"дата не старше истекшего времени в секундах.Многие предлагали использовать «timedelta» в других статьях, но мне это здесь не подходит ...

Article.objects.filter(created_on__lte=datetime.now(timezone.utc) - timedelta(hours=0, minutes=0, seconds=publisher__stats__elapsed_time_in_seconds))
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'publisher__stats__elapsed_time_in_seconds' is not defined

Могу ли я использовать timedelta с логикой столбцов SQL?Иначе как мне это сделать?

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Основная проблема заключается в том, что вы не понимаете, почему вы получаете ошибку

name 'publisher__stats__elapsed_time_in_seconds' is not defined`.

Давайте еще раз посмотрим на код:

Article.objects.filter(created_on__lte=datetime.now(timezone.utc) -
    timedelta(hours=0, minutes=0, seconds=publisher__stats__elapsed_time_in_seconds))

Вкод над символом publisher__stats__elapsed_time_in_seconds интерпретируется как ссылка на переменную, которая не определена в вашем коде. Если вы добавили

publisher__stats__elapsed_time_in_seconds = 1

непосредственно перед фрагментом кода выше, вы не получитеошибка.(Вы также не получите желаемых результатов.) Вы ожидаете, что ORM в Django будет работать с символом publisher__stats__elapsed_time_in_seconds, но прежде чем Django сможет добраться до него, интерпретатор Python должен интерпретировать код и способ написания кода,это просто имя переменной, которую должен разрешить интерпретатор.Django не имеет возможности даже увидеть его.

Хорошо, поэтому способ запретить интерпретатору интерпретировать имя как ссылку на переменную и заставить Django ORM обрабатывать имя, заключается в использовании F() выражения .Таким образом, у вас будет соблазн просто сделать это:

Article.objects.filter(created_on__lte=datetime.now(timezone.utc) -
    timedelta(hours=0, minutes=0, seconds=F("publisher__stats__elapsed_time_in_seconds")))

Но тогда вы будете передавать timedelta параметр, который он не знает, как обрабатывать.

Как указал Шиллингтв комментарии , в другом ответе Lutz Prechelt показано, как переместить выражение F() за пределы timedelta.В вашем случае вы можете сделать это:

Article.objects.filter(created_on__lte=datetime.now(timezone.utc) -
        timedelta(seconds=1) * F("publisher__stats__elapsed_time_in_seconds"))))
0 голосов
/ 24 января 2019

В зависимости от модели издателя существует проблема определения поля для сравнения. Ваше поле в вопросе

publisher__stats__elapsed_time_in_seconds

Ваш код запроса

Article.objects.filter(created_on__lte=datetime.now(timezone.utc) - timedelta(hours=0, minutes=0, seconds=publisher__stats__elapsed_time_in_seconds)).

Это означает, что мне нужно получить все статьи, у которых есть время создания (поле create_on) до или точно равное времени (поле elapsed_time_in_seconds) для статьи -> publisher -> records record.

Это означает, что он ищет поле elapsed_time_in_seconds на объекте stats, которое должно быть связано с вашим объектом издателя через FK или каким-либо другим способом. В свою очередь, объект издателя должен быть связан с вашим объектом статьи.

Ваша модель Article связана с моделью Publisher, но, похоже, нет никакой связи между Publisher и Stats (??). Можете ли вы проверить модель статистики, чтобы увидеть, что поле и отношение определены правильно?

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