Django の ManyToMany 隠しテーブルの操作方法#
作成日:2021 年 5 月 28 日午後 6 時 18 分
タグ:ORM、Python
今日、質問に遭遇しましたが、オンラインで議論されているものを検索しましたが、解決策は提案されていませんでした。その後、調査を行い、記録する価値があると判断しましたので、以下に詳細を説明します。
問題#
デフォルトの Django ユーザーの権限グループテーブル「auth_user_groups」を変更したいです。このテーブルは「User」テーブルを介して操作できます。
from django.contrib.auth.models import User
u1 = User.objects.get(id=1)
u1.groups # これが所属しているauthユーザーグループの中間テーブルです
# 以下の方法でグループを追加できます
u1.groups.add()
現在の要件は、このテーブルを直接操作し、一括データの挿入を容易にすることです。
背景#
まず、データベースでこのテーブルの構造を確認する必要があります。論理的には、Group テーブルと User テーブルの両方が外部キーフィールドのテーブルであると推測できます(Django の ManyToMany の自動作成ルールに基づく)。
mysql> desc auth_user_groups;
+----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | MUL | NULL | |
| group_id | int(11) | NO | MUL | NULL | |
+----------+---------+------+-----+---------+----------------+
予想通りですね。したがって、このテーブルを指すために手動でモデルを定義する必要があります。
解決策#
- モデルのカスタマイズ
from django.db import models as db
from django.contrib.auth.models import Group, User
class UserAuthGroup(db.Model):
user = db.ForeignKey(User, on_delete=db.CASCADE)
group = db.ForeignKey(Group, on_delete=db.CASCADE)
class Meta:
db_table = "auth_user_groups" # テーブル名を指定
これで、Python コンソールを開いてこのテーブルのデータを操作できます。
しかし、サーバーを実行すると、別のエラーが発生します。
ソースコードを調査した結果、サーバーの実行時にシステムチェックが実行され、その中にはすべてのモデルのチェックが含まれています。その中の 1 つが「fields.E340」という指標です。
中間テーブルのフィールドがテーブル名 / モデル / モデル。フィールド名と競合しています。
Django は中間テーブルを直接操作することを望んでいないようです。確かに、データの混乱が起こりやすいです。しかし、時にはいくつかのハック機能を実装する必要がある場合もあります。
- 起動エラーの解決
解決策は、このチェックをコメントアウトし、settings.py
ファイルに次の内容を追加することです。
SILENCED_SYSTEM_CHECKS = ["fields.E340"] # 複数追加できます
これで、サーバーを実行すると正常に動作し、操作できるようになります。