Django新手:如何为不同用户类型分表实现注册(替代auth_user)
Hey there! Let's walk through how to set up three separate user tables for students, instructors, and non-teaching staff instead of relying on Django's default auth_user table. Since you're new to Django, I'll keep this step-by-step and easy to follow.
1. Create Custom User Models
First, you'll define three distinct user models in your app's models.py. Each will inherit from AbstractBaseUser and PermissionsMixin—this lets you leverage Django's built-in authentication features (like password hashing and permissions) while keeping your tables separate.
Here's an example for the Student model; you can replicate this pattern for instructors and non-teaching staff, adding unique fields for each type:
from django.db import models from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin # Manager for Student model (handles user creation) class StudentManager(BaseUserManager): def create_user(self, email, username, student_id, password=None, **extra_fields): if not email: raise ValueError("Students must provide an email address") email = self.normalize_email(email) user = self.model(email=email, username=username, student_id=student_id, **extra_fields) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, email, username, student_id, password=None, **extra_fields): extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True) return self.create_user(email, username, student_id, password, **extra_fields) # Student User Model class Student(AbstractBaseUser, PermissionsMixin): username = models.CharField(max_length=150, unique=True) email = models.EmailField(max_length=255, unique=True) student_id = models.CharField(max_length=20, unique=True) # Unique to students is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) objects = StudentManager() # Set email as the login identifier (you can use username instead if preferred) USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['username', 'student_id'] def __str__(self): return f"Student: {self.username} ({self.student_id})"
Repeat this for Instructor (add fields like instructor_id, department) and NonTeachingStaff (add fields like staff_id, role).
2. Build a Custom Authentication Backend
Django's default auth system only recognizes the default auth.User model, so you need a custom backend to let it authenticate users from your three new tables. Create a backends.py file in your app:
from django.contrib.auth.backends import ModelBackend from .models import Student, Instructor, NonTeachingStaff class MultiUserBackend(ModelBackend): def authenticate(self, request, username=None, password=None, **kwargs): # Try authenticating as a Student first try: user = Student.objects.get(email=username) if user.check_password(password): return user except Student.DoesNotExist: pass # Next, try Instructor try: user = Instructor.objects.get(email=username) if user.check_password(password): return user except Instructor.DoesNotExist: pass # Finally, try NonTeachingStaff try: user = NonTeachingStaff.objects.get(email=username) if user.check_password(password): return user except NonTeachingStaff.DoesNotExist: return None def get_user(self, user_id): # Fetch user by ID across all three models try: return Student.objects.get(pk=user_id) except Student.DoesNotExist: try: return Instructor.objects.get(pk=user_id) except Instructor.DoesNotExist: try: return NonTeachingStaff.objects.get(pk=user_id) except NonTeachingStaff.DoesNotExist: return None
Then update your project's settings.py to use this backend:
AUTHENTICATION_BACKENDS = [ 'your_app_name.backends.MultiUserBackend', ]
3. Set Up Admin Interface for Custom Users
To manage these users in Django's admin panel, register each model with a custom admin class. Edit your app's admin.py:
from django.contrib import admin from django.contrib.auth.admin import UserAdmin from .models import Student, Instructor, NonTeachingStaff class StudentAdmin(UserAdmin): model = Student list_display = ['email', 'username', 'student_id', 'is_staff'] fieldsets = ( (None, {'fields': ('email', 'password')}), ('Personal Details', {'fields': ('username', 'student_id')}), ('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}), ('Important Dates', {'fields': ('last_login', 'date_joined')}), ) add_fieldsets = ( (None, { 'classes': ('wide',), 'fields': ('email', 'username', 'student_id', 'password1', 'password2'), }), ) search_fields = ['email', 'username'] ordering = ['email'] # Register Student model with its admin class admin.site.register(Student, StudentAdmin) # Repeat the above pattern for Instructor and NonTeachingStaff
4. Create Registration Forms & Views
Each user type will need its own registration flow. First, create registration forms in forms.py:
from django.contrib.auth.forms import UserCreationForm from .models import Student, Instructor, NonTeachingStaff class StudentRegistrationForm(UserCreationForm): class Meta: model = Student fields = ['username', 'email', 'student_id', 'password1', 'password2'] # Create similar forms for Instructor and NonTeachingStaff
Then build registration views in views.py:
from django.shortcuts import render, redirect from .forms import StudentRegistrationForm, InstructorRegistrationForm, NonTeachingStaffRegistrationForm def register_student(request): if request.method == 'POST': form = StudentRegistrationForm(request.POST) if form.is_valid(): form.save() return redirect('login') # Redirect to your login page else: form = StudentRegistrationForm() return render(request, 'auth/register_student.html', {'form': form}) # Add views for register_instructor and register_non_teaching_staff
Finally, map these views to URLs in your app's urls.py:
from django.urls import path from . import views urlpatterns = [ path('register/student/', views.register_student, name='register_student'), path('register/instructor/', views.register_instructor, name='register_instructor'), path('register/non-teaching/', views.register_non_teaching_staff, name='register_non_teaching'), # Add your login URL here if you're using Django's default login view ]
Key Notes to Remember
- Run Migrations: After defining your models, run
python manage.py makemigrationsfollowed bypython manage.py migrateto create the new database tables. - Login Flow: Django's default
LoginViewwill work with your custom backend as long as users log in with the field you set asUSERNAME_FIELD(email in our example). - Separation: Each user table is completely independent—users can't exist in multiple tables (if you need role-based access instead of separate tables, this approach isn't ideal, but it fits your requirement perfectly).
Hope this gives you a solid foundation to build on! If you hit snags with migrations, admin setup, or anything else, feel free to ask for more specifics.
内容的提问来源于stack exchange,提问作者Krishna

