Запрос Django - объедините два разных случая в фильтре

Я использую Django 1.10

У меня есть запрос, который зависит от полученного параметра - это зависит от того, имеет ли 'job_name' значение None или нет:

def delete_jobs_by_age_and_name(days_ago, job_name=None):

    date_to_delete_from = datetime.today() - timedelta(days=days_ago

    if job_name is not None:
        jobs_to_delete = AsyncJob.objects.filter(
            name=job_name,
            created_at__lte=date_to_delete_from
    )

    else:
        jobs_to_delete = AsyncJob.objects.filter(created_at__lte=date_to_delete_from)

Я хотел бы сделать это одним запросом. Например что-то вроде:

job_name = ANY if job_name is None
jobs_to_delete = AsyncJob.objects.filter(
            name=job_name,
            created_at__lte=date_to_delete_from
    )

Есть такой вариант?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
42
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете составлять запросы.

jobs_to_delete = AsyncJob.objects.filter(created_at__lte=date_to_delete_from)
if job_name is not None:
    jobs_to_delete = jobs_to_delete.filter(name=job_name)

Я искал способ выполнить запрос только один раз. Спасибо

user2880391 07.08.2018 14:23

Это действительно запускает запрос только один раз. Наборы запросов ленивы, а filter () фактически не выполняет никаких вызовов базы данных.

Daniel Roseman 07.08.2018 14:25

Я считаю, что функция должна вернуть значение jobs_to_delete.

Самый короткий (2 строки) способ, о котором я могу думать:

jobs_to_delete = AsyncJob.objects.filter(created_at__lte=date_to_delete_from)
return jobs_to_delete.filter(name=job_name) if job_name else jobs_to_delete 

Таким образом, вы используете встроенный оператор if, который сокращает написанный код и сохраняет все читабельным и простым.

Спасибо за этот фрагмент кода, который может оказать некоторую немедленную помощь. правильное объяснение значительно улучшило бы его долгосрочную ценность, показывая Зачем, это хорошее решение проблемы, которое сделает его более полезным для будущих читателей с другими похожими вопросами. Пожалуйста, редактировать свой ответ, чтобы добавить некоторые пояснения, включая сделанные вами предположения.

Tim Diekmann 07.08.2018 10:55
Ответ принят как подходящий

Вы можете передать свои аргументы filter в качестве словаря, который вы можете изменить заранее, чтобы вам понадобился только один вызов filter, а затем просто распакуйте словарь в вызове filter. Что-то вроде этого:

filter_kwargs = {'created_at__lte': date_to_delete_from}
if job_name is not None:
    filter_kwargs['name'] = job_name

jobs_to_delete = AsyncJob.objects.filter(**filter_kwargs)

Отличная идея. Спасибо.

user2880391 07.08.2018 14:17

Другие вопросы по теме