一、项目结构
myproject/
├── myproject/
│ ├── settings.py
│ ├── urls.py
├── users/
│ ├── models.py # 关联模型
│ ├── forms.py # 表单定义
│ ├── views.py # 视图函数
│ ├── urls.py # 子路由
│ ├── templates/
│ │ ├── register.html
│ │ ├── login.html
│ │ ├── profile.html
│ │ └── edit_profile.html
二、模型定义
# users/models.py
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(
User,
on_delete=models.CASCADE,
related_name='profile'
)
mobile = models.CharField('手机号', max_length=11, unique=True)
avatar = models.ImageField('头像', upload_to='avatars/', blank=True)
bio = models.TextField('个人简介', blank=True)
def __str__(self):
return f"{self.user.username} 的扩展资料"
三、表单定义
# users/forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import Profile
class SignupForm(UserCreationForm):
mobile = forms.CharField(max_length=11, required=True)
avatar = forms.ImageField(required=False)
class Meta(UserCreationForm.Meta):
fields = ('username', 'email', 'password1', 'password2', 'mobile')
def save(self, commit=True):
user = super().save(commit=False)
user.email = self.cleaned_data['email']
if commit:
user.save()
# 创建关联的Profile对象
Profile.objects.create(
user=user,
mobile=self.cleaned_data['mobile'],
avatar=self.cleaned_data['avatar']
)
return user
class UserEditForm(forms.ModelForm):
class Meta:
model = User
fields = ['username', 'email', 'first_name', 'last_name']
class ProfileEditForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['mobile', 'avatar', 'bio']
四、视图实现
# users/views.py
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from .forms import SignupForm, UserEditForm, ProfileEditForm
def register(request):
if request.method == 'POST':
form = SignupForm(request.POST, request.FILES)
if form.is_valid():
user = form.save()
login(request, user) # 注册后自动登录
return redirect('profile')
else:
form = SignupForm()
return render(request, 'users/register.html', {'form': form})
def user_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user:
login(request, user)
return redirect('profile')
else:
return render(request, 'users/login.html', {'error': '用户名或密码错误'})
return render(request, 'users/login.html')
@login_required
def user_logout(request):
logout(request)
return redirect('login')
@login_required
def profile(request):
return render(request, 'users/profile.html')
@login_required
def edit_profile(request):
if request.method == 'POST':
user_form = UserEditForm(request.POST, instance=request.user)
profile_form = ProfileEditForm(
request.POST,
request.FILES,
instance=request.user.profile
)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
return redirect('profile')
else:
user_form = UserEditForm(instance=request.user)
profile_form = ProfileEditForm(instance=request.user.profile)
return render(request, 'users/edit_profile.html', {
'user_form': user_form,
'profile_form': profile_form
})
五、路由配置
# myproject/urls.py
from django.contrib import admin
from django.urls import path, include
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
path('users/', include('users.urls')),
path('register/', views.register, name='register'),
path('login/', views.user_login, name='login'),
path('logout/', views.user_logout, name='logout'),
path('profile/', views.profile, name='profile'),
path('edit/', views.edit_profile, name='edit_profile'),
]
六、模板示例
<!-- users/register.html -->
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-primary">注册</button>
<p>已有账号?<a href="{% url 'login' %}">立即登录</a></p>
</form>
<!-- users/login.html -->
<form method="post">
{% csrf_token %}
<div class="form-group">
<input type="text" name="username" placeholder="用户名" required>
</div>
<div class="form-group">
<input type="password" name="password" placeholder="密码" required>
</div>
<button class="btn btn-primary">登录</button>
<p>没有账号?<a href="{% url 'register' %}">注册新用户</a></p>
</form>
<!-- users/profile.html -->
<h2>欢迎回来,{{ user.username }}</h2>
<div class="profile-info">
<img src="{{ user.profile.avatar.url }}" class="avatar">
<p>📧 邮箱:{{ user.email }}</p>
<p>📱 手机:{{ user.profile.mobile }}</p>
<p>📝 简介:{{ user.profile.bio }}</p>
</div>
<a href="{% url 'edit_profile' %}" class="btn btn-secondary">编辑资料</a>
<a href="{% url 'logout' %}" class="btn btn-danger">退出登录</a>
<!-- users/edit_profile.html -->
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-section">
<h3>基础信息</h3>
{{ user_form.as_p }}
</div>
<div class="form-section">
<h3>扩展信息</h3>
{{ profile_form.as_p }}
</div>
<button class="btn btn-success">保存修改</button>
</form>
七、关键配置
# settings.py
MEDIA_URL = '/media/' # 媒体文件访问路径
MEDIA_ROOT = BASE_DIR / 'media' # 本地存储路径
# 保持使用默认用户模型
# 无需设置 AUTH_USER_MODEL
八、数据迁移
# 生成迁移文件
python manage.py makemigrations
# 执行迁移
python manage.py migrate
# 创建测试用户
python manage.py createsuperuser
九、效果验证
- 注册流程
访问/users/register
→ 填写用户名、邮箱、密码、手机号 → 自动创建 User 和 Profile 记录 - 资料修改
登录后访问/users/profile/edit
→ 修改头像和简介 → 查看更新后的个人主页 - 管理员后台
访问/admin
→ 默认 User 管理界面不变 → 可手动添加 Profile 内联管理(可选)
十、扩展建议
-
自动创建Profile
使用 Django 信号机制:# users/signals.py from django.db.models.signals import post_save from django.dispatch import receiver from .models import Profile @receiver(post_save, sender=User) def create_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) @receiver(post_save, sender=User) def save_profile(sender, instance, **kwargs): instance.profile.save()
-
管理员界面增强
# users/admin.py from django.contrib import admin from django.contrib.auth.admin import UserAdmin from .models import Profile class ProfileInline(admin.StackedInline): model = Profile class CustomUserAdmin(UserAdmin): inlines = [ProfileInline] admin.site.unregister(User) admin.site.register(User, CustomUserAdmin)
方案优势
- 零修改默认用户模型,完全兼容 Django Admin
- 可灵活添加任意扩展字段
- 支持渐进式迭代开发
- 用户系统升级时无需复杂数据迁移