【发布时间】:2021-10-04 01:59:08
【问题描述】:
我正在创建一个系统,通过让用户添加所有者的姓名来跟踪不同电话公司的所有者。我希望用户能够一次添加多个所有者,并且希望避免使用大量 RegEx、Ajax 和 Node,我在我的数据库中创建了 5 个“所有者”表(意大利面条代码的缩影,我知道)。最后 4 个 Owner 表具有 null=True 和 blank=True,因此它们是可选的。在 UI 中显示此内容时,我将所有者的每个表单字段表示形式放在其自己的 div 中并隐藏最后 4 个 div。用户可以通过单击按钮选择“添加另一个所有者”,最多可添加 4 个额外所有者。很少会填写所有五个 div,因此其中一些始终被基本的 javascript 隐藏。然后我继续使用 .save() 像任何其他模型一样保存所有这些。当用户填写完所有需要的字段并点击“提交”时,一切正常,但是......数据永远不会发送到数据库。
我在任何地方都没有错误,这导致我猜测我在保存数据时传入的表单无效。我知道问题出在“几个隐藏的表单”部分,因为当我只有 1 个所有者表并且没有任何隐藏时,我的系统运行良好。但是,由于它没有给我任何错误消息,我现在不知道我能做什么 - 我不知道为什么它认为我的表单无效。
注意:我意识到 django 的方式是制作表单集以添加一个表的多个实例,但是使这些动态化并隐藏,例如,表单集中的 5 个表单中的 4 个,并在单击按钮或真正的动态表单时显示其余的表单循环的行为非常具有挑战性,我没有 javascript/react 知识来做到这一点。隐藏表单并根据用户请求显示它的能力很重要 - 我知道它可以很容易地解决,否则只需使用表单集而不隐藏任何内容。
编辑: 我尝试了一些方法来修复它,例如在表单名称和 .save() 之间添加 .instance,设置 instance =(我正在编辑其实例的表单)然后 commit=False,并设置 commit=True在最后保存。我制作的新“实例”变量变灰并显示“未使用局部变量“实例”值。
我在我的models.py 文件中发现了一个错误:在PhoneCompany 中,owner_Set 应该是一个ForeignKey,但实际上写成一个ManyToManyField。当我更正它时,它返回以下错误:django.db.utils.IntegrityError: NOT NULL constraint failed: new__phoneBook_companyinformation.owner_set_id 我想这并不奇怪;由于数据从未保存到数据库中,因此没有创建所有者集,因此没有可引用的所有者集。
我的 models.py 文件:
from django.db import models
Owner1(models.Model):
owner1_name = models.CharField(max_length=200)
Owner2(models.Model):
owner2_name = models.CharField(max_length=200)
Owner3(models.Model):
owner3_name = models.CharField(max_length=200)
Owner4(models.Model):
owner4_name = models.CharField(max_length=200)
Owner5(models.Model):
owner5_name = models.CharField(max_length=200)
OwnerSet(models.Model):
owner1 = models.ForeignKey(Owner1, on_delete=models.CASCADE, default=None)
owner2 = models.ForeignKey(Owner2, on_delete=models.CASCADE, default=None)
owner3 = models.ForeignKey(Owner3, on_delete=models.CASCADE, default=None)
owner4 = models.ForeignKey(Owner4, on_delete=models.CASCADE, default=None)
owner5 = models.ForeignKey(Owner5, on_delete=models.CASCADE, default=None)
PhoneCompany(models.Model):
name = models.CharField(max_length = 400, default=None)
address = models.CharField(max_length = 400, default=None)
owner_set = models.ForeignKey(OwnerSet, on_delete=models.CASCADE, default=None)
我的 forms.py 文件:
from django.forms import ModelForm
from django import forms
from .models import *
class Form1(ModelForm):
class Meta:
model = Owner1
fields = ['owner1_name']
widgets = {
'owner1_name': TextInput(attrs={'class': 'form-control', 'id': 'owner1'})}
class Form2(ModelForm):
class Meta:
model = Owner2
fields = ['owner2_name']
widgets = {
'owner2_name': TextInput(attrs={'class': 'form-control', 'id': 'owner2'})}
class Form3(ModelForm):
class Meta:
model = Owner3
fields = ['owner3_name']
widgets = {
'owner3_name': TextInput(attrs={'class': 'form-control', 'id': 'owner3'})}
class Form4(ModelForm):
class Meta:
model = Owner4
fields = ['owner4_name']
widgets = {
'owner4_name': TextInput(attrs={'class': 'form-control', 'id': 'owner4'})}
class Form5(ModelForm):
class Meta:
model = Owner5
fields = ['owner5_name']
widgets = {
'owner5_name': TextInput(attrs={'class': 'form-control', 'id': 'owner5'})}
class Form6(ModelForm):
class Meta:
model = OwnerSet
fields = ['owner1_name']
# because i needed at least one to make the code run and it didn't like like '__all__'
widgets = {
'owner1_name': iTextInput(attrs={'class': 'form-control', 'id': 'fk_owner1'})}
class Form7(ModelForm):
class Meta:
model = PhoneCompany
fields = ['name', 'address']
widgets = {
'name': TextInput(attrs={'class': 'form-control', 'id': 'comp_name'})
'address': TextInput(attrs={'class': 'form-control', 'id': 'adrs'})
}
我的views.py 文件:
from django.shortcuts import render, redirect
from .forms import *
def company_input(request):
form1 = Form1()
form2 = Form2()
form3 = Form3()
form4 = Form4()
form5 = Form5()
form6 = Form6()
form7 = Form7()
if request.method == 'POST':
form_owner1 = Form1(request.POST)
form_owner2 = Form2(request.POST)
form_owner3 = Form3(request.POST)
form_owner4 = Form4(request.POST)
form_owner5 = Form5(request.POST)
form_ownerset = Form6(request.POST)
form_company = Form7(request.POST)
if form_owner1.is_valid() and form_owner2.is_valid() and
form_owner3.is_valid() and form_owner4.is_valid() and
form_owner5.is_valid() and form_ownerset.is_valid() and
form_company.is_valid():
owner1 = form_owner1.save()
owner2 = form_owner2.save()
owner3 = form_owner3.save()
owner4 = form_owner4.save()
owner5 = form_owner5.save()
instance = form_ownerset.save(commit=False) # greys out
instance.owner1 = owner1
instance.owner2 = owner2
instance.owner3 = owner3
instance.owner4 = owner4
instance.owner5 = owner5
ownerset = instance.save(commit=True)
instance = form_company.save(commit=False) # greys out
instance.ownerset = ownerset
company = instance.save()
else:
print("Error: a form is not valid.") # never returns the error...
context = {'from1': form1,
'form2': form2,
'form3': form3,
'form4': form4,
'form5': form5,
'form6': form6,
'form7': form7,
}
return render(request, 'phoneBook/reg_owners.html', context)
我的 reg_owners.html 文件:
<div id="owners" class="column">
<div id="owner1">
<h5>Owner 1:</h5>
<br>
{{ form1.as_p }}
</div>
<div id="masterdiv">
<button id="btn1" style="width: 90px; margin-left: 40px" >Add Owner</button>
<div id="own2" style="display: none; margin-left: 40px; border-radius: 6px;">
<p>{{ form2.as_p }}</p>
</div>
<br>
<button id="btn2" style="margin-left: 40px; display: none">Add Owner</button>
<div id="own3" style="display: none; margin-left: 40px; border-radius: 6px;">
<p>{{ form3.as_p }}</p>
</div>
<br>
<button id="btn3" style="margin-left: 40px; display: none">Add Owner</button>
<div id="own4" style="display: none; margin-left: 40px; border-radius: 6px;">
<p>{{ form4.as_p }}</p>
</div>
<br>
<button id="btn4" style="margin-left: 40px; display: none">Add Owner</button>
<div id="own5" style="display: none; margin-left: 40px; border-radius: 6px;">
<p>{{ form5.as_p }}</p>
</div>
</div>
我的 add_owner.js 文件:
const btn1 = document.getElementById("btn1")
const btn2 = document.getElementById("btn2")
const btn3 = document.getElementById("btn3")
const btn4 = document.getElementById("btn4")
# own1 is not included, because the first owner form is required and never changes or hides
const own2 = document.getElementById("own2")
const own3 = document.getElementById("own3")
const own4 = document.getElementById("own4")
const own5 = document.getElementById("own5")
btn1.onclick = function(e){
e.preventDefault();
if(btn1.innerHTML === "Add Owner"){
btn1.innerHTML = "Remove";
if(btn2.style.display === "none" && own2.style.display === "none"){
btn2.style.display = "block";
own2.style.display = "block";
}
else if (btn2.style.display === "block" && own2.style.display === "block"){
btn2.style.display = "none";
own2.style.display = "none";
}
}
/*close the div*/
else{
btn1.innerHTML = "Add Owner"
if(own2.style.display === "block" && btn2.style.display === "block"){
own2.style.display = "none"
btn2.style.display = "none"
}
}
}
btn2.onclick = function(e){
e.preventDefault();
if(btn2.innerHTML === "Add Owner"){
btn2.innerHTML = "Remove";
btn1.disabled = true
/*Display button 3 and owner 3*/
if(btn3.style.display === "none" && own3.style.display === "none"){
btn3.style.display = "block";
own3.style.display = "block";
} /*hide button 3 and owner 3*/
else if (btn3.style.display === "block" && own3.style.display === "block"){
btn3.style.display = "none";
own3.style.display = "none";
}
}
/*close the div*/
else{
btn2.innerHTML = "Add Owner"
if(own3.style.display === "block" && btn3.style.display === "block"){
own3.style.display = "none"
btn3.style.display = "none"
btn1.disabled = false
}
}
}
btn3.onclick = function(e){
e.preventDefault();
if(btn3.innerHTML === "Add Owner"){
btn3.innerHTML = "Remove";
btn2.disabled = true
/*Display button 3 and owner 3*/
if(btn4.style.display === "none" && own4.style.display === "none"){
btn4.style.display = "block";
own4.style.display = "block";
} /*hide button 3 and owner 3*/
else if (btn4.style.display === "block" && own4.style.display === "block"){
btn4.style.display = "none";
own4.style.display = "none";
}
}
/*close the div*/
else{
btn3.innerHTML = "Add Owner"
if(own4.style.display === "block" && btn4.style.display === "block"){
own4.style.display = "none"
btn4.style.display = "none"
btn2.disabled = false
}
}
}
btn4.onclick = function(e){
e.preventDefault();
if(btn4.innerHTML === "Add Owner"){
btn4.innerHTML = "Remove";
btn3.disabled = true
if(own5.style.display === "none"){
own5.style.display = "block";
} /*hide button 3 and author 3*/
else if (own5.style.display === "block"){
own5.style.display = "none";
}
}
/*close the div*/
else{
btn4.innerHTML = "Add iOwner"
if(own5.style.display === "block"){
own5.style.display = "none"
btn3.disabled = false
}
}
}
【问题讨论】:
-
您需要在
form_ownerset.instance上致电save,因为您更改了instance。所以form_ownerset.instance.save() -
我尝试了您的两个建议,但它们没有任何作用
-
你也可以试试
form_company吗? -
是的。虽然它看起来像 instance = 技巧永远不会起作用 - 它只是变灰并说“未使用局部变量'instance'值”
-
我在任何地方都添加了 form_(x).instance.save() 我现在改变了一个实例,没有区别
标签: javascript python html django django-forms