我有模特商会:
class Chamber(models.Model):
chamber_name = models.CharField(max_length=100)
相关模型 ChamberProperty :
class ChamberProperty(models.Model):
chamber = models.ForeignKey(Chamber, on_delete=models.CASCADE)
property_name = models.CharField(max_length=50)
property_value = models.CharField(max_length=100, default=None)
现在商会可以有很多 ChamberProperty 。这些要求只是更改为使得如果将 ChamberProperty 添加到 Chamber ,它将被添加到所有未来的 Chamber 实例中,使用空 property_value(默认=无),以便下次加载用于创建新 Chamber 实例的表单时,所有以前的 ChamberProperty.property_name < / strong>在表单中加载,并为空。
示例表格:
第一次创建Chamber实例:
Chamber.chamber_name: Foo
ChamberProperty.property_name: Bar
ChamberProperty.property_value: Baz
第二次创建Chamber实例:
Chamber.chamber_name: Qux
ChamberProperty.property_name: Bar # Old property, retain the name
ChamberProperty.property_value: None # Old property, value empty
ChamberProperty.property_name: Quux # New property, added by a button
ChamberProperty.property_value: 700 # New property, value filled with input box
第三次创建Chamber实例:
Chamber.chamber_name: Corge
ChamberProperty.property_name: Bar # Old property, retain the name
ChamberProperty.property_value: None # Old property, value empty
ChamberProperty.property_name: Quux # Old property, retain the name
ChamberProperty.property_value: None # Old property, value empty
ChamberProperty.property_name: Ouier # New property, added by a button
ChamberProperty.property_value: Grault # New property, value filled with input box
等等。
澄清:如果您使用&#34; ChamberProperty 温度&#34;创建商会A,那么下次创建商会时,商会B,它已经有&#34; ChamberProperty 温度&#34;。然后,你可以向商会B添加一个新的 ChamberProperty ,比如,&#34; Degrees&#34;无论什么价值。然后,如果您创建一个新的 Chamber ,C室,它将具有&#34; ChamberProperty 温度和度数&#34;。
现在我意识到我必须递归地将 ChamberProperty 实例添加到所有其他 Chamber 实例。
使用jQuery脚本在表单中添加了新的属性和值,我已经这样了:
<div class="card loading-card" id="card-loaded">
<h3 class="card-header bg-primary text-white">
Add Chamber
</h3>
<div class="card-body">
<form class="form-horizontal" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ properties_formset.management_form }}
<!-----------Chamber------------>
<table>
<tr>
<td style="vertical-align:top">
<table>
<tr>
{% for field in chamber_form %}
<td>{{ field|as_crispy_field }}</td>
{% endfor %}
</tr>
</table>
</td>
<br />
<!-----------Chamber Properties------------>
<td><p>     </p></td>
<td>
<table class="new-chamber-properties" id="propertiestable">
<script type="text/html" id="property-template">
<div id="property-__prefix__">
<table>
<tr>
{% for field in properties_formset.empty_form %}
<td>{{ field|as_crispy_field }}</td>
{% endfor %}
</tr>
</table>
</div>
</script>
<div id="property-form">
<tr>
{% for properties_form in properties_formset %}
<div id="property-{{ forloop.counter0 }}"></div>
{% endfor %}
</tr>
</div>
<tr>
<td>
<a href="#" id="add-property-button" class="btn btn-outline-primary add-item">Add Properties</a>
</td>
<td>
<a href="#" id="remove-property-button" class="btn btn-outline-danger remove-item">Remove Properties</a>
</td>
<td><button class="btn btn-primary" type="submit">Submit</button></td>
</tr>
</table>
</td>
</tr>
</table>
</form>
</div>
</div>
和jQuery:
<script>
$(document).ready(function () {
$('.add-item').click(function (ev) {
ev.preventDefault();
var count = $('#property-form').children().length;
console.log(count)
var tmplMarkup = $('#property-template').html();
var compiledTmpl = tmplMarkup.replace(/__prefix__/g, count);
$('div#property-form').append(compiledTmpl);
// update form count
$('#id_form-TOTAL_FORMS').attr('value', count + 1);
// some animate to scroll to view our new form
$('html, body').animate({ scrollTop: $("#add-property-button").position().top - 200 }, 800);
});
for (var i = 0; i < 4; i++) {
var tmplMarkup = $('#property-template').html();
var compiledTmpl = tmplMarkup.replace(/__prefix__/g, i);
$('div#property-form').append(compiledTmpl);
// update form count
$('#id_form-TOTAL_FORMS').attr('value', i + 1);
}
document.getElementById("id_form-0-property_name").value = "Process";
document.getElementById("id_form-1-property_name").value = "Type";
document.getElementById("id_form-2-property_name").value = "Model";
document.getElementById("id_form-3-property_name").value = "Electrode Diameter";
document.getElementById("card-loaded").style.visibility = "visible";
$('.remove-item').click(function (ev) {
ev.preventDefault();
var count = $('#property-form').children().length;
console.log(count);
if (count > 0) {
var successCount = count - 1;
console.log(successCount);
var formlist = $('#property-form')[0];
while (count > successCount) {
var childNode = formlist.lastChild;
formlist.removeChild(childNode);
count = $('#property-form').children().length;
}
// update form count
$('#id_form-TOTAL_FORMS').attr('value', count);
// some animate to scroll to view our new form
$('html, body').animate({ scrollTop: $("#remove-property-button").position().top - 200 }, 800);
}
});
});
</script>
我不确定如何做到这一点。
我想的也许是,当表单加载时,检索该客户的所有 ChamberProperty 实例,但是如果我将这些值设置为空,它将改变所有其他值的值< strong>商会实例。
对此有何帮助?
答案 0 :(得分:1)
问题是您当前的模型不能反映您的要求。什么构成属性?显然,它只是名称,而不是它的价值。该值应保存在单独的模型中,而不是与名称和腔室相关联:
class ChamberProperty(models.Model):
name = models.CharField(max_length=50)
class ChamberPropertyValue(models.Model):
chamber = models.ForeignKey(Chamber, on_delete=models.CASCADE)
property = models.ForeignKey(ChamberProperty, on_delete=models.CASCADE)
value = models.CharField(max_length=100, default=None)
创建新的工作室时,您将立即为数据库中存在的每个ChamberPropertyValue
添加一个ChamberProperty
。通过这种方式,旧房间将保持其状态不具有与其相关联的任何新名称/属性。创建新的chamber
后,此代码段应进入您的表单验证:
for prop in ChamberProperty.objects.all():
ChamberPropertyValue.objects.get_or_create(property=prop, chamber=chamber)