Djangoのcontrib.authのモデルUserでメールフィールドを一意にする方法 質問する

Djangoのcontrib.authのモデルUserでメールフィールドを一意にする方法 質問する

contrib.auth電子メール フィールドのエントリが一意であることを確認することで、標準のユーザー モデルにパッチを適用する必要があります。

User._meta.fields[4].unique = True

コード内でこれを実行するのに最適な場所はどこですか?

番号の使用を避けたいフィールド[4]. 使用することをお勧めしますフィールド['メール']、 しかし田畑辞書ではなく、リストのみです。

別のアイデアとしては、新しいチケットを開いて、新しいパラメータを含むパッチをアップロードすることですsettings.py

AUTH_USER_EMAIL_UNIQUE = True

Django ユーザー モデルで電子メール アドレスの一意性を実現するための最も正しい方法について何か提案はありますか?

ベストアンサー1

注意:以下のコードは、Djangoの古いバージョン(カスタムユーザーモデルが導入されました)。これには競合状態が含まれており、トランザクション分離レベルが でSERIALIZABLE、リクエスト スコープのトランザクションでのみ使用する必要があります。

フィールド インスタンスの属性は読み取り専用であるため、コードは機能しません。考えているよりも少し複雑になるのではないかと心配しています。

フォームを使用して User インスタンスのみを作成する場合は、この動作を強制するカスタム ModelForm を定義できます。

from django import forms
from django.contrib.auth.models import User

class UserForm(forms.ModelForm):
    class Meta:
        model = User

    def clean_email(self):
        email = self.cleaned_data.get('email')
        username = self.cleaned_data.get('username')
        if email and User.objects.filter(email=email).exclude(username=username).exists():
            raise forms.ValidationError(u'Email addresses must be unique.')
        return email

その後、新しいユーザーを作成する必要があるときはいつでもこのフォームを使用します。

ちなみに、位置ではなく名前でフィールドを取得するために を使用できますModel._meta.get_field('field_name')。たとえば、次のようになります。

# The following lines are equivalent
User._meta.fields[4]
User._meta.get_field('email')

アップデート

Django のドキュメントでは、clean複数のフォーム フィールドにまたがるすべての検証に メソッドを使用することを推奨しています。これは、 メソッドがすべての メソッド<FIELD>.cleanとメソッドの後に呼び出されるためです。つまり、内から<FIELD>_cleanフィールドの値が に存在することを (ほとんどの場合) 信頼できます。cleaned_dataclean

フォーム フィールドは宣言された順序で検証されるため、<FIELD>_clean問題のフィールドが依存する他のすべてのフィールドよりも後に表示される限り、メソッドに複数フィールドの検証を配置することは問題ないと思います。検証エラーがフォームではなくフィールド自体に関連付けられるようにするため、これを行います。

おすすめ記事