頂いた回答をもとに試行錯誤しておりましたが、クエリセットオブジェクトを取得できずなかなかうまく行きませんでした。(SQL自体はあっていますが、Djangoで応用しようとすると引っかかりました。)
スタックオーバーフローにも似た回答があり、以下のSQLでも良いそうです。
https://stackoverflow.com/questions/21943088/find-lowest-level-in-hierarchy
SQL
1SELECT id
2FROM Category
3EXCEPT
4SELECT parent_id
5FROM Category
上記SQLをDjangoのORM記述にしたところ、実現できました。
models.py
python
1class Category(models.Model):
2    category = models.CharField(verbose_name="Category", max_length=200, unique=True)
3    parent_id = models.ForeignKey('self', blank=True, null=True, on_delete=models.CASCADE)
4    register_time = models.DateTimeField(auto_now_add=True)
5
6    def select_lowest_level(self):
7        qs1 = Category.objects.values_list('id') #すべてのidを取得 <QuerySet [(1,), (2,), (3,), (4,), (5,), (6,), (7,), (8,), (9,)]>
8        qs2 = Category.objects.values_list('parent') #使われている親idを取得 <QuerySet [(None,), (1,), (2,), (2,), (4,), (3,),(None,), (7,), (8,)]>
9        qs3 = qs1.difference(qs2) #EXCEPTで差分のみ取得 <QuerySet [(3,), (4,), (9,)]>
10        id_list = [int(x[0]) for x in qs3] # idのリストに変換 [3, 4, 9]
11        cat = Category.objects.filter(id__in=id_list) #リストのIDに一致するものをSELECT
12        return cat # <QuerySet [<Category: ネコ科>, <Category: 犬科>, <Category: 地球>]>                             
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/12/25 09:08
2018/12/27 00:27 編集