Django条件post_save信号失效:创建超级用户不生成用户档案
解决创建超级用户时不生成用户档案的问题
你的代码存在几处关键问题导致逻辑失效,以下是具体修正方案:
1. 信号接收器位置错误
你把create_user_profile信号函数定义在了UserProfile类内部,Django无法正确识别并注册这个接收器,必须将其移到类外部。同时,post_save.connect调用也不应放在函数内部,否则会重复连接信号。
2. 重复定义save方法
你连续重写了两次save方法,后一个会完全覆盖前一个的逻辑,导致第一个图片处理代码完全失效,需要合并两个方法的功能。
修正后的完整代码
from django.db import models from tinymce import models as tinymce_models from accounts.models import CustomUser from phone_field import PhoneField from constrainedfilefield.fields import ConstrainedFileField import os from io import BytesIO from django.core.files.uploadedfile import InMemoryUploadedFile import sys from PIL import Image from django.db.models.signals import post_save import PIL class UserProfile(models.Model): user = models.OneToOneField(CustomUser, null=True, on_delete=models.CASCADE) preferred_name = models.CharField(null=True, blank=True, max_length=75) pronouns = models.CharField(null=True, blank=True, max_length=40) phone = PhoneField(blank=True, help_text='Contact phone number') job_title = models.CharField(null=True, blank=True, max_length=75) birthdate = models.DateField(null=True, blank=True) bio = tinymce_models.HTMLField(null=True, blank=True) profile_image = ConstrainedFileField( null=True, blank=True, upload_to='projects/employee_profiles', content_types=['image/png', 'image/jpg', 'image/jpeg', 'image/gif'], max_upload_size=2097152, ) def save(self, *args, **kwargs): if self.profile_image: # 先保存一次获取文件路径 super().save(*args, **kwargs) img = Image.open(self.profile_image.path) # 裁剪为正方形 if img.height > img.width: left = 0 right = img.width top = (img.height - img.width) / 2 bottom = (img.height + img.width) / 2 img = img.crop((left, top, right, bottom)) elif img.width > img.height: left = (img.width - img.height) / 2 right = (img.width + img.height) / 2 top = 0 bottom = img.height img = img.crop((left, top, right, bottom)) # 缩放到60x60分辨率 if img.height > 60 or img.width > 60: output_size = (60, 60) img.thumbnail(output_size) img.save(self.profile_image.path) # 处理图片格式转换与宽度压缩 image = Image.open(self.profile_image.path) outputIoStream = BytesIO() basewidth = 100 wpercent = basewidth / image.size[0] hsize = int(image.size[1] * wpercent) imageTemproaryResized = image.resize((basewidth, hsize)) imageTemproaryResized.save(outputIoStream, format='PNG') outputIoStream.seek(0) self.profile_image = InMemoryUploadedFile(outputIoStream, 'ConstrainedFileField', "%s.png" % self.profile_image.name.split('.')[0], 'image/png', sys.getsizeof(outputIoStream), None) # 统一保存所有修改 super(UserProfile, self).save(*args, **kwargs) def __str__(self): return str(self.user) # 信号接收器移至类外部 def create_user_profile(sender, instance, created, **kwargs): if created and not instance.is_superuser: UserProfile.objects.create(user=instance) # 连接post_save信号 post_save.connect(create_user_profile, sender=CustomUser)
关键修正点说明
- 信号接收器独立于类定义,确保Django能在应用加载时正确注册。
- 合并后的
save方法按顺序处理图片裁剪、缩放、格式转换,避免重复调用save引发的循环问题。 created and not instance.is_superuser的判断逻辑会严格筛选:仅当创建普通用户时生成档案,超级用户创建时直接跳过。
内容的提问来源于stack exchange,提问作者Finn
相关产品推荐
相关产品推荐

