Django: фильтр по атрибуту внешнего ключа для самоссылки - PullRequest
3 голосов
/ 10 января 2020

В моем приложении Django 2.2 у меня есть такая модель:

class Folder(models.Model):
    name = models.CharField(max_length=100)
    parent_folder = models.ForeignKey("Folder", null=True, on_delete=models.SET_NULL)

По сути, папка может иметь родителя, родительский объект этой папки может иметь родителя и т. Д.

Итак, что я хотел бы сделать, это упорядочить папки по их атрибутам name, начиная с папок верхнего уровня (то есть папок без parent_folder), а затем по убыванию в иерархии папок.

Для иллюстрации приведем следующие объекты в таблице:

+----+---------+---------------+
| id |  name   | parent_folder |
+----+---------+---------------+
|  1 | fuel    | <None>        |
|  2 | blabla  | 1             |
|  3 | volcano | 2             |
|  4 | awful   | 2             |
|  5 | apple   | 1             |
|  6 | amazing | <None>        |
|  7 | wow     | 6             |
+----+---------+---------------+

Упорядоченный вывод I, за исключением:

+----+---------+---------------+
| id |  name   | parent_folder |
+----+---------+---------------+
|  6 | amazing | <None>        |
|  7 | wow     | 6             |
|  1 | fuel    | <None>        |
|  5 | apple   | 1             |
|  2 | blabla  | 1             |
|  4 | awful   | 2             |
|  3 | volcano | 2             |
+----+---------+---------------+

Ответы [ 2 ]

3 голосов
/ 10 января 2020

Я рекомендую использовать для этого django-mptt, который можно установить с помощью pip3 install django-mptt.

Добавить mptt в INSTALLED_APPS, затем изменить вашу модель:

from mptt.models import MPTTModel, TreeForeignKey

class Folder(MPTTModel):
    name = models.CharField(max_length=100)
    parent = TreeForeignKey('self', on_delete=models.CASCADE, blank=True, null=True)

Теперь вы можете просто позвонить Folder.get_family(), и ваш набор запросов будет отсортирован в «древовидном порядке» по умолчанию.

2 голосов
/ 10 января 2020

Может быть легко достигнуто с помощью Django MPTT .

То, что вам нужно, возвращается .get_family() (см. документы ).

...