Django新手求教:如何使用自定义数据表实现用户认证?
Hey there! Let's walk through how to fix this custom user authentication issue in Django—since you're using PostgreSQL, these steps will work seamlessly with your backend.
The core problem here is that Django's built-in authenticate method defaults to using the auth_user table because it relies on Django's default User model. To make it use your custom register table, we need to integrate your model with Django's authentication system properly. Here's how to do it step by step:
Your current register model is a basic Django Model, but it doesn't include the fields and methods Django's authentication system needs. We'll modify it to inherit from AbstractBaseUser and PermissionsMixin—these base classes provide all the core auth functionality like password hashing, session management, and permissions.
Update your models.py:
from django.db import models from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin # First, create a custom user manager (required for custom auth models) class CustomUserManager(BaseUserManager): def create_user(self, username, mob, password=None): if not username: raise ValueError("Username is required!") # Create a user instance user = self.model( username=username, mob=mob, ) # Let Django handle password hashing (more reliable than manual hashing) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, username, mob, password): user = self.create_user(username, mob, password) # Add superuser permissions user.is_staff = True user.is_superuser = True user.save(using=self._db) return user # Now update your register model (renamed to Register for Python style conventions) class Register(AbstractBaseUser, PermissionsMixin): username = models.CharField(max_length=50, unique=True) # Ensure usernames are unique mob = models.BigIntegerField() # Auth required fields (Django needs these to manage user state) is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) # Tell Django which field to use for login USERNAME_FIELD = 'username' # Fields required when creating a user (other than username/password) REQUIRED_FIELDS = ['mob'] # Attach our custom manager objects = CustomUserManager() def __str__(self): return self.username # Required permission methods for Django's auth system def has_perm(self, perm, obj=None): return self.is_superuser def has_module_perms(self, app_label): return self.is_superuser
Add this line to your settings.py—this tells Django's entire auth system to use your Register model instead of the default auth_user table:
AUTH_USER_MODEL = 'your_app_name.Register' # Replace 'your_app_name' with your actual app name (e.g., 'accounts.Register')
Important Note: This setting should be configured early in your project. If you already have existing migrations, you'll need to either reset your database (backup data first!) or fix migration history. For beginners, resetting the database and running fresh migrations is the simplest path.
Now apply your model changes to PostgreSQL:
python manage.py makemigrations python manage.py migrate
Your existing views need small tweaks to work with the custom model, and we'll fix the loginuser view to handle GET requests (it currently throws an error if someone loads the page via GET):
Update your views.py:
from django.shortcuts import render, redirect from django.contrib import auth def registeruser(request): if request.method == 'POST': username = request.POST['username'] mob = request.POST['mob'] password = request.POST['password1'] password2 = request.POST['password2'] # Add password match check if password != password2: return render(request, "home.html", {'error': "Passwords don't match!"}) # Use our custom manager to create the user (handles password hashing automatically) user = auth.get_user_model().objects.create_user(username=username, mob=mob, password=password) user.save() return render(request, "home.html") else: return render(request, "home.html") def loginuser(request): if request.method == 'POST': usern = request.POST['username'] passw = request.POST['password'] # Now authenticate will automatically use your custom Register model user = auth.authenticate(request, username=usern, password=passw) if user is not None: auth.login(request, user) return redirect("/") else: return render(request, 'userpage.html', {'error': 'Invalid username or password', 'username': usern}) # Handle GET requests (load the login page) else: return render(request, 'userpage.html')
- Always use
auth.get_user_model()instead of directly importing your custom model—it makes your code more maintainable if you ever change the user model later. - The
USERNAME_FIELDmust be unique, as Django uses it to identify users during authentication. - The custom user manager is mandatory—Django needs it to create users and superusers correctly.
内容的提问来源于stack exchange,提问作者Vishnu Chithan

