Django Запрос отменен, начинается с - PullRequest
0 голосов
/ 20 апреля 2020

У меня есть модель, которая содержит путь к папке, и я хочу получить каталоги, которые содержат точный путь.

Это моя модель:

class Directory(models.Model):
    name = models.CharField(max_length=5)
    path=models.CharField(max_length=100)

В этой модели; name поле всегда что-то вроде этого "A" или "ZDCF"

Правило именования простое:

  • символ uniqeu с использованием наименьшего символа (A, B, .... Z, AA, AB ...)

Имена путей имеют два простых правила:

  1. Всегда заканчивается точкой "."
  2. Сумма верхних путей (например, ".AB")

И это то, что я хочу: Я хочу выбрать все верхние каталоги, которые содержат указанный c путь к каталогу.


Я попытаюсь объяснить с помощью изображения:

Directory Tree

Допустим, эти круги - это мои каталоги.

В этом примере я выбрал именованный каталог ' D ' и хочу чтобы получить верхние каталоги "C", "B" и "A".

Я не хочу получать 'E', 'F' , 'G', 'H' и 'J' названы директорами.


Объясняя с изображением; Я хочу получить только все зеленые кружки ; Список результатов должен содержать только зеленые кружки, но не должен содержать оранжевый один.

Если я использую этот код:

myDir = Directory.objects.get(name='D')
listDir = Directory.objects.filter(path__startswith=myDir.path)

listDir QuerySet будет содержать «E», «F», «G», «H» и «J». Но я не хочу их.

И если я использую этот код:

myDir = Directory.objects.get(name='D')
listDir =[]
for xDir in Directory.objects.all():
    realPath = xDir.path+xDir.name+'.'
    if myDir.path.startswith(realPath):
        listDir.append(xDir)

Да, listDir будет содержать то, что я хочу, но будет много l oop так что Я не хочу использовать l oop или итератор тоже.

Я обновил код здесь; Если я не использую переменную ' realPath ', listDir будет также содержать имена с именами dirs, такие как "K", "L", "M", "O", "P".

Да, я знаю, что будут лучшие решения l oop, возможно, может сократить время l oop с использованием некоторых итерационных инструментов, но, я думаю, это не будет хорошим решением, , поскольку вы не фильтруете по БД напрямую, вы обрабатываете список после получения его из БД, поэтому он будет работать медленнее.


Как я могу фильтровать мои каталоги , используя Django собственные параметры запроса (без каких-либо запросов l oop else)?


1 Ответ

0 голосов
/ 20 апреля 2020
from django.db.models.functions import Length

my_dir = Directory.objects.get(name='D')
dir_len = len(my_dir.path) 
list_dirs = Directory.objects.annotate(dir_len=Length('path')) \
                             .filter(dir_len__lte=dir_len, path__startswith=my_dir.path)
...