Проверьте, существует ли элемент - PullRequest
0 голосов
/ 29 июля 2009

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

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

filenames = os.listdir(settings.SCREENSHOTS_ON_DISC)
for filename in filenames:
    exists = Screenshot.objects.filter(filename=filename)
    if exists:
        ...

Есть ли более приятный / быстрый способ сделать это? Обратите внимание, что снимок экрана может быть в базе данных более одного раза (поэтому я не использовал .get).

Ответы [ 3 ]

2 голосов
/ 29 июля 2009

Если ваша модель Screenshot имеет много атрибутов, то код, который вы показали, выполняет ненужную работу для ваших конкретных нужд. Например, вы можете сделать что-то вроде этого:

files_in_db = Screenshot.objects.values_list('filename', flat=True).distinct()

, который выдаст вам список всех имен файлов в базе данных и сгенерирует SQL для выборки только имен файлов. Он не будет пытаться создавать и заполнять объекты Screenshot. Если у вас есть

files_on_disc = os.listdir(settings.SCREENSHOTS_ON_DISC)

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

1 голос
/ 29 июля 2009

Этот запрос возвращает вам все файлы, которые находятся в вашей базе данных и файловой системе:

discfiles = os.listdir(settings.SCREENSHOTS_ON_DISC)

filenames = (Screenshot.objects.filter(filename__in=discfiles)
                               .values_list('filename', flat=True)
                               .order_by('filename')
                               .distinct())

Обратите внимание на order_by. Если в определении модели указан порядок, то использование distinct может не дать ожидаемого результата. Это задокументировано здесь:

Так что сделайте порядок явным, затем выполните запрос.

1 голос
/ 29 июля 2009

Вы можете попробовать:

Screenshot.objects.filter(filename__in = filenames)

Это даст вам список всех скриншотов, которые у вас есть. Вы можете сравнить два списка и посмотреть, что не существует между ними. Это должно помочь вам начать, но вы можете настроить запрос на производительность / использование.

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