Django:在使用电子邮件登录字段而不是用户名后, super 用户和用户无法登录管理和用户页面

标签 django python-3.x django-models django-admin django-2.0

我一直在寻找答案,但仍然找不到对我有用的解决方案。

我是 Django 新手。我编写了一个网络应用程序,它基本上是一个博客,作者将在其中拥有自己的网站,并且在每篇文章下都会有一个评论部分。我希望创建后 super 用户将自动成为作者之一。用户名字段不是必需的,因为作者将通过他们的名字和姓氏来识别。这就是为什么我需要他们仅使用电子邮件登录。

我使用的Django版本是2.0,我尝试尽可能使用CBV(基于类的 View )。

在使用户名无关并在登录页面中仅使用电子邮件和密码后,我在这两种情况下都无法登录: - 作为在网站登录页面上注册的用户 - 作为管理员通过管理员登录页面上的控制台命令createsuperuser注册

这是实际示例。

删除整个数据库并在网页上注册普通用户和在终端上注册 super 用户后,它们已正确保存在数据库中。用户名字段为空。

id 用户名 电子邮件 名字 姓氏 is_active is_staff is_superuser

---------- ---------- ------------------- ----- ----- ---------- ---------- ---------- ------------

1 johnsmith@gmail.com 约翰·史密斯 1 0 0

2 mysu@gmail.com Mysuper Myuser 1 1 1

但是,我无法以普通用户身份登录网站,也无法以 super 用户身份登录管理页面。

对于某些问题,是设置中的后端配置。我按照docs中写的内容进行操作,所以我的设置文件的部分是:

settings.py

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog_app',
]

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',
    # to let the superuser login
    'django.contrib.auth.middleware.RemoteUserMiddleware',
]

# Custom superuser configuration

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.RemoteUserBackend',
]

我的其他文件是:

models.py

from django.db import models
from django.urls import reverse
from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.utils.text import slugify

