我有一个表单,用户可以添加多个项目,这些项目将显示在表格中,然后如果用户点击保存按钮,所有这些项目将保存到数据库,但我不知道该怎么做。请问有人能给我一个想法吗?
这是我必须处理的表格
在屏幕截图中,有一个添加按钮将添加到下表中,然后有保存按钮将发布到数据库。
我现在只创建了一个模型和表单
class OpeningStock(models.Model):
office = models.ForeignKey(OfficeSetup, blank=True, null=True, on_delete=models.CASCADE)
miti = models.DateTimeField(null=True)
item_group = models.ForeignKey(ItemGroup, blank=True, null=True)
item = models.ForeignKey(Item, blank=True, null=True)
department = models.ForeignKey(DepartmentSetup, blank=True, null=True)
employee = models.ForeignKey(Employee, blank=True, null=True)
quantity = models.PositiveIntegerField(default=0)
value = models.DecimalField(default=0.0, max_digits=100, decimal_places=2)
specification = models.CharField(blank=True, null=True, max_length=600)
remarks = models.TextField(blank=True, null=True)
def stock(request):
form = StockForm(request.POST or None)
if request.method == "POST" and form.is_valid():
office_instance = OfficeSetup.objects.get(user=request.user)
new_form = form.save(commit=False)
new_form.office = office_instance
new_form.save()
messages.success(request, 'Thank you')
return redirect('stock')
messages.warning(request, "Correct the errors below")
stocks = OpeningStock.objects.all()
context = {
"form": form,
"stocks": stocks
}
return render(request, 'dashboard/stocks/stock.html', context)
{% block content %}
<div class="right_col" role="main">
<h1 class="text-center">Stock</h1>
<div class="space"></div>
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
</form>
</div>
<div class="stock-list">
{% include 'dashboard/stocks/stock_adjustment_list.html' %}
</div>
{% endblock content %}
有人能告诉我一个简单的例子/演示来解决这个问题吗?
答案 0 :(得分:1)
好的,为了回应您的评论,我创建了一个简化的Django应用程序来演示解决方案,
注意:我已从表中删除了除一个外键和相应值之外的所有键,并且我还将所有模板合并为一个(没有任何样式)。
源代码可以在这里找到: https://github.com/kujosHeist/stack-overflow-django
肯定有更好的方法可以做到这一点,但我的解决方案是,每次单击“添加”按钮时,表格都会使用值进行更新,并且值将存储在对象列表中。 然后单击“提交”时,它会遍历对象列表并将数据发布到后端以进行存储。
有一种方法可以将整个对象列表一起发送,但是django / ajax会对列表进行笨拙的处理,所以现在分开发送它们会更容易。
另外,我在后端手动创建对象,而不是使用表单,但是应该有一种方法可以在发布之前将JavaScript对象存储在FormData对象中,这样就可以使用form.is_valid()和form.save() 但为了简单起见,我避免了这一点。
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<div class="right_col" role="main">
<h1 class="text-center">Stock</h1>
<div class="space"></div>
<form class="stock-form form-group">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="Submit">
</form>
<button class="btn btn-primary add-stock" id="add-button">Add</button>
</div>
<div class="stock-list">
<table class="table table-striped stock-table">
<thead>
<tr>
<th>#</th>
<th>Item</th>
<th>Miti</th>
<th>Quantity</th>
<th>Value</th>
<th>Specification</th>
<th>Remarks</th>
</tr>
</thead>
<tbody id="table-body">
<!-- here how should i show all those added items -->
</tbody>
</table>
</div>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script>
var itemCount = 0;
var objList = [];
$(document).ready(function() {
$("#add-button").on("click", function(){
// store values in object and add them to list
var obj = {};
obj['date'] = $('#id_miti').val();
obj['item_id'] = $('#id_item').val();
// (adding itemCount to values so all they all aren't the same)
obj['quantity'] = $('#id_quantity').val() + itemCount;
obj['value'] = $('#id_value').val() + itemCount;
obj['specification'] = $('#id_specification').val();
obj['remarks'] = $('#id_remarks').val();
objList.push(obj);
// get item name for displaying in table
var e = document.getElementById("id_item");
var itemName = e.options[e.selectedIndex].innerText;
// add object to table
$("#table-body").append("<tr>");
$("#table-body").append("<td>" + itemName + "</td>");
$("#table-body").append("<td>" + (itemCount++) + "</td>");
$("#table-body").append("<td>" + obj['date'] + "</td>");
$("#table-body").append("<td>" + obj['quantity'] + "</td>");
$("#table-body").append("<td>" + obj['value'] + "</td>");
$("#table-body").append("<td>" + obj['specification'] + "</td>");
$("#table-body").append("<td>" + obj['remarks'] + "</td>");
$("#table-body").append("</tr>");
console.log("Added object to table:")
console.log(obj);
});
$('.stock-form').submit(function(e) {
e.preventDefault();
if(objList.length > 0){
var token = "{{csrf_token}}";
// loop through object list and post to back end
// could send them all together, but ajax/django handles list of objects
// awkwardly
for(var i = 0; i < objList.length; i++){
var data = objList[i];
data['csrfmiddlewaretoken'] = token
$.ajax({
type: 'post',
url: '',
data: data,
success: function(data) {
console.log("Success!")
console.log('data', data);
}
});
}
}
});
});
</script>
from django.shortcuts import render, redirect
from django.core.urlresolvers import reverse
import json
from .models import OpeningStock, Item
from django.http import HttpResponse
from .forms import OpeningStockForm
from dateutil import parser
def index(request):
form = OpeningStockForm(request.POST or None)
if request.method == "POST":
# manually retrieve fields and create object
data = request.POST
date = parser.parse(data['date'])
# get item from db, make sure you add some sample items to the db
item = Item.objects.get(pk=data["item_id"])
s = OpeningStock(item=item, miti=date, quantity=data['quantity'], value=data['value'], specification=data['specification'], remarks=data['remarks'])
s.save()
return HttpResponse(json.dumps({'result': 'success', 'data': request.POST}))
else:
context = {}
context['form'] = form
return render(request, 'question1/index.html', context)
from django.db import models
from django.utils import timezone
class Item(models.Model):
name = models.CharField(max_length=32)
class OpeningStock(models.Model):
item = models.ForeignKey(Item, blank=True, null=True)
miti = models.DateTimeField(null=True, default=timezone.now)
quantity = models.PositiveIntegerField(default=34)
value = models.DecimalField(default=2.5, max_digits=100, decimal_places=2)
specification = models.CharField(blank=True, null=True, max_length=600, default="Sample Spec")
remarks = models.TextField(blank=True, null=True, default="Sample remarks")
from django.forms import ModelForm
from django import forms
from .models import Item
from question1.models import OpeningStock
class OpeningStockForm(ModelForm):
item = forms.CharField(
widget=forms.Select(
choices=Item.objects.all().values_list('id', 'name')
)
)
class Meta:
model = OpeningStock
fields = ["item","miti","quantity","value","specification","remarks"]
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name="index"),
]