同じデータベースに対して複数の django サイト (サイト 1、サイト 2、サイト 3 と呼びましょう) を実行しており、サイト全体でユーザー名の重複を許可したいと考えています。サイトと認証フレームワークはこれを達成していないようです。デフォルトでは、ユーザー名は auth.User の一意のフィールドです。
だから私がこれまでにやったこと(モンキーパッチ、ユーザーオブジェクトの混乱...):
User._meta.get_field('username')._unique = False
User.add_to_class('site', models.ForeignKey(Site, default=Site.objects.get_current().id, blank=True, null=True))
User._meta.unique_together = (('username', 'site'),)
この部分は、ユーザー名の一意性を取り除き、サイト フィールドを追加し、カップル (ユーザー名、サイト) を一意にします。
次に、User.objects.get(username=xx) を要求するときに発生する可能性のある問題 (たとえば、認証バックエンド) が発生します。別のサイトで同じユーザー名を使用しているユーザーがいる場合です。そこで、User.objects マネージャーにパッチを当てることにしました。
def get_query_set(filter=True):
q = QuerySet(User.objects.model, using=User.objects._db)
if filter:
return q.filter(site = Site.objects.get_current())
return q
User.objects.get_query_set = get_query_set
これまでのところうまくいくようです。しかし...サイトはほとんど同じオブジェクトを使用しており、すべてのサイトに共通の管理インターフェースを使用してこれらのオブジェクトのユーザーフィールドを変更する可能性が高いです...したがって、オブジェクトに属性を付けたい場合( auh.User への外部キー) を site2 のユーザーに、site1 で管理者としてログインしている間、これは機能しません。ユーザー マネージャーが site=site1 でフィルタリングするためです。
私は少し掘り下げて、これがうまくいくように見えることを発見しました:
class UserDefaultManager(UserManager):
def get_query_set(self, filter=None):
return QuerySet(User.objects.model)
User._default_manager = UserDefaultManager()
私が理解している限り、_default_manager は関連オブジェクト マネージャーによって使用されます。次に、 User.objects.get(username=xx) はサイトをフィルタリングしますが、 an_object.user はしません。
ええと、質問は: はい、これは面倒です。欠陥があると確信していますが、それらはどれですか?
次の質問は、有効な場合、このコードを配置するのに最適な場所はどこですか? 現在、models.py ファイルにあり、モジュールがロードされたときに実行されました...