मेरे पास एक HTML फॉर्म है जहां उपयोगकर्ता आइटम के नाम पर टाइप करते हैं और इनपुट फॉर्म में इसके अनुरूप मूल्य टाइप करते हैं, जो तब दिखाई देता है जब फॉर्म Django बैकएंड को सबमिट किया जाता है।
अपने एचटीएमएल फॉर्म में मैंने कुछ जावास्क्रिप्ट शामिल किए हैं ताकि इन मूल्यों का कुल रीफ्रेश किए बिना और फॉर्म जमा करने से पहले तुरंत दिखाई दे।
मेरा लक्ष्य:
आईडी Total
के अंतर्गत HTML में Javascript द्वारा गणना की गई कुल राशि भेजें
<th scope="col">Total Equipment and Assets</th>
<th scope="col" id="Total"></th>
कक्षा में
total_assets= models.IntegerField(null=True, blank=True, verbose_name='Total Assets')
प्रस्तुत करने के बाद Model.py में।
ध्यान दें कि प्रश्न का कारण यह है कि कुल मान मैन्युअल रूप से नहीं जोड़े जाते हैं, उनकी गणना सीधे जावास्क्रिप्ट का उपयोग करके की जाती है।
चीजों को और स्पष्ट करने के लिए यहां एक नमूना दिया गया है।
यहाँ एचटीएमएल टेम्पलेट है:
<tr>
<td>
<input
placeholder="Type in the Equipment and assets"
type="text"
class="form-control"
name="item_1"
id="item_1"
{% if form.is_bound %}value="{{ form.item_1.value }}"{% endif %}/>
{% for err in form.item_1.errors %}
<small class="text-danger mb-2 ml-2">{{ err }}</small>
{% endfor %}
</td>
<td>
<h6 style="float:left; margin-right:5px; margin-top:7px">$</h6>
<input
type="number"
class="form-control w-25 subtotal-group subtotal-group-1"
name="item_1_amount"
id="item_1_amount"
{% if form.is_bound %}value="{{ form.item_1_amount.value }}"{% endif %}/>
{% for err in form.item_1_amount.errors %}
<small class="text-danger mb-2 ml-2">{{ err }}</small>
{% endfor %}
</td>
</tr>
<tr>
<td>
<input
placeholder="Type in the Equipment and assets"
type="text"
class="form-control"
name="item_2"
id="item_2"
{% if form.is_bound %}value="{{ form.item_2.value }}"{% endif %}/>
{% for err in form.item_2.errors %}
<small class="text-danger mb-2 ml-2">{{ err }}</small>
{% endfor %}
</td>
<td>
<h6 style="float:left; margin-right:5px; margin-top:7px">$</h6>
<input
autocomplete="off"
type="number"
class="form-control w-25 subtotal-group subtotal-group-1"
name="item_2_amount"
id="item_2_amount"
{% if form.is_bound %}value="{{ form.item_2_amount.value }}"{% endif %}/>
{% for err in form.item_2_amount.errors %}
<small class="text-danger mb-2 ml-2">{{ err }}</small>
{% endfor %}
</td>
</tr>
यहाँ जावास्क्रिप्ट है
<script>
const q=(e,n=document)=>n.querySelector(e);
const qa=(e,n=document)=>n.querySelectorAll(e);
const results={};
console. log(results)
qa('[type="number"].form-control').forEach(input=>input.addEventListener('input',function(e){
results[ this.name ]=Number( this.value );
const resultGroupSet1 = [...qa('.subtotal-group-1')]
.map(s => Number(s.value))
.reduce((a,v) => a+v);
q('th#Total').textContent = resultGroupSet1;
}));
</script>
यहाँ वह जगह है जहाँ कुल HTML टेम्पलेट में परिलक्षित होता है
<thead class="table-light">
<tr>
<th scope="col">Total Equipment and Assets</th>
<th scope="col" id="Total"></th>
</tr>
</thead>
ये है model.py
item_1 = models.CharField(max_length=100,null=True, blank=True, verbose_name='Item 1')
item_1_amount = models.IntegerField(null=True, blank=True, verbose_name='Item 1 Amount')
item_2 = models.CharField(max_length=100,null=True, blank=True, verbose_name='Item 2')
item_2_amount = models.IntegerField(null=True, blank=True, verbose_name='Item 2 Amount')
total_assets = models.IntegerField(null=True, blank=True, verbose_name='Total Assets')
यहाँ विचार है:
def add_bp(request):
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = infoForm(request.POST)
# check whether it's valid:
if form.is_valid():
form.save()
b_name = form.cleaned_data.get('bName')
messages.success(request, f'PDF created for {b_name}!')
return redirect('application:core')
# if a GET (or any other method) we'll create a blank form
else:
form = infoForm()
return render(request, 'application/template.html', {'form': form, })
4 जवाब
एचटीएमएल को इसमें अपडेट करें:
<thead class="table-light">
<tr>
<th scope="col">Total Equipment and Assets</th>
<th scope="col">
<!-- Value which is visible (calculated using JS) -->
<span id="Total"></span>
<!-- Add a hidden input to store value (value calculated and assigned using JS) -->
<input type="hidden" name="total_assets" value="0" id="total_assets">
</th>
</tr>
</thead>
resultGroupSet1
को इस रूप में असाइन करने के लिए स्क्रिप्ट अपडेट करें:
id=Total
के साथ स्पैन टैग के लिए पाठ्य सामग्रीname=total_assets
के साथ छिपे हुए इनपुट का मान
// Assign result to span tag which is visible
q('span#Total').textContent = resultGroupSet1;
// Assign result as value to hidden input field with name total_assets
q('input#total_assets').value = resultGroupSet1;
विचारों में कोई अन्य परिवर्तन नहीं।
name="total_assets"
के साथ एक इनपुट फ़ील्ड के रूप में उपयोग किया जाता है, मान अनुरोध निकाय को पास कर दिया जाएगा और request.POST
पर पहुंच योग्य होगा। यहां, जैसा कि total_assets
फ़ील्ड छिपा हुआ है, यह उपयोगकर्ताओं को दिखाई नहीं देता है और फिर भी फ़ॉर्म सबमिट होने पर POST डेटा में मान उपलब्ध होता है। इसलिए, जब form.save()
को परिकलित मान कहा जाता है (JS का उपयोग करके) सहेजा जाएगा।
मुझे लगता है कि आपका प्रश्न यह है कि इस तत्व में मूल्य कैसे प्राप्त करें:
<th scope="col" id="Total"></th>
आप बस अपने एचटीएमएल कोड में इनपुट तत्व जोड़ सकते हैं और उसमें नाम जोड़ सकते हैं:
<th scope="col"><input id="Total" name="total_assets" value=""></th>
फिर आपके विचार.py में:
def add_bp(request):
if request.method == 'POST':
form = infoForm(request.POST)
if form.is_valid():
form.save()
आप मैन्युअल रूप से भी कुल प्राप्त कर सकते हैं:
def add_bp(request):
if request.method == 'POST':
total_assets = request.POST.get("total_assets")
संभवत: आप जो खोज रहे हैं वह <input type="hidden" ...>
है, यह अंतिम उपयोगकर्ता द्वारा दिखाई नहीं देता है और इसे सबमिट फ़ॉर्म में शामिल किया जाता है
Django बैकएंड में यह गणना क्यों नहीं करते?
मेरा सुझाव है कि सभी तर्कों को सामान्य रूप से पारित किया जाए और केवल एक श्रोता को मॉडल की बचत में जोड़ा जाए (हर बार जब आप किसी तत्व को तालिका में सहेजेंगे तो कोड का यह छोटा टुकड़ा इसे सहेजने से ठीक पहले चलेगा):
from django.db.models.signals import pre_save
from django.dispatch import receiver
@receiver(pre_save, model_class)
def form_pre_save(instance, *args, **kwargs):
instance.total_assets = instance.item_1_amount + instance.item_2_amount
इस तरह जब आप इस प्रकार के तत्व को किसी भिन्न स्थान पर सहेजना चाहते हैं (उदाहरण के लिए बैकएंड में) तो आपको ऐसा करने वाले कोड को दोबारा नहीं लिखना होगा, बल्कि केवल इंस्टेंस को सहेजना होगा।
आप सिग्नल प्री_सेव फ़ंक्शन के बारे में अधिक पढ़ सकते हैं यहां
NOT NULL
dalam contoh Anda tidak melibatkan JSON.