You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中实现客户与企业两类不同用户的独立注册功能?

Django 双角色用户差异化注册实现方案

第一步:扩展用户模型,区分角色并拆分差异化属性

修改现有models.py文件,新增角色字段标识用户类型,差异化属性通过一对一关联的专属表存储,避免主表冗余:

# models.py 完整修改后代码
from django.db import models
from django.contrib.auth.base_user import BaseUserManager
from django.contrib.auth.models import AbstractUser
from django.utils.translation import gettext_lazy as _
from rest_framework.authtoken.models import Token
from django.db.models.signals import post_save
from django.conf import settings
from django.dispatch import receiver

class UserManager(BaseUserManager):
    use_in_migrations = True

    def _create_user(self, email, password, **extra_fields):
        if not email:
            raise ValueError('The given email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email, password=None, is_staff=False, is_superuser=False, **extra_fields):
        extra_fields.setdefault('is_staff', is_staff)
        extra_fields.setdefault('is_superuser', is_superuser)
        return self._create_user(email, password, **extra_fields)


class User(AbstractUser):
    # 角色类型选项
    USER_TYPE_CHOICES = (
        ('customer', '个人客户'),
        ('company', '企业用户'),
    )
    username = None
    last_name = None
    first_name = None
    name = models.CharField(max_length=100)
    email = models.EmailField(_('email address'), unique=True)
    contact = models.CharField(max_length=100)
    # 新增角色字段,标识用户类型
    user_type = models.CharField(max_length=20, choices=USER_TYPE_CHOICES, default='customer')

    # 建议修改为邮箱作为登录凭证,原id作为登录字段不符合常规使用习惯,需保留原逻辑可改回'id'
    USERNAME_FIELD = 'email' 
    REQUIRED_FIELDS = ['contact', 'name']

    objects = UserManager() 

# 个人客户独有属性表
class CustomerProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='customer_profile')
    # 以下为示例属性,可按需修改
    age = models.IntegerField(blank=True, null=True, verbose_name='年龄')
    delivery_address = models.CharField(max_length=200, blank=True, verbose_name='收货地址')

# 企业用户独有属性表
class CompanyProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='company_profile')
    # 以下为示例属性,可按需修改
    business_license = models.CharField(max_length=100, verbose_name='统一社会信用代码')
    company_address = models.CharField(max_length=200, verbose_name='企业地址')
    business_scope = models.TextField(blank=True, verbose_name='经营范围')

@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)

修改完成后执行python manage.py makemigrations和python manage.py migrate同步数据库结构。

第二步:编写两类用户的注册表单

新建forms.py文件,分别定义两个注册表单,控制需要用户填写的字段和校验规则:

# forms.py
from django import forms
from .models import User, CustomerProfile, CompanyProfile

# 个人客户注册表单
class CustomerRegisterForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput, label='登录密码')
    confirm_password = forms.CharField(widget=forms.PasswordInput, label='确认密码')

    class Meta:
        model = User
        fields = ['name', 'email', 'contact', 'password']
    
    # 校验两次密码一致性
    def clean_confirm_password(self):
        password = self.cleaned_data.get('password')
        confirm_password = self.cleaned_data.get('confirm_password')
        if password and confirm_password and password != confirm_password:
            raise forms.ValidationError("两次输入的密码不一致")
        return confirm_password

class CustomerProfileForm(forms.ModelForm):
    class Meta:
        model = CustomerProfile
        fields = ['age', 'delivery_address']

# 企业用户注册表单
class CompanyRegisterForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput, label='登录密码')
    confirm_password = forms.CharField(widget=forms.PasswordInput, label='确认密码')

    class Meta:
        model = User
        fields = ['name', 'email', 'contact', 'password']
    
    def clean_confirm_password(self):
        password = self.cleaned_data.get('password')
        confirm_password = self.cleaned_data.get('confirm_password')
        if password and confirm_password and password != confirm_password:
            raise forms.ValidationError("两次输入的密码不一致")
        return confirm_password

class CompanyProfileForm(forms.ModelForm):
    class Meta:
        model = CompanyProfile
        fields = ['business_license', 'company_address', 'business_scope']

第三步:编写差异化注册视图

在views.py中编写两个视图,分别处理两类用户的注册逻辑:

# views.py
from django.shortcuts import render, redirect
from django.db import transaction
from .forms import CustomerRegisterForm, CustomerProfileForm, CompanyRegisterForm, CompanyProfileForm

# 个人客户注册逻辑
def customer_register(request):
    if request.method == 'POST':
        user_form = CustomerRegisterForm(request.POST)
        profile_form = CustomerProfileForm(request.POST)
        if user_form.is_valid() and profile_form.is_valid():
            # 开启事务保证数据一致性
            with transaction.atomic():
                # 保存公共用户信息
                user = user_form.save(commit=False)
                user.set_password(user_form.cleaned_data['password'])
                user.user_type = 'customer'
                user.save()
                # 保存个人客户专属信息
                profile = profile_form.save(commit=False)
                profile.user = user
                profile.save()
            # 注册成功跳转登录页,可按需修改跳转路径
            return redirect('login')
    else:
        user_form = CustomerRegisterForm()
        profile_form = CustomerProfileForm()
    return render(request, 'customer_register.html', {
        'user_form': user_form,
        'profile_form': profile_form
    })

# 企业用户注册逻辑
def company_register(request):
    if request.method == 'POST':
        user_form = CompanyRegisterForm(request.POST)
        profile_form = CompanyProfileForm(request.POST)
        if user_form.is_valid() and profile_form.is_valid():
            with transaction.atomic():
                user = user_form.save(commit=False)
                user.set_password(user_form.cleaned_data['password'])
                user.user_type = 'company'
                user.save()
                profile = profile_form.save(commit=False)
                profile.user = user
                profile.save()
            return redirect('login')
    else:
        user_form = CompanyRegisterForm()
        profile_form = CompanyProfileForm()
    return render(request, 'company_register.html', {
        'user_form': user_form,
        'profile_form': profile_form
    })

第四步:配置路由

在应用的urls.py中添加两个注册路径:

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    # 现有路由保持不变
    path('register/customer/', views.customer_register, name='customer_register'),
    path('register/company/', views.company_register, name='company_register'),
]

第五步:开发两个注册模板

分别创建templates/customer_register.html和templates/company_register.html两个模板文件,渲染对应的表单即可,示例模板结构:

<!-- customer_register.html 示例,企业注册模板仅需替换标题和提示文字即可 -->
<!DOCTYPE html>
<html>
<head>
    <title>个人客户注册</title>
</head>
<body>
    <h2>个人客户注册</h2>
    <form method="post">
        {% csrf_token %}
        {{ user_form.as_p }}
        {{ profile_form.as_p }}
        <button type="submit">提交注册</button>
    </form>
</body>
</html>

如果两类用户的差异化属性较少,也可以直接把所有字段放到主User表中,通过表单控制不同角色显示不同字段,减少表关联复杂度。

内容的提问来源于stack exchange,提问作者somya goyal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 07:45:04