我正在制作我的第一个应用程序,它是一个待办事项列表应用程序。我正在尝试让用户使用电子邮件注册并使用它登录。
这是调试向我显示的错误:
ProgrammingError at /register/
no existe la relación «core_user»
LINE 1: SELECT 1 AS "a" FROM "core_user" WHERE "core_user"."email" =...
^
Request Method: POST
Request URL: http://127.0.0.1:8000/register/
Django Version: 5.0.2
Exception Type: ProgrammingError
Exception Value:
no existe la relación «core_user»
LINE 1: SELECT 1 AS "a" FROM "core_user" WHERE "core_user"."email" =...
我的文件具有以下配置
模型.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
email = models.EmailField(unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
class Task(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
description = models.TextField()
complete = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
class Meta:
ordering = ['complete']
views.py
from django.shortcuts import render, redirect
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView, FormView
from django.urls import reverse_lazy
from django.contrib.auth.views import LoginView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth import login
from .models import Task
from .forms import LoginForm, RegisterForm
class CustomLoginView(LoginView):
template_name = 'core/login.html'
form_class = LoginForm
redirect_authenticated_user = True
def get_success_url(self):
return reverse_lazy('task_list')
class RegisterPage(FormView):
template_name = 'core/register.html'
form_class = RegisterForm
redirect_authenticated_user = True
success_url = reverse_lazy('task_list')
def form_valid(self, form):
user = form.save()
if user is not None:
login(self.request, user)
return super(RegisterPage, self).form_valid(form)
def get(self, *args, **kwargs):
if self.request.user.is_authenticated:
return redirect('task_list')
return super(RegisterPage, self).get(*args, **kwargs)
class TaskList(LoginRequiredMixin, ListView):
model = Task
template_name = 'core/index.html'
context_object_name = 'task_list'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['task_list'] = context['task_list'].filter(user=self.request.user)
context['count'] = context['task_list'].filter(complete=False).count()
search_input = self.request.GET.get('search-area') or ''
if search_input:
context['task_list'] = context['task_list'].filter(title__startswith=search_input)
context['search_input'] = search_input
return context
class TaskDetail(LoginRequiredMixin, DetailView):
model = Task
template_name = 'core/task_detail.html'
context_object_name = 'task'
class TaskCreate(LoginRequiredMixin, CreateView):
model = Task
template_name = 'core/task_form.html'
fields = ['title', 'description', 'complete']
success_url = reverse_lazy('task_list')
def form_valid(self, form):
form.instance.user = self.request.user
return super(TaskCreate, self).form_valid(form)
class TaskUpdate(LoginRequiredMixin, UpdateView):
model = Task
fields = ['title', 'description', 'complete']
success_url = reverse_lazy('task_list')
class TaskDelete(LoginRequiredMixin, DeleteView):
model = Task
context_object_name = 'task'
success_url = reverse_lazy('task_list')
表格.py
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth import get_user_model
from django import forms
class RegisterForm(UserCreationForm):
class Meta:
model = get_user_model()
fields = ('email', 'password1', 'password2')
class LoginForm(AuthenticationForm):
username = forms.CharField(label='Email')
def clean(self):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
# Verificar si el nombre de usuario es un correo electrónico
if '@' in username:
kwargs = {'email': username}
# Asignar los datos limpios validados al formulario
self.cleaned_data['username'] = username
self.cleaned_data['password'] = password
return super().clean()
后端.py
from django.contrib.auth.hashers import check_password
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model
from django.db.models import Q
UserModel = get_user_model()
class EmailBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
try:
user = UserModel.objects.get(Q(username__iexact=username) | Q(email__iexact=username))
except UserModel.DoesNotExist:
return None
except UserModel.MultipleObjectsReturned:
# Podrías manejar este caso de manera más específica si es necesario
user = UserModel.objects.filter(Q(username__iexact=username) | Q(email__iexact=username)).order_by('id').first()
if user and check_password(password, user.password):
return user
else:
return None
设置.py
"""
Django settings for todolist_project project.
Generated by 'django-admin startproject' using Django 5.0.2.
For more information on this file, see
https://docs.djangoproject.com/en/5.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.0/ref/settings/
"""
from pathlib import Path
from decouple import config
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-0blmoc@*qb)vl*b++oj$akhq!3@s^dhbq3u89nt3ap(%0%thd9'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
AUTHENTICATION_BACKENDS = [
'core.backends.EmailBackend', # Personalización para permitir inicio de sesión con email
]
# Personalización de la autenticación para permitir inicio de sesión con email
AUTH_USER_MODEL = 'core.User'
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'core.apps.CoreConfig',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'todolist_project.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'todolist_project.wsgi.application'
# Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': config('DB_NAME'),
'USER': config('DB_USER'),
'PASSWORD': config('DB_PASSWORD'),
'HOST': config('DB_HOST'),
'PORT': config('DB_PORT'),
}
}
# Password validation
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
AUTHENTICATION_BACKENDS = [
'core.backends.EmailBackend', # Personalización para permitir inicio de sesión con email
]
# Personalización de la autenticación para permitir inicio de sesión con email
AUTH_USER_MODEL = 'core.User'
# Internationalization
# https://docs.djangoproject.com/en/5.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
LOGIN_URL = 'login'
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.0/howto/static-files/
STATIC_URL = '/static/'
# Default primary key field type
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
我希望能够正确登录和注册,而无需使用用户名、电子邮件和密码。
在您的情况下,由于您已经覆盖了使用电子邮件作为用户名的默认行为,因此您应该在 REQUIRED_FIELDS 列表中包含“电子邮件”而不是“用户名”。
class User(AbstractUser):
email = models.EmailField(unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['email']