Tęskniłem za tym problemem tak długo i skończyłem eksperymentować. Jestem nowicjuszem w Django.

Używam niestandardowego modelu użytkownika, ale z jakiegoś powodu ten formularz rejestracyjny nie działa prawidłowo. Nie mogę się zalogować za pomocą logowania metody (), choć jest w porządku. Ponadto formularz logowania nie pozwala na żaden inny użytkownik logowania innego niż superużytkownik.

Oto błąd:

AttributeError at /register/
'AnonymousUser' object has no attribute '_meta'
Request Method: POST
Request URL:    http://127.0.0.1:8000/register/
Django Version: 2.2.4
Exception Type: AttributeError
Exception Value:    
'AnonymousUser' object has no attribute '_meta'
Exception Location: C:\Users\hello\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\utils\functional.py in inner, line 257
Python Executable:  C:\Users\hello\AppData\Local\Programs\Python\Python37-32\python.exe
Python Version: 3.7.4

Śledzenie:

File "C:\Users\hello\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\exception.py" in inner
  34.             response = get_response(request)
File "C:\Users\hello\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  115.                 response = self.process_exception_by_middleware(e, request)
File "C:\Users\hello\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\hello\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\views\generic\base.py" in view
  71.             return self.dispatch(request, *args, **kwargs)
File "C:\Users\hello\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\views\generic\base.py" in dispatch
  97.         return handler(request, *args, **kwargs)
File "D:\authen\authentica\views.py" in post
  40.                 login(request, user)
File "C:\Users\hello\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\contrib\auth\__init__.py" in login
  126.     request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
File "C:\Users\hello\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\utils\functional.py" in inner
  257.         return func(self._wrapped, *args)

Exception Type: AttributeError at /register/
Exception Value: 'AnonymousUser' object has no attribute '_meta'

Oto kod:

Models.py

from django.db import models
from django.conf import settings
from django.contrib.auth import get_user_model 
from django.forms import ModelForm
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin

class CustomUserManager(BaseUserManager):
    use_in_migrations = True   
    def create_user(self, email, name ,password=None,is_active= True, is_staff=False, is_admin=False):
        if not name:
            raise ValueError("Users must've a name")
        if not email:
            raise ValueError("Users must've a email")
        if not password:
            raise ValueError("User must've a password")
        user_obj= self.model(
            email=self.normalize_email(email) ,
            name= name
        )
        user_obj.set_password(password)    # Change password for the User
        user_obj.staff= is_staff
        user_obj.admin= is_admin
        user_obj.active= is_active
        user_obj.save(using =self._db)
        return user_obj 

    def create_staffuser(self,email, name ,password=None):
        user= self.create_user(
            email,
            name,
            password=password,
            is_staff= True
        )
        return user

    def create_superuser(self,email, name ,password=None, **extra_fields):
        extra_fields.setdefault('is_superuser', True)
        user = self.create_user(
            email,
            name,
            password=password,
        )
        user.staff = True
        user.admin = True
        user.save(using=self._db)
        return user

class CustomUser(AbstractBaseUser, PermissionsMixin):
    name    = models.CharField(max_length=255)
    email   = models.CharField(max_length=254, unique=True)
    active  = models.BooleanField(default= True)
    staff   = models.BooleanField(default= False)
    admin   = models.BooleanField(default= False)
    timestamp= models.DateTimeField(auto_now_add=True)
    USERNAME_FIELD  ='email'
    REQUIRED_FIELDS= []

    objects= CustomUserManager()

    def __str__(self):
        return self.email

    def get_full_name(self):
        return self.email, self.name

    def has_perm(self, perm, obj=None):
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        # Simplest possible answer: Yes, always
        return True

    @property
    def is_staff(self):
        return self.staff

    @property
    def is_admin(self):
        return self.admin

    @property
    def is_active(self):
        return self.active

Views.py

class RegisterView(TemplateView):
    template_name= 'authentica/register.html'
    def get(self, request):
        user= request.user
        if user.is_authenticated:
            return redirect('home')
        else:
            form = RegisterForm()
            return render(request, self.template_name, {'form': form})

    def post(self, request):
        if request.POST:
            form = RegisterForm(request.POST)
            if form.is_valid():
                form.save()
                email = form.cleaned_data.get('email')
                password = form.cleaned_data.get('password')
                user = authenticate(email=email ,password=password) #django built in authentication
                login(request, user)
                return redirect('home') 
        else:
            form = RegisterForm()
        return render(request, self.template_name, {'form': form})

Forms.py

class RegisterForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
password2 = forms.CharField(label='Confirm password', widget=forms.PasswordInput)

class Meta:
    model = CustomUser
    fields = ('email', 'name')

# def clean_name(self):
#     name= self.cleaned_data.get('name')
#     qs= CustomUser.objects.get('name')
#     if qs.exists():
#         raise forms.ValidationError('Name is taken')
#     return name

def clean_email(self):
    email = self.cleaned_data.get('email')
    qs = CustomUser.objects.filter(email=email)
    if qs.exists():
        raise forms.ValidationError("email is taken")
    return email

def clean_password2(self):
    # Check that the two password entries match
    password1 = self.cleaned_data.get("password1")
    password2 = self.cleaned_data.get("password2")
    if password1 and password2 and password1 != password2:
        raise forms.ValidationError("Passwords don't match")
    return password2
0
cyberhawk 10 styczeń 2020, 18:40

1 odpowiedź

Najlepsza odpowiedź

Nie zapisujesz hasła dla użytkownika. Twój niestandardowy RegisterForm jest ModelForm dla CustomUser, który oszczędza tylko pola email i name.

Więc kiedy jesteś swoim użytkownikiem, to nie powiedzie się i zwraca None.

Następnym krokiem jest login() Użytkownik, który jest None i wytwarza błąd, który widzisz.

Dziedziczyć z django.contrib.auth.forms.UserCreationForm zamiast ModelForm. To oszczędzą Ci dużo kodu (np. Nie musisz definiować pola password1 i password2, ani clean_password2) i poprawnie zapisz użytkownika.

0
dirkgroten 10 styczeń 2020, 16:26