# Create your models here.
class UserManager(BaseUserManager):
    use_in_migrations = True

    def _create_user(self, email, password, **extra_fields):
        """
        Creates and saves a 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

    def create_user(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(email, password, **extra_fields)

    def create_superuser(self, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', 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)

class Author(AbstractUser):
    """ Author and User model """

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    username = models.CharField(max_length=40, unique=False, default='')
    email = models.EmailField(unique=True, max_length=256, verbose_name='email')
    slug = models.SlugField(unique=True, editable=False)

    def __str__(self):
        return self.name()

    def save(self, *args, **kwargs):

        slug_name = self.name()
        slug_number = 0

        while True:
            if slug_number == 0:
                pass
            else:
                slug_name = self.name() + "-" + str(slug_number)
            slug_number += 1
            if not Author.objects.filter(slug=slugify(slug_name)).exists():
                break

        self.slug = slugify(slug_name)

        super(Author, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('blog_app:author_detail', kwargs={'slug':self.slug})

    def name(self):
        """ The function for displaying the name of the author and slugs """
        return self.first_name + ' ' + self.last_name

class Article(models.Model):
    """ Article model """

    date = models.DateTimeField(auto_now_add=True, editable=False)
    date_updated = models.DateTimeField(auto_now=True, editable=False)
    title = models.CharField(max_length=256, unique=True)
    text = models.CharField(max_length=1024)
    author = models.ForeignKey(Author, null=True, blank=False, on_delete=models.SET_NULL, related_name='articles')
    slug = models.SlugField(unique=True, editable=False)

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        """ Creates slugs. If slug repeats then adds the number in the i the end
         which has not exist before. Those numbers are in the order """

        slug_name = self.title
        slug_number = 0

        while True:
            if slug_number == 0:
                pass
            else:
                slug_name = self.title + "-" + str(slug_number)
            slug_number += 1
            if not Article.objects.filter(slug=slugify(slug_name)).exists():
                break

        self.slug = slugify(slug_name)

        super(Article, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('blog_app:detail', kwargs={'slug':self.slug})

    def updates_detected(self):
        """ Checks whether updates happened. Due to microseconds calculations, it
        is impossible to check it by a regular comparison. Therefore I give the
        article a 1-minute margin. The update, which happened earlier than 1 minute
        from the creation of an article is assumed not to be an update """
        from datetime import timedelta

        d_creation = self.date.replace(tzinfo = None)
        d_update = self.date_updated.replace(tzinfo = None)
        td = timedelta(seconds = 5)

        if abs(d_update - d_creation) < td:
            return False
        else:
            return True

class Comment(models.Model):
    """ Comment model """

    date = models.DateTimeField(auto_now_add=True, editable=False)
    text = models.CharField(max_length=256)
    author = models.CharField(max_length=64)
    article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='comments', unique=True)

    def __str__(self):
        return self.date

admin.py

from django.contrib import admin
from blog_app.models import Article, Comment, Author

# Register your models here.

admin.site.register(Article)
admin.site.register(Author)
admin.site.register(Comment)

forms.py

from django import forms
from django.contrib.auth.forms import UserCreationForm
from blog_app.models import Author

class SignUpForm(UserCreationForm):
    class Meta:
        model = Author
        fields = ('first_name', 'last_name', 'email', 'password1', 'password2')

views.py

from django.shortcuts import render, redirect
from django.contrib.auth import login
from django.views.generic import (TemplateView, ListView, DetailView, CreateView,
                                    UpdateView, DeleteView)
from django.contrib.auth.views import LoginView, LogoutView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from blog_app import models
from blog_app.forms import SignUpForm


# Create your views here.

# Main pages
class IndexView(ListView):
    model = models.Article
    ordering = ['-date']
    context_object_name = 'articles'
    template_name = "blog_app/index.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['injectme'] = 'BASIC INJECTION'
        return context

class AboutMeView(TemplateView):
    template_name = "blog_app/about_me.html"

# Article views

class ArticlePageView(DetailView):
    context_object_name = 'article_detail'
    model = models.Article
    template_name = 'blog_app/article_page.html'

class CreateArticleView(LoginRequiredMixin, CreateView):
    login_url = reverse_lazy("blog_app:login")
    model = models.Article
    fields = ('title', 'text')

    def form_valid(self, form):
        author = self.request.user
        form.instance.author = author
        return super(CreateArticleView, self).form_valid(form)

class UpdateArticleView(LoginRequiredMixin, UpdateView):
    login_url = reverse_lazy("blog_app:login")
    model = models.Article
    fields = ('title', 'text')

class ArticleDeleteView(LoginRequiredMixin, DeleteView):
    login_url = reverse_lazy("blog_app:login")
    model = models.Article
    success_url = reverse_lazy("blog_app:index")

# Author/user views

class AuthorPageView(DetailView):
    context_object_name = 'author_detail'
    model = models.Author
    template_name = 'blog_app/author_page.html'

class LoginAuthorView(LoginView):
    template_name = 'blog_app/login.html'
    success_url = reverse_lazy("blog_app:index")

class LogoutAuthorView(LogoutView):
    next_page = reverse_lazy("blog_app:index")

class CreateAuthorView(CreateView):
    model = models.Author
    form_class = SignUpForm

class UpdateAuthorView(LoginRequiredMixin, UpdateView):
    login_url = reverse_lazy("blog_app:login")
    model = models.Author
    fields = ['first_name']

class AuthorDeleteView(LoginRequiredMixin, DeleteView):
    login_url = reverse_lazy("blog_app:login")
    model = models.Author
    success_url = reverse_lazy("blog_app:index")

你知道我的问题是什么吗?

最佳答案

您是否使用此处记录的AUTH_USER_MODEL设置在settings.py中注册自定义用户模型:custom user model

关于Django:在使用电子邮件登录字段而不是用户名后, super 用户和用户无法登录管理和用户页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50426047/

相关文章:

python - Django - 在模型中,created_at 是一个 UNIX 时间戳

python - 绘制非结构化三角形曲面 Python

python - '<' not supported between instances of ' str'和 'int'

python - 来自一个输入的多个输入

python - Django模型更新或创建具有唯一约束的对象

python - 我无法安装 mysqlclient

django - 您可以在模板中自动显示模型选择吗?

python - 如何解决 django 形式的查询集要求问题

django - Django 中的 unique_together 不起作用

python - Django 从数据库中获取最新条目