6

ManyToManyField を介して接続されている 2 つのモデル (写真とタグ) があります。

class Photo(models.Model):
    tags = models.ManyToManyField(Tag)

class Tag(models.Model):
    lang = models.CharField(max_length=2)
    name_es = models.CharField(max_length=40)
    name_en = models.CharField(max_length=40)

時折、どの写真からも参照されなくなった孤立したタグを取得します。これらのタグを効率的に削除する方法はありますか? 私はこの答えについて知っています: Django: M2M孤立したエントリを削除しますか?

現時点でのソリューションは次のようになります。

for tag in Tag.objects.all():
    if not tag.photo_set.select_related(): tag.delete()

ただし、データベースの増加に伴い、このスクリプトの実行時間は非常に長くなります:-P タグ テーブルからすべてのタグ ID のリストを取得し、多対多テーブルからすべてのタグ ID のリストを取得する効率的な方法はありますか?交点リストを作成するためのテーブル?

4

3 に答える 3

4

中間テーブルでサブクエリを試す

qs = Tag.objects.exclude(pk__in=Book.tags.through.objects.values('tag'))

# then you could
qs.delete()

# or if you need to trigger signal per item
for x in qs:
    x.delete()
于 2012-05-16T02:45:07.800 に答える
2

このタスクのパフォーマンスをさらに改善する必要があったため、okmのソリューションを少し変更しました。

    all_tag_pks = Tag.objects.values_list('pk', flat=True)
    used_tag_pks = Photo.tags.through.objects.values_list('tag', flat=True)
    Tag.objects.filter(pk__in=list(set(all_tag_pks) - set(used_tag_pks))).delete()

それによって、データベースへのクエリははるかに小さく、より速くなります。

于 2012-11-12T23:58:19.640 に答える