Django Web应用注册时重复创建两个Profile问题求助
Django注册时重复创建Profile实例的问题解决
问题核心原因
你遇到的重复创建Profile的问题,大概率是两种创建逻辑重复触发:
- 视图代码里手动调用了
Profile.objects.create创建实例 - 你的Profile模型可能配置了
post_save信号,在User对象创建时自动生成Profile
两种逻辑叠加,就会导致每次注册生成两个Profile实例。另外,视图里通过create_user已经得到了user对象,没必要再用User.objects.get(username=username)重复查询,这属于冗余代码,但不会直接导致重复创建。
解决方案
方案1:移除视图手动创建逻辑(推荐)
如果你的models.py中存在如下自动创建Profile的信号配置:
# models.py中的信号代码示例 from django.db.models.signals import post_save from django.contrib.auth.models import User 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)
则需要删除视图里手动创建Profile的代码,优化后的视图代码如下:
def signup(request): if request.method == "POST": print("Signup view called") username = request.POST["username"] email = request.POST["email"] password = request.POST["password"] password2 = request.POST["password2"] if password == password2: if User.objects.filter(email=email).exists(): messages.info(request, "Email Taken") return redirect("signup") elif User.objects.filter(username=username).exists(): messages.info(request, "Username Taken") return redirect("signup") else: # create_user方法会自动保存用户,无需额外调用user.save() User.objects.create_user(username=username, email=email, password=password) return redirect("signup") else: messages.info(request, "Password Not Matching") return redirect("signup") else: return render(request, "signup.html")
方案2:移除信号逻辑,保留视图手动创建
如果不需要信号自动生成Profile,先删除models.py中的post_save信号代码,再优化视图里的冗余查询:
def signup(request): if request.method == "POST": print("Signup view called") username = request.POST["username"] email = request.POST["email"] password = request.POST["password"] password2 = request.POST["password2"] if password == password2: if User.objects.filter(email=email).exists(): messages.info(request, "Email Taken") return redirect("signup") elif User.objects.filter(username=username).exists(): messages.info(request, "Username Taken") return redirect("signup") else: user = User.objects.create_user(username=username, email=email, password=password) # 直接使用已创建的user对象,无需重复查询 Profile.objects.create(user=user) # create方法自动保存实例,无需调用new_profile.save() return redirect("signup") else: messages.info(request, "Password Not Matching") return redirect("signup") else: return render(request, "signup.html")
内容的提问来源于stack exchange,提问作者Usman Ndako
相关产品推荐
相关产品推荐

