Django表单数据未保存到数据库
Posted
技术标签:
【中文标题】Django表单数据未保存到数据库【英文标题】:Django form data not saving to database 【发布时间】:2021-10-07 21:49:41 【问题描述】:我有一个views.py,它将来自不同模型的三个表单组合成模板上的一个表单。该代码似乎是可操作的,views.py 文档中的打印语句表明该表单有效并且所有相关数据都可用。但是,只有来自 form1
和 form2
的数据会保存到数据库中。
我已经阅读了(感觉是)这个网站上的几十个线程,但是打印语句和清除数据库是我最后的生产性调试想法,现在我不知道如何进一步调试.请提出建议!
views.py
def consent(request):
context =
'title': 'Consent',
print(Author)
try:
UD = UserDetails.objects.get(user_id=request.user.id)
consent = UD.participate_consent
if consent == True:
username = request.user.username
messages.warning(request, f'Hej, username, you already did that.')
return redirect('profile')
except:
context['form1'] = None
context['form2'] = None
context['form3'] = None
if request.method == 'POST':
form1 = UserDetailsForm(request.POST)
form2 = GetUserFirstLast(request.POST, instance=User.objects.get(id=request.user.id))
form3 = GetAuthorInfo(request.POST, instance=User.objects.get(id=request.user.id))
context['form1'] = form1
context['form2'] = form2
context['form3'] = form3
if form1.is_valid() and form2.is_valid() and form3.is_valid():
print(form1.cleaned_data)
print(form2.cleaned_data)
print(form3.cleaned_data)
form1.save()
form2.save()
form3.save()
username = form1.cleaned_data.get('username')
messages.success(request, f'Thanks for consenting, username! \nNow we can get started.')
return redirect('profile')
else:
print("a form is not valid")
else:
form1 = UserDetailsForm()
form2 = GetUserFirstLast(instance=User.objects.get(id=request.user.id))
form3 = GetAuthorInfo(instance=User.objects.get(id=request.user.id))
context['form1'] = form1
context['form2'] = form2
context['form3'] = form3
return render(request, 'users/consent.html', context)
form3相关模型
class Author(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT, primary_key=True)
username = models.CharField(max_length=100, blank=True)
slug = slug = models.SlugField(max_length=400, unique=True, blank=True)
bio = HTMLField()
points = models.IntegerField(default=0)
profile_pic = ResizedImageField(size=[50, 80], quality=100, upload_to="static/users/authors/", default='static/users/authors/default.png')
def __str__(self):
return self.username
@property
def num_posts(self):
return Post.objects.filter(user=self).count()
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.username)
super(Author, self).save(*args, **kwargs)
form3相关的forms.py
class GetAuthorInfo(forms.ModelForm):
user = forms.CharField(widget=forms.HiddenInput(), required=True)
profile_pic = forms.ImageField(label = profile_pic_label, required=False, initial='static/users/authors/default.png')
bio = forms.CharField(label = bio_label, widget=forms.Textarea())
username = forms.CharField(widget=forms.HiddenInput(), required=True)
class Meta:
model = Author
fields = ['user', 'profile_pic', 'bio', 'username']
编辑开始 遵循(或尝试)遵循答案中的建议,表单现在看起来像
class GetAuthorInfo(forms.ModelForm):
class Meta:
model = Author
fields = '__all__'
exclude = ['points']
labels =
'profile_pic': profile_pic_label,
'bio': bio_label
widgets =
'bio': forms.Textarea(),
'username': forms.HiddenInput()
但还是不行。 编辑结束
模板的相关部分
<form method="POST">
% csrf_token %
<fieldset class="form-group">
<legend class="border-bottom mb-4">% translate 'Informed Consent' %</legend>
form2|crispy
form1|crispy
<h4>For the forum</h4><hr>
<img src="% static 'users/authors/default.png' %" style="height:150px;width:200px;">
form3|crispy
<input type="hidden" name="user" value=" user.id ">
<input type="hidden" name="username" value=" user.username ">
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">% translate 'Submit' %</button>
</div>
<div> form.errors </div>
</form>
Django 版本 3.2.5
Python 版本 3.8.10
操作系统 Linux Mint 20.1
请!
【问题讨论】:
【参考方案1】:表单具有文件字段,因此您可以在视图中请求文件 像这样
form3 = GetAuthorInfo(request.POST,request.FILES, instance=User.objects.get(id=request.user.id))
在你的 html 代码中
<form method="POST" enctype="multipart/form-data">
请稍微改变一下你的表格
class GetAuthorInfo(forms.ModelForm):
class Meta:
model = Author
fields = '__all__'
exclude = ['slug']
# if you want to add widgets & labels to fields like
labels =
'dob':'Date Of Birth',
widgets =
'dob': forms.DateInput(attrs='type': 'date')
【讨论】:
我将 request.FILES 和 profile_pic 字段从模型中取出(并重新迁移等),看看这是否是问题所在,但忘记将其放回原处。然后没有任何变化——没有 profile_pic 字段仍然没有保存到模式中。尽管如此,按照您的建议,仍然没有数据保存到数据库中。 因为我就是这样学到的——可能是错误的——你应该指明“所有”字段或只指明你想要的字段。在这种特殊情况下,我不想用这个表单填充points
(这是问题,因为我没有从调试中恢复),所以目的是除了点之外的所有字段。
当用户已经连接外键时,您不必添加额外的字段用户名
@Bob 试试这个告诉我你是否还有错误【参考方案2】:
fields = ['user', 'bio', 'username', 'profile_pic']
【讨论】:
感谢您的建议,但没有任何改变。以上是关于Django表单数据未保存到数据库的主要内容,如果未能解决你的问题,请参考以下文章
Django绑定表单无效,但未引发ValidationError