Django & SQLite3客户注册问题:CustomerProfile数据未保存
问题:Django客户注册时CustomerProfile表无法保存数据,User表正常
开发Django项目时,客户注册功能出现异常——用户信息能正常保存到User表,但CustomerProfile表没有生成对应记录。项目包含app和user两个目录,相关代码如下:
app目录下的forms代码
from django import forms from django.contrib.auth.forms import UserCreationForm from user.models import Customer, CustomerProfile, generate_customer_id class Customer_Register_Form(UserCreationForm): cus_name = forms.CharField( label="Customer Name", widget=forms.TextInput(attrs={"class": "form-control"}) ) email = forms.EmailField(widget=forms.EmailInput(attrs={"class": "form-control"})) phone_number = forms.CharField( widget=forms.TextInput(attrs={"class": "form-control"}) ) address = forms.CharField(widget=forms.TextInput(attrs={"class": "form-control"})) username = forms.CharField( widget=forms.TextInput( attrs={"class": "form-control", "placeholder": "Enter your username"} ) ) password1 = forms.CharField( label="Password", widget=forms.PasswordInput( attrs={"class": "form-control", "placeholder": "Enter your password"} ), ) password2 = forms.CharField( label="Confirm Password", widget=forms.PasswordInput( attrs={"class": "form-control", "placeholder": "Confirm your password"} ), ) class Meta: model = Customer # Use your custom user model fields = [ "username", "cus_name", "password1", "password2", "email", "phone_number", "address", ] def save(self, commit=True): user = super().save(commit=False) user.cus_name = self.cleaned_data['cus_name'] user.email = self.cleaned_data['email'] user.phone_num = self.cleaned_data['phone_number'] user.address = self.cleaned_data['address'] if commit: user.save() # Assuming there's a one-to-one relationship between User and CustomerProfile CustomerProfile.objects.create(username=user, cus_id=generate_customer_id(user)) return user
user目录下的models代码
from django.db import models from django.contrib.auth.models import AbstractUser, BaseUserManager from django.db.models.signals import post_save from phonenumber_field.modelfields import PhoneNumberField from django.dispatch import receiver # Create your models here. class User(AbstractUser): class Role(models.TextChoices): CUSTOMER = "CUSTOMER", "Customer" PHARMACIST = "PHARMACIST", "Pharmacist" RETAILASSISTANT = "RETAILASSISTANT", "Retail Assistant" MANAGER = "MANAGER", "Manager" base_role = Role.CUSTOMER role = models.CharField(max_length=50, choices=Role.choices) def save(self, *args, **kwargs): if not self.pk: self.role = self.base_role return super().save(*args, **kwargs) def generate_customer_id(instance): return f"CUS{instance.id:04d}" def generate_pharmacist_id(instance): return f"PM{instance.id:04d}" def generate_retail_assistant_id(instance): return f"RA{instance.id:04d}" def generate_manager_id(instance): return f"M{instance.id:04d}" class CustomerManager(BaseUserManager): def get_queryset(self, *args, **kwargs): result = super().get_queryset(*args, **kwargs) return result.filter(role=User.Role.CUSTOMER) class Customer(User): base_role = User.Role.CUSTOMER customer = CustomerManager() class Meta: proxy = True def welcome(self): return "Only for customers" class CustomerProfile(models.Model): username = models.OneToOneField(User, on_delete=models.CASCADE) password = models.CharField(max_length=16) cus_id = models.CharField(max_length=7, unique=True) cus_name = models.CharField(max_length=50) email = models.EmailField(max_length=50) phone_num = PhoneNumberField(blank=True, null=True) address = models.CharField(max_length=255, blank=True, null=True) @receiver(post_save, sender=Customer) def create_user_profile(sender, instance, created, **kwargs): if created and instance.role == "CUSTOMER": CustomerProfile.objects.create( username=instance, cus_id=generate_customer_id(instance) ) class PharmacistManager(BaseUserManager): def get_queryset(self, *args, **kwargs): result = super().get_queryset(*args, **kwargs) return result.filter(role=User.Role.PHARMACIST) class Pharmacist(User): base_role = User.Role.PHARMACIST pharmacist = PharmacistManager() class Meta: proxy = True def welcome(self): return "Only for pharmacists" class PharmacistProfile(models.Model): username = models.OneToOneField(User, on_delete=models.CASCADE) password = models.CharField(max_length=16) pharmacist_id = models.CharField(max_length=6, unique=True) @receiver(post_save, sender=Pharmacist) def create_pharmacist_profile(sender, instance, created, **kwargs): if created and instance.role == "PHARMACIST": PharmacistProfile.objects.create( username=instance, pharmacist_id=f"PM{instance.id:04d}" ) class RetailAssistantManager(BaseUserManager): def get_queryset(self, *args, **kwargs): result = super().get_queryset(*args, **kwargs) return result.filter(role=User.Role.RETAILASSISTANT) class RetailAssistant(User): base_role = User.Role.RETAILASSISTANT RetailAssistant = RetailAssistantManager() class Meta: proxy = True def welcome(self): return "Only for retail assistants" class RetailAssistantProfile(models.Model): username = models.OneToOneField(User, on_delete=models.CASCADE) password = models.CharField(max_length=16) retailassistant_id = models.CharField(max_length=6, unique=True) @receiver(post_save, sender=RetailAssistant) def create_retail_assistant_profile(sender, instance, created, **kwargs): if created and instance.role == "RETAILASSISTANT": RetailAssistantProfile.objects.create( username=instance, retailassistant_id=f"RA{instance.id:04d}" ) class ManagerManager(BaseUserManager): def get_queryset(self, *args, **kwargs): result = super().get_queryset(*args, **kwargs) return result.filter(role=User.Role.MANAGER) class Manager(User): base_role = User.Role.MANAGER manager = ManagerManager() class Meta: proxy = True def welcome(self): return "Only for managers" class ManagerProfile(models.Model): username = models.OneToOneField(User, on_delete=models.CASCADE) password = models.CharField(max_length=16) manager_id = models.CharField(max_length=5, unique=True) @receiver(post_save, sender=Manager) def create_manager_profile(sender, instance, created, **kwargs): if created and instance.role == "MANAGER": ManagerProfile.objects.create( username=instance, manager_id=f"M{instance.id:04d}" )
排查思路
- 检查信号触发状态:在
create_user_profile信号处理函数中添加打印或日志,验证当Customer实例创建时,该函数是否被执行 - 核对CustomerProfile必填字段:查看模型中哪些字段未设置
blank=True或null=True,确认创建Profile时是否提供了所有必填值 - 验证表单save方法的Profile创建逻辑:手动在Django shell中执行表单save里的
CustomerProfile.objects.create语句,检查是否抛出异常,比如字段不匹配、cus_id重复等问题 - 排查代理模型的信号兼容性:因为Customer是User的代理模型,确认Django的
post_save信号是否会正确发送给代理模型的sender,是否需要调整信号绑定的sender - 查看数据库与运行日志:检查Django运行日志中的报错信息,同时查看数据库是否存在约束冲突、事务未提交等情况
- 验证generate_customer_id函数输出:确认该函数生成的cus_id是否符合字段长度要求,是否会出现重复值导致创建失败
内容的提问来源于stack exchange,提问作者FL C.
相关产品推荐
相关产品推荐

