2017-08-08 57 views
0

我有一個Django應用程序,我一直在努力,並且我終於得到了一致的註冊工作。但是,對於登錄頁面,我只能使用管理員帳戶登錄。我嘗試使用我自己的登錄view以及使用django.contrib.auth.views.login視圖。當我嘗試使用我在應用程序中註冊的用戶之一進行登錄時,它說用戶名或密碼不正確,這是不正確的。無法使用Django表單登錄

我使用的是自定義的用戶模型,如下所示:

models.py:

# from https://medium.com/@ramykhuffash/33e47976b517 
class UserManager(BaseUserManager): 
    """ 
    A custom user manager to deal with emails as unique identifiers for auth 
    instead of usernames. The default that's used is "UserManager" 
    """ 
    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 Email must be set') 
     email = self.normalize_email(email) 
     user = self.model(email=email, **extra_fields) 
     user.set_password(password) 
     user.save() 
     return user 

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


class User(AbstractBaseUser, PermissionsMixin): 
    email = models.EmailField(unique=True, null=True) 
    is_staff = models.BooleanField(
     _('staff status'), 
     default=False, 
     help_text=_('Designates whether the user can log into this site.'), 
    ) 
    is_active = models.BooleanField(
     _('active'), 
     default=True, 
     help_text=_(
      'Designates whether this user should be treated as active. ' 
      'Unselect this instead of deleting accounts.' 
     ), 
    ) 
    USERNAME_FIELD = 'email' 
    objects = UserManager() 

    def __str__(self): 
     return self.email 

    def get_full_name(self): 
     return self.email 

    def get_short_name(self): 
     return self.email 

    def email_user(self, subject, message, from_email=None, **kwargs): 
     send_mail(subject, message, from_email, [self.email], **kwargs) 

下面是代碼,我服了網頁:

urls.py :

from django.conf.urls import url 
from django.contrib.auth.views import logout, login 

from myprojectimport views 

urlpatterns = [ 
    url(r'^signup$', views.signup, name='signup'), 
    url(r'^login$', login, {'template_name': 'login.html'}), 
    url(r'^logout$', views.logout, name='logout'), 
    url(r'^do-logout$', logout, {'next_page': 'login'}, name='do-logout') 
] 

這是我的看法。

views.py:

def signup(request): 
    if request.user.is_authenticated(): 
     print 'authenticated!' 
     return redirect('resident_list') 
    if request.method == 'POST': 
     print 'request is POST' 
     form = SignUpForm(request.POST) 

     if form.is_valid(): 
      print 'form is valid' 
      print form 
      email = form.cleaned_data['email'] 

      user = form.save(commit=False) 
      user.is_active = False 
      user.username = email 
      user.save() 

      profile = Profile(user=user, email_confirmed=False) 

      profile.save() 

      current_site = get_current_site(request) 

      subject = 'Activate Your Account' 
      message = render_to_string('email/account_activation_email.html', { 
       'user': user, 
       'domain': current_site.domain, 
       'uid': urlsafe_base64_encode(force_bytes(user.pk)), 
       'token': account_activation_token.make_token(user), 
      }) 
      user.email_user(subject, message) 
      print 'sent email to ' + str(user) 
      return redirect('activation_sent') 
     else: 
      print 'form is not valid' 
      print form 
      print form.data['first_name'] 
      print form.data['last_name'] 
      print form.data['email'] 
    else: 
     form = SignUpForm() 

    print 'returning the sign up page' 
    return render(request, 'signup.html', {'form': form}) 

def activation_sent(request): 
    return render(request, 'activation_sent.html') 

def login(request): 
    if request.user.is_authenticated(): 
     print 'authenticated!' 
     return redirect('resident_list') 
    else: 
     print 'user is not authenticated' 
     print request.method 
     if request.method == 'POST': 
      print 'request posted' 
      form = LoginForm(request.POST) 
      print form.errors 
      if form.is_valid(): 
       print 'form is valid' 
       form_user = form.save(commit=False) 
       username = form.cleaned_data['username'] 
       user = User.objects.get_by_natural_key(username) 

       django.contrib.auth.login(request, user) 
       return redirect('resident_list') 
      else: 
       print 'form is not valid' 
       print 'errors are ' + form.errors 
       return render(request, 'login.html', {'form': form}) 
     else: 
      print 'didn\'t even post any data... was this a GET??' 
      form = LoginForm() 
      return render(request, 'login.html', {'form': form}) 


def logout(request): 
    if request.method == 'POST': 
     return redirect('do-logout') 
    return render(request, 'logout.html') 

這裏是我的形式....

forms.py:

class Email(forms.EmailField): 
    def clean(self, value): 
     super(Email, self).clean(value) 
     try: 
      User.objects.get(email=value) 
      print 'user already exists' 
      raise forms.ValidationError(
       "This email is already registered. Use the 'forgot password' link on the login page") 
     except User.DoesNotExist: 
      return value 



class SignUpForm(UserCreationForm): 
    def __init__(self, *args, **kwargs): 
     super(SignUpForm, self).__init__(*args, **kwargs) 
     self.fields.pop('password2') 
     print self.fields 

    email = Email(label="Email", widget=forms.TextInput(
     attrs={ 
      'class': 'form-control', 
      'placeholder': 'Email', 
     })) 

    first_name = forms.CharField(label="First name", widget=forms.TextInput(
     attrs={ 
      'class': 'form-control', 
      'placeholder': 'First Name', 
     })) 
    last_name = forms.CharField(widget=forms.TextInput(
     attrs={ 
      'class': 'form-control', 
      'placeholder': 'Last Name', 
     })) 

    password1 = forms.CharField(widget=forms.TextInput(
     attrs={ 
      'type': 'password', 
      'class': 'form-control', 
      'placeholder': 'Password' 
     })) 

    agrees_to_legal = forms.BooleanField() 

    class Meta: 
     model = User 
     fields = ("first_name", "last_name", "email", "password1") 


class LoginForm(forms.ModelForm): 

    username = forms.CharField(label="Username", widget=forms.TextInput(
     attrs={ 
      'class': 'form-control', 
      'placeholder': 'Email', 
     })) 

    password = forms.CharField(widget=forms.TextInput(
     attrs={ 
      'type': 'password', 
      'class': 'form-control', 
      'placeholder': 'Password' 
     })) 

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

我的HTML模板只是下降的表單元素,我認爲這發佈這些內容太多了。

當我從註冊頁面發佈POST時,它會嘗試發送一封電子郵件(另一個單獨的問題),但在Django管理面板中創建新的User。但是當我去/login並嘗試用新用戶登錄時,我無法做到這一點。我在這裏錯過了什麼嗎?

+0

你在設置中設置了'AUTH_USER_MODEL'作爲自己的自定義模型'User'? –

+0

是的,我甚至在這裏嘗試[this](https://stackoverflow.com/a/37332393/1822214)解決方案,它仍然無法正常工作。 –

+0

嘗試從django.contrib.auth import get_user_model中打印此方法的值。 –

回答

0

我有相同的自定義用戶設置爲你做什麼,我使用驗證,並在用戶登錄的過程是:

from django.contrib.auth import authenticate, login 

@require_POST 
def login_form(request): 
    user = authenticate(email=request.POST.get("email"), password=request.POST.get("password")) 
    if user is not None: 
     login(request, user) 
    else: 
     return WRONG USER OR PASS 
0

我想在你的urls.py您致電django auth login,而不是你的登錄方法您的應用程序
url(r'^login$', login, {'template_name': 'login.html'}),應該
url(r'^login$', views.login, {'template_name': 'login.html'}),