У меня возникла проблема с решением этой ошибки: не найден запрос на совпадение адреса электронной почты - PullRequest
0 голосов
/ 08 февраля 2020

Я использую пользовательского пользователя и попытался войти в систему с моей конечной точки API. Я создал собственный сериализатор, исключая поле имени пользователя, так как электронная почта является уникальным идентификатором для моей модели. В моем файле settings.py этот сериализатор настроен на сериализацию авторизационной регистрации. Я также проверил, что это письмо существует через файл администратора. Есть ли какое-то разъединение между сериализатором и моделью?

My Urls.py:

"""goal_project URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
#from django.views.generic.base import TemplateView #the generic template view for use as the homepage########was for the home page
#the imports below are for the REST implementation
from django_registration.backends.one_step.views import RegistrationView
#the custom user forms
from accounts.forms import CustomUserCreationForm
from accounts.forms import CustomUserChangeForm


urlpatterns = [
    #path to admin site
    path('admin/', admin.site.urls),

    #the path to the accounts api, runs through accounts api folder, uses UserSerializer in the appropriate view
    path("api/", include("accounts.api.urls")),

    #Login Through Browsable API
    path("api-auth/", include("rest_framework.urls")), #login is now option in API
    #Login Through REST 
    path("api/rest-auth/", include("rest_auth.urls")), 

    #Registration via rest
    path("api/rest-auth/registration/", include("rest_auth.registration.urls")), 
]

Файл My account.models:

from django.db import models
from django.contrib.auth.models import AbstractUser, BaseUserManager

#redefine the user manager for a user model with no username
class UserManager(BaseUserManager):
    use_in_migrations = True

    #helper method to create user
    def _create_user(self, email, password, **extra_fields):
        #Create and save user with the given email and password
        if not email:
            raise ValueError('The given email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self.db)
        return user

    #the method to create regular user
    def create_user(self, email, password=None, **extra_fields):
        #create and save regular user with the given email and password
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(email, password, **extra_fields)

    #method to create super user
    def create_superuser(self, email, password, **extra_fields):
        #create a super use with the given email and password
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        #verify has right credentials
        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self._create_user(email, password, **extra_fields) 

#the custom user model, no user name instead email
class CustomUser(AbstractUser):
    #no username
    username = None
    #email field is unique
    email = models.EmailField(verbose_name = 'email address', unique = True)
    #the username field is email
    USERNAME_FIELD = 'email'
    #email is now automatically required as username
    REQUIRED_FIELDS = []
    #link the new manager to the model through 'objects'
    objects = UserManager()

Пользовательская регистрация Сериализатор:

class RegisterSerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomUser
        fields = ['email', 'password']

Некоторые соответствующие настройки для django auth в settings.py:

set the custom user model
AUTH_USER_MODEL = 'accounts.CustomUser'

#for use with crispy forms
CRISPY_TEMPLATE_PACK = 'bootstrap4'

#django allauth
ACCOUNT_EMAIL_VERIFICATION = 'mandatory'
ACCOUNT_EMAIL_REQUIRED = True

#The REST FRAMEWORK DICTIONARY
REST_FRAMEWORK = { #want to authenticate with both token authentication and session authentication
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 2
}

#Django all-auth settings
#unique email
ACCOUNT_UNIQUE_EMAIL = True
#no username required for registration serializer
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
#email is required
ACCOUNT_EMAIL_REQUIRED = True
#email is required
ACCOUNT_EMAIL_REQUIRED = True
#no account usernname
ACCOUNT_USERNAME_REQUIRED = False
#authentication method is email
ACCOUNT_AUTHENTICATION_METHOD = 'email'


#the register serializer setting
REST_AUTH_REGISTER_SERIALIZERS = {'REGISTER_SERIALIZER':'accounts.api.serializers.RegisterSerializer',
}
...