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

如何在Django中创建两种用户类型(普通用户与企业用户)

两种可复用Django默认User模型的企业账户实现方案

不用从零构建模型,下面两种方案既能复用User的所有字段(邮箱、密码、用户名等),还能轻松扩展企业专属字段:


方案一:OneToOneField关联默认User(适合已有项目,无需替换默认用户系统)

这种方案给每个企业账户绑定一个默认User实例,通过一对一关联扩展企业专属字段,完全复用User的核心功能。

1. 修正模型(models.py)

from django.contrib.auth.models import User

class BusinessProfile(models.Model):
    # 一对一关联默认User,复用其所有字段
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='business_profile')
    # 企业专属扩展字段
    industry = models.CharField(max_length=100, blank=True, null=True, verbose_name="所属行业")
    credit_card_last4 = models.CharField(max_length=4, blank=True, null=True, verbose_name="信用卡后四位")  # 禁止存储完整卡号

    class Meta:
        verbose_name = "企业账户"
        verbose_name_plural = "企业账户"
    
    def __str__(self):
        return f"{self.user.email}(企业账户)"

2. 注册表单(forms.py)

同时处理User和企业扩展字段的表单:

from django import forms
from django.contrib.auth.models import User
from .models import BusinessProfile

class BusinessRegisterForm(forms.Form):
    username = forms.CharField(max_length=150, label="用户名")
    email = forms.EmailField(label="邮箱")
    password = forms.CharField(widget=forms.PasswordInput, label="密码")
    industry = forms.CharField(max_length=100, required=False, label="所属行业")
    credit_card_last4 = forms.CharField(max_length=4, required=False, label="信用卡后四位")

    # 校验邮箱唯一性
    def clean_email(self):
        email = self.cleaned_data.get('email')
        if User.objects.filter(email=email).exists():
            raise forms.ValidationError("该邮箱已被注册")
        return email

    # 校验用户名唯一性
    def clean_username(self):
        username = self.cleaned_data.get('username')
        if User.objects.filter(username=username).exists():
            raise forms.ValidationError("该用户名已被占用")
        return username

3. 视图逻辑(views.py)

先创建User实例,再绑定企业扩展信息:

from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login
from django.contrib.auth.models import User
from .forms import BusinessRegisterForm
from .models import BusinessProfile

def business_registration(request):
    if request.method == 'POST':
        form = BusinessRegisterForm(request.POST)
        if form.is_valid():
            # 提取表单数据
            username = form.cleaned_data['username']
            email = form.cleaned_data['email']
            password = form.cleaned_data['password']
            industry = form.cleaned_data['industry']
            credit_card_last4 = form.cleaned_data['credit_card_last4']

            # 创建默认User(自动加密密码)
            user = User.objects.create_user(username=username, email=email, password=password)
            # 创建企业扩展档案
            BusinessProfile.objects.create(user=user, industry=industry, credit_card_last4=credit_card_last4)
            
            # 登录用户
            user = authenticate(request, username=username, password=password)
            if user:
                login(request, user)
                return redirect('/')
    else:
        form = BusinessRegisterForm()
    return render(request, 'business_register.html', {'form': form})

方案二:自定义用户模型(AbstractUser,适合新项目)

直接继承Django的AbstractUser,把企业字段整合到用户模型里,无需额外关联,逻辑更简洁。

1. 自定义用户模型(models.py)

from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomUser(AbstractUser):
    # 标记是否为企业账户
    is_business = models.BooleanField(default=False, verbose_name="是否为企业账户")
    # 企业专属字段
    industry = models.CharField(max_length=100, blank=True, null=True, verbose_name="所属行业")
    credit_card_last4 = models.CharField(max_length=4, blank=True, null=True, verbose_name="信用卡后四位")

    class Meta:
        verbose_name = "用户"
        verbose_name_plural = "用户"

2. 配置settings.py

告诉Django使用自定义用户模型:

AUTH_USER_MODEL = '你的APP名.CustomUser'

3. 注册表单(forms.py)

基于UserCreationForm扩展:

from django.contrib.auth.forms import UserCreationForm
from .models import CustomUser

class BusinessRegisterForm(UserCreationForm):
    industry = forms.CharField(max_length=100, required=False, label="所属行业")
    credit_card_last4 = forms.CharField(max_length=4, required=False, label="信用卡后四位")

    class Meta:
        model = CustomUser
        fields = ['username', 'email', 'password1', 'password2', 'industry', 'credit_card_last4']

    def save(self, commit=True):
        user = super().save(commit=False)
        user.is_business = True  # 标记为企业账户
        if commit:
            user.save()
        return user

4. 视图逻辑(views.py)

简化版,直接保存表单即可:

from django.shortcuts import render, redirect
from django.contrib.auth import login
from .forms import BusinessRegisterForm

def business_registration(request):
    if request.method == 'POST':
        form = BusinessRegisterForm(request.POST)
        if form.is_valid():
            user = form.save()
            login(request, user)
            return redirect('/')
    else:
        form = BusinessRegisterForm()
    return render(request, 'business_register.html', {'form': form})

你现有代码的核心问题

你之前的BusinessModel用OneToOneField关联User的email和password是错误的——User本身已经包含这些字段,这种写法会导致一个企业账户关联两个不同的User实例,逻辑完全混乱。上面两种方案都能彻底解决这个问题,同时满足复用字段和后续扩展的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:16:13