在DJango身份验证系统中使电子邮件地址唯一

时间:2017-12-16 01:55:42

标签: django email authorization

我需要让DJango身份验证系统的EMail字段独一无二。

我正在使用Python 3.6.3和DJango 1.11.7

为了做到这一点,我发现了这个: Making email field unique with Django User admin

在关注它时,我将以下代码添加到代表身份验证的应用程序文件夹下的__init__.py。我也尝试将其添加到项目的__init_-.py文件中。

from django.contrib.auth.models import User
User._meta.get_field("email")._unique = True

无论哪种方式,我仍然得到相同的错误(下面列出)。我该如何解决?

TIA

C:\WORK\Software\Python64bitv3.6\python.exe manage.py runserver
Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x000001F9D03BCEA0>
Traceback (most recent call last):
  File "C:\WORK\Software\Python64bitv3.6\lib\site-packages\django-1.11.7-py3.6.egg\django\utils\autoreload.py", line 228, in wrapper
    fn(*args, **kwargs)
  File "C:\WORK\Software\Python64bitv3.6\lib\site-packages\django-1.11.7-py3.6.egg\django\core\management\commands\runserver.py", line 117, in inner_run
    autoreload.raise_last_exception()
  File "C:\WORK\Software\Python64bitv3.6\lib\site-packages\django-1.11.7-py3.6.egg\django\utils\autoreload.py", line 251, in raise_last_exception
    six.reraise(*_exception)
  File "C:\WORK\Software\Python64bitv3.6\lib\site-packages\django-1.11.7-py3.6.egg\django\utils\six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "C:\WORK\Software\Python64bitv3.6\lib\site-packages\django-1.11.7-py3.6.egg\django\utils\autoreload.py", line 228, in wrapper
    fn(*args, **kwargs)
  File "C:\WORK\Software\Python64bitv3.6\lib\site-packages\django-1.11.7-py3.6.egg\django\__init__.py", line 27, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "C:\WORK\Software\Python64bitv3.6\lib\site-packages\django-1.11.7-py3.6.egg\django\apps\registry.py", line 85, in populate
    app_config = AppConfig.create(entry)
  File "C:\WORK\Software\Python64bitv3.6\lib\site-packages\django-1.11.7-py3.6.egg\django\apps\config.py", line 94, in create
    module = import_module(entry)
  File "C:\WORK\Software\Python64bitv3.6\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "C:\WORK\AppPython\ContractorsClubBackofficeCode\authorization\__init__.py", line 1, in <module>
    from django.contrib.auth.models import User
  File "C:\WORK\Software\Python64bitv3.6\lib\site-packages\django-1.11.7-py3.6.egg\django\contrib\auth\models.py", line 4, in <module>
    from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
  File "C:\WORK\Software\Python64bitv3.6\lib\site-packages\django-1.11.7-py3.6.egg\django\contrib\auth\base_user.py", line 52, in <module>
    class AbstractBaseUser(models.Model):
  File "C:\WORK\Software\Python64bitv3.6\lib\site-packages\django-1.11.7-py3.6.egg\django\db\models\base.py", line 110, in __new__
    app_config = apps.get_containing_app_config(module)
  File "C:\WORK\Software\Python64bitv3.6\lib\site-packages\django-1.11.7-py3.6.egg\django\apps\registry.py", line 247, in get_containing_app_config
    self.check_apps_ready()
  File "C:\WORK\Software\Python64bitv3.6\lib\site-packages\django-1.11.7-py3.6.egg\django\apps\registry.py", line 125, in check_apps_ready
    raise AppRegistryNotReady("Apps aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

更新

您好@solarissmoke并感谢您的投入!

我是DJango的新手 - 而且 - 我还在学习:-)我已经定义了以下内容。寻找要在数据库级别完成的检查。

forms.py

from django import forms
from django.contrib.auth.models import User
from authorization.models import UserProfileInfo, Mstrgenstate, Mstrgencountry, Mstrgenstoretype, Mstrgensalutationtype, Mstrgenbusinesstype

class UserForm (forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput())

    class Meta():
        model = User
        fields = ('username', 'email', 'password')

    def clean_email(self):
        # Get the email
        email = self.cleaned_data.get('email')

        # Check to see if any users already exist with this email as a username.
        try:
            match = User.objects.get(email=email)
        except User.DoesNotExist:
            # Unable to find a user, this is fine
            return email

        # A user was found with this as a username, raise an error.
        raise forms.ValidationError( "This email address is already in use. Please supply a different email address.")


    def clean_username(self):
        # Get the username
        username = self.cleaned_data.get('username')

        # Check to see if any users already exist with this email as a username.
        try:
            match = User.objects.get(username=username)
        except User.DoesNotExist:
            # Unable to find a user, this is fine
            return username

        # A user was found with this as a username, raise an error.
        raise forms.ValidationError("This userid is already in use. Please supply a different userid.")

class UserProfileInfoForm (forms.ModelForm):
    class Meta():
        model = UserProfileInfo
        fields = ('approle', 'profilepic')

在这里,我使用的模型称为User。在您提到的示例中,您将其命名为MyUser。我也将在下面进行更改:

FROM:

class Meta():
    model = User
    fields = ('username', 'email', 'password')

TO:

class Meta():
    model = MyUser
    fields = ('username', 'email', 'password')

右?

TIA

1 个答案:

答案 0 :(得分:3)

您链接的解决方案是7岁,绝对不再是这样做的方式。

更好的方法是使用custom user model。在您的情况下,您将覆盖email字段以使其唯一:

class MyUser(AbstractBaseUser):
    email = models.EmailField(unique=True)

如果电子邮件将成为用户的唯一标识符(即,这是他们用于登录的内容),那么您还需要设置:

USERNAME_FIELD = 'email'

在您的用户类上。

最后告诉Django在您的设置文件中使用这个新用户模型:

AUTH_USER_MODEL = 'myapp.MyUser'