我的目的是使用Django的User模型和UserProfile模型创建用户配置文件(基本上添加了有关用户的详细信息/字段)。然后,我想创建一个注册表单,要求填写用户模型和UserProfile模型中包含的字段(即两个模型中字段的单个表单)。
现在正在发生的事情是在我的表单中输入必要的数据后,视图通过,服务器确实创建了一个User对象,甚至将它链接到UserProfile对象(据我所知,这种联系是因为信号而发生的)在models.py类中创建)。但是,没有关于UserProfile的信息(在这种情况下,“location”字段)被添加,并且在我的生活中,我无法弄清楚原因。
我有以下models.py
class UserProfile(models.Model):
# This field is required.
user = models.ForeignKey(User, unique=True, related_name="connector")
location = models.CharField(max_length=20, blank=True, null=True)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
我有以下forms.py(其中UserForm基于Django定义的用户模型)
class UserForm(ModelForm):
class Meta:
model = User
class UserProfileForm(ModelForm):
class Meta:
model = UserProfile
我有以下views.py
@csrf_protect
def register(request):
if request.method == 'POST':
form1 = UserForm(request.POST)
form2 = UserProfileForm(request.POST)
if form1.is_valid() and form2.is_valid():
#create initial entry for user
username = form1.cleaned_data["username"]
password = form1.cleaned_data["password"]
new_user = User.objects.create_user(username, password)
new_user.save()
#create entry for UserProfile (extension of new_user object)
profile = form2.save(commit = False)
profile.user = new_user
profile.save()
return HttpResponseRedirect("/books/")
else:
form1 = UserForm()
form2 = UserProfileForm()
c = {
'form1':form1,
'form2':form2,
}
c.update(csrf(request))
return render_to_response("registration/register.html", c)
我有以下register.html
<form action="/accounts/register/" method="post">{% csrf_token %}
<p style="color:red"> {{form.username.errors}}</p>
{{ form1.as_p }}
{{ form2.as_p }}
<input type="submit" value="Create the account">
</form>
谁能看到我做错了什么?有一个更好的方法吗?提前谢谢!
答案 0 :(得分:1)
您的问题是因为您在一个<form></form>
中有多个表单
您需要使用prefix,因此您的代码如下所示:
@csrf_protect
def register(request):
if request.method == 'POST':
form1 = UserForm(request.POST, prefix = "user")
form2 = UserProfileForm(request.POST, prefix = "profile")
if form1.is_valid() and form2.is_valid():
#create initial entry for user
username = form1.cleaned_data["username"]
password = form1.cleaned_data["password"]
new_user = User.objects.create_user(username, password)
new_user.save()
#create entry for UserProfile (extension of new_user object)
profile = form2.save(commit = False)
profile.user = new_user
profile.save()
return HttpResponseRedirect("/books/")
else:
form1 = UserForm(prefix = "user")
form2 = UserProfileForm(prefix = "profile")
c = {
'form1':form1,
'form2':form2,
}
c.update(csrf(request))
return render_to_response("registration/register.html", c)
从UserProfileForm中排除用户字段使用排除
class UserProfileForm(ModelForm):
class Meta:
model = UserProfile
exclude = ('user',)
如果手动创建配置文件,则无需使用 post_save 信号
答案 1 :(得分:0)
在我看来,没有必要使用django信号。
如果你给我完整的项目资源(如果可能的话)我将解决你的问题
不推荐您使用的方法在一个表单中嵌入两个单独的表单,并且它不漂亮。但如果你说你测试过的数据是正确的,请先试用下面的代码。
我改变了保存用户和userprofile对象的方式。通知我。
从模型中移除信号:
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True, related_name="connector")
location = models.CharField(max_length=20, blank=True, null=True)
观点:
@csrf_protect
def register(request):
if request.method == 'POST':
form1 = UserForm(request.POST)
form2 = UserProfileForm(request.POST)
if form1.is_valid() and form2.is_valid():
#create initial entry for user
username = form1.cleaned_data["username"]
password = form1.cleaned_data["password"]
new_user = User()
new_user.username = username
new_user.set_password(password)
new_user.save()
profile = UserProfile()
profile.user = new_user
profile.save()
return HttpResponseRedirect("/books/")
else:
form1 = UserForm()
form2 = UserProfileForm()
c = {
'form1':form1,
'form2':form2,
}
c.update(csrf(request))
return render_to_response("registration/register.html", c)
答案 2 :(得分:0)
在视图中保存配置文件时,您不需要post_save
信号。可能会被覆盖。