1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Django】ForeignKeyのon_deleteの設定値をまとめたい

Posted at

目的

現在、作成しているサービスにて、あるテーブルのレコードを削除した際に、関連して削除されるレコードのテーブルを知りたかった。
python manage.py inspectdbon_deleteの情報も出力されるかなと思ったが、そうでもなかった。

確認環境

  • Django1.X
    • かなり古いので、コードが動かなかったらごめんなさい

コード

  • ざっくり書いているので、手直しして使用してください。。

全modelsのForeignKeyのフィールドとon_deleteを出力するカスタムコマンド

from django.core.management.base import BaseCommand
from django.db.models import get_models


class Command(BaseCommand):
    def handle(self, *args, **options):
        # 全modelsクラスを取得(Djangoが自動生成したmodels含む)
        models = get_models(include_auto_created=True)
        # models名でソートしてループ
        for model in sorted(models, key=lambda model: model._meta.db_table):
            # テーブル名取得
            table = model._meta.db_table
            # フィールド取得
            meta_fields = model._meta.fields
            # 出力
            self.stdout.write('')
            self.stdout.write('■■■ Table ■■■')
            self.stdout.write('{table}'.format(table=table))
            self.stdout.write('')
            self.stdout.write('■■■ ForeignKey Field ■■■')
            # フィールド分ループ
            for meta_field in meta_fields:
                # ForeignKeyか?
                if 'ForeignKey' in str(meta_field):
                    # フィールド名取得
                    name = meta_field.name
                    # フィールドのverbose_name取得(使ってないけど)
                    verbose_name = meta_field.verbose_name
                    # on_deleteの設定値取得
                    del_kind = str(meta_field.rel.on_delete).split(' ')[1]
                    # 出力
                    self.stdout.write('{name}:{del_kind}'.format(name=name, del_kind=del_kind))

指定したテーブルのレコードを削除した際に、関連してレコードが削除されるテーブルを出力するカスタムコマンド

# テーブル名を指定してCASCADEでレコードが削除される項目
class Command(BaseCommand):
    def handle(self, *args, **options):
        # 入力値取得(削除対象テーブル)
        delete_target_table = args[0]
        # 入力値が存在するか
        if delete_target_table:
            # 全modelsクラスを取得(Djangoが自動生成したmodels含む)
            models = get_models(include_auto_created=True)
            # models名でソートしてループ
            for model in sorted(models, key=lambda model: model._meta.db_table):
                # テーブル名取得
                table = model._meta.db_table
                # フィールド取得
                meta_fields = model._meta.fields
                # フィールド分ループ
                for meta_field in meta_fields:
                    # ForeignKeyか?
                    if 'ForeignKey' in str(meta_field):
                        # フィールド名取得
                        name = meta_field.name
                        # on_deleteの設定値取得
                        del_kind = str(meta_field.rel.on_delete).split(' ')[1]
                        # 指定したテーブル かつ on_deleteがCASCADEか?
                        if (name == delete_target_table) and (del_kind == 'CASCADE'):
                            # テーブル名出力
                            self.stdout.write(table)
                            # modelsのループに戻る
                            break
        else:
            print('削除対象のテーブルを入力してください')
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?