Django用户名密码验证实现求助(附models.py代码)
Hey there! Let's walk through how to build proper username-password authentication in Django using your existing models. First up, a critical security note: storing passwords as plain text (like your current password field) is a major risk—we’ll fix that right away.
Django has built-in tools for password hashing, so let’s adjust your model to store hashed passwords instead of plain text. You’ve got two solid options:
Option A: Tweak Your Existing Model (Quick Fix)
If you want to keep your current model structure, update it to include password hashing methods:
from django.contrib.auth.hashers import make_password, check_password from django.db import models import datetime class UserInfo(models.Model): username = models.CharField(max_length=150, unique=True) # Add unique to prevent duplicate usernames password = models.CharField(max_length=255) # Hashed passwords are longer—increase max length created_at = models.DateTimeField(default=datetime.now, blank=True) verified = models.BooleanField(default=False) # Use False instead of 0 for clearer boolean logic def __str__(self): return self.username def set_password(self, raw_password): # Hash the password before saving it to the database self.password = make_password(raw_password) def check_password(self, raw_password): # Verify a raw password against the stored hash return check_password(raw_password, self.password)
Option B: Use Django’s Built-In User System (Recommended)
Django’s built-in auth system handles password hashing, sessions, permissions, and more out of the box. Extend AbstractUser to add your custom fields:
from django.contrib.auth.models import AbstractUser from django.db import models import datetime class UserInfo(AbstractUser): verified = models.BooleanField(default=False) created_at = models.DateTimeField(default=datetime.now, blank=True) def __str__(self): return self.username
Then add this line to your settings.py to tell Django to use your custom user model:
AUTH_USER_MODEL = 'your_app_name.UserInfo'
(Replace your_app_name with the actual name of your Django app.)
Next, let’s create a flow for users to sign up, with password confirmation and hashing.
Create a Registration Form
Make a forms.py file in your app to handle input validation:
from django import forms from .models import UserInfo class UserRegistrationForm(forms.ModelForm): password = forms.CharField(widget=forms.PasswordInput) confirm_password = forms.CharField(widget=forms.PasswordInput) class Meta: model = UserInfo fields = ['username'] # We'll handle password separately def clean(self): cleaned_data = super().clean() password = cleaned_data.get('password') confirm_password = cleaned_data.get('confirm_password') if password != confirm_password: raise forms.ValidationError("Passwords don't match!") return cleaned_data
Registration View
Add this to your views.py to process the form and create a user:
from django.shortcuts import render, redirect from .forms import UserRegistrationForm from django.contrib import messages def register(request): if request.method == 'POST': form = UserRegistrationForm(request.POST) if form.is_valid(): user = form.save(commit=False) # Hash the password (skip this if using Option B—Django handles it automatically) user.set_password(form.cleaned_data['password']) user.save() messages.success(request, "Registration successful! Please log in.") return redirect('login') else: form = UserRegistrationForm() return render(request, 'register.html', {'form': form})
Now let’s build the login flow to verify users’ credentials.
Login View
Add this to views.py:
from django.shortcuts import render, redirect from .models import UserInfo from django.contrib import messages # If using Option B, replace the above with: # from django.contrib.auth import authenticate, login def user_login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') # Option A: Using your custom UserInfo model try: user = UserInfo.objects.get(username=username) if user.check_password(password): # Store user ID in session to keep them logged in request.session['user_id'] = user.id messages.success(request, "Welcome back!") return redirect('home') # Redirect to your main page else: messages.error(request, "Invalid username or password") except UserInfo.DoesNotExist: messages.error(request, "Invalid username or password") # Option B: Using Django's built-in auth (uncomment this if you went with Option B) # user = authenticate(request, username=username, password=password) # if user is not None: # login(request, user) # messages.success(request, "Welcome back!") # return redirect('home') # else: # messages.error(request, "Invalid username or password") return render(request, 'login.html')
Login Template (login.html)
Create a simple template for the login form:
<!DOCTYPE html> <html> <head> <title>Login</title> </head> <body> <h2>Login</h2> {% if messages %} {% for message in messages %} <div style="color: {% if message.tags == 'success' %}green{% else %}red{% endif %};"> {{ message }} </div> {% endfor %} {% endif %} <form method="post"> {% csrf_token %} <div> <label>Username:</label> <input type="text" name="username" required> </div> <div> <label>Password:</label> <input type="password" name="password" required> </div> <button type="submit">Log In</button> </form> </body> </html>
If you want to restrict certain pages to logged-in users, add a login check.
For Option A (Custom Model)
Create a decorator in views.py:
from django.shortcuts import redirect, get_object_or_404 from .models import UserInfo def login_required(view_func): def wrapper(request, *args, **kwargs): if 'user_id' not in request.session: messages.error(request, "Please log in first!") return redirect('login') # Attach the user object to the request for easy access request.user = get_object_or_404(UserInfo, id=request.session['user_id']) return view_func(request, *args, **kwargs) return wrapper
Use it on your views like this:
@login_required def home(request): return render(request, 'home.html', {'user': request.user})
For Option B (Built-In Auth)
Use Django’s pre-made login_required decorator:
from django.contrib.auth.decorators import login_required @login_required def home(request): return render(request, 'home.html', {'user': request.user})
- Never store plain text passwords: Always use Django’s hashing tools—never write your own password logic.
- CSRF protection: Always include
{% csrf_token %}in your forms to block cross-site request forgery attacks. - Unique usernames: The
unique=Trueon the username field prevents duplicate accounts. - Email verification: Your
verifiedfield can be used to implement email confirmation—add anemailfield toUserInfo, send a verification link, and markverified=Truewhen the user clicks it.
内容的提问来源于stack exchange,提问作者user20

