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"] # 複数追加できます
これで、サーバーを実行すると正常に動作し、操作できるようになります。
参考文献#
- http://c.biancheng.net/view/8001.html
- https://www.cnblogs.com/fengbo123/p/10837696.html
- https://www.pythonanywhere.com/forums/topic/14430/
- https://docs.djangoproject.com/en/3.2/ref/models/options/