Django form.is_valid失败并且没有保存表单



我的帐户模型在用户创建新用户帐户时自动创建&只有用户价值被添加到这个模型中,其余的都是空的!我试图让用户更新或在他们的帐户模型中添加更多信息,但is.valid()在视图&没有保存表单。出了什么问题& &;如何解决这个问题?

Models.py

class profile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
bio = models.TextField(blank=True, null=True, max_length=100)
profile_img = models.ImageField(
upload_to="profile_images", default="default.jpg")
location = models.CharField(max_length=100, blank=True)
def __str__(self):
return self.user.username

Forms.py

class accountForm(ModelForm):
class Meta:
model = profile
fields = "__all__"
widgets = {
# 'fields': forms.TextInput(attrs={'class': "form-control"}),
'profile_img': forms.FileInput(attrs={'class': 'form-control', 'id': 'inputGroupFile04'}),
'bio': forms.Textarea(attrs={'class': 'form-control'}),
'location': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Location'}),
}

views.py

def account(request):
Profile = profile.objects.get(user=request.user)
form = accountForm(instance=Profile)
if request.method == "POST":
form = accountForm(request.POST, instance=Profile)
if form.is_valid():
form.save()
return redirect("sign_in")
context = {"form": form}
return render(request, "account.html", context)

我会在您的视图中实现一些错误处理。你有

if form.is_valid:表述,没有别的了。这就是为什么错误没有显示在页面

通常当这种情况发生在我身上时,我会在调用。is_valid()

之后丢弃一个调试器语句import ipdb; ipdb.set_trace()

然后在生成的终端中,我将输入form.errors,您应该看到哪里出错了

首先,为了上传文件,您需要确保元素正确地定义了enctype"多部分/form-data"在你的表单标签:

#templates file
<form enctype="multipart/form-data" method="post" action="/foo/">
其次,添加请求。文件toform = accountForm(request.POST, request.FILES, instance=Profile)

你可以从django docs

中了解更多。

您可以使用cleaned_data来保存表单。

试试这个视图:

views.py


def account(request):
profile_instance = profile.objects.get(user=request.user)
form = accountForm(instance=profile_instance)
if request.method == "POST":
form = accountForm(request.POST, instance=profile_instance)
if form.is_valid():
user = request.user
bio = request.POST.get('bio')
profile_img = request.POST.get('profile_img')
location = request.POST.get('location')
profile.objects.create(
user=user, bio=bio, profile_img=profile_img, location=location)
return redirect("sign_in")
else:
form = accountForm()
return render(request, "home/account.html", {'form': form})

请确保,您已登录并且profile模型不包含用于上述代码工作的两个相同用户,因为您已将其设置为Foreignkey

Note:模型是用PascalCase而不是smallcase写的,所以如果你把它命名为Profile而不是profile会更好。表单也是一样,最好写AccountForm,或者写ProfileForm,而不是accountForm




试试下面的代码,其中配置文件将直接创建。

models.py


class profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
# other fields are same...

在实际场景中,最好将user改为Profile模型中的OneToOneField,因为一个人只能有一个配置文件,我假设您是第一次创建用户的配置文件,而不是更新现有的配置文件,所以我不会使用instancein form.

views.py

def account(request):
if request.method == "POST":
form = accountForm(request.POST)
if form.is_valid():
username = request.POST.get('username')
password = request.POST.get('password1')
bio = request.POST.get('bio')
profile_img = request.POST.get('profile_img')
location = request.POST.get('location')
created_user = User.objects.create(
username=username, password=password)
profile.objects.create(
user=created_user, bio=bio, profile_img=profile_img, location=location)
return redirect('sign_in')
else:
form = accountForm()
return render(request, "home/account.html", {'form': form})

forms.py

class accountForm(ModelForm):
username = forms.CharField(
widget=forms.TextInput(attrs={'class': 'form-control'}))
password1 = forms.CharField(
widget=forms.PasswordInput(attrs={'class': 'form-control'}))
password2 = forms.CharField(
widget=forms.PasswordInput(attrs={'class': 'form-control'}))
def clean(self):
cleaned_data = super().clean()
p1 = cleaned_data.get('password1')
p2 = cleaned_data.get('password2')
if p1 != p2:
raise forms.ValidationError('Both the passwords must match')
class Meta:
model = profile
fields = ['username', 'password1',
'password2', 'profile_img', 'bio', 'location']
widgets = {
# 'fields': forms.TextInput(attrs={'class': "form-control"}),
'profile_img': forms.FileInput(attrs={'class': 'form-control', 'id': 'inputGroupFile04'}),
'bio': forms.Textarea(attrs={'class': 'form-control'}),
'location': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Location'}),
}

它将直接创建新用户的配置文件,并进行密码验证,并且这些用户也与User模型相关,因此您不会得到the field user in profile model must be an user instance的错误。

谢谢大家的建议,但我知道这里的问题是什么了。抱歉没有提供HTML代码,因为我没有添加表单。这里的用户标签。所以请求。POST没有提供给用户。有两种方法可以解决这个问题。您可以在models.py中使用一对一的关系,这并不一定需要您选择用户。下一个是更有效的形式。

隐藏用户表单
class accountForm(ModelForm):
class Meta:
model = profile
fields = "__all__"
widgets = {
user': forms.hiddenInput(),
'profile_img': forms.FileInput(attrs={'class': 'form-control', 'id': 'inputGroupFile04'}),
'bio': forms.Textarea(attrs={'class': 'form-control'}),
'location': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Location'}),
}

然后,在views.py中添加用户:

def account(request):
form = accountForm(initial=request.user)
if request.method == "POST":
form = accountForm(request.POST, initial = request.user)
if form.is_valid():
form.save()
return redirect("sign_in")
context = {"form": form}
return render(request, "account.html", context)

如果你想更新它,使用instance代替初始的&提供配置文件

最新更新