处理两个差异动作,添加和保存

时间:2017-11-30 01:44:26

标签: python django python-3.x django-forms django-views

我有一个表单,用户可以添加多个项目,这些项目将显示在表格中,然后如果用户点击保存按钮,所有这些项目将保存到数据库,但我不知道该怎么做。请问有人能给我一个想法吗?

这是我必须处理的表格

enter image description here

在屏幕截图中,有一个添加按钮将添加到下表中,然后有保存按钮将发布到数据库。

我现在只创建了一个模型和表单

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 %}

有人能告诉我一个简单的例子/演示来解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

好的,为了回应您的评论,我创建了一个简化的Django应用程序来演示解决方案,

注意:我已从表中删除了除一个外键和相应值之外的所有键,并且我还将所有模板合并为一个(没有任何样式)。

源代码可以在这里找到: https://github.com/kujosHeist/stack-overflow-django

肯定有更好的方法可以做到这一点,但我的解决方案是,每次单击“添加”按钮时,表格都会使用值进行更新,并且值将存储在对象列表中。 然后单击“提交”时,它会遍历对象列表并将数据发布到后端以进行存储。

有一种方法可以将整个对象列表一起发送,但是django / ajax会对列表进行笨拙的处理,所以现在分开发送它们会更容易。

另外,我在后端手动创建对象,而不是使用表单,但是应该有一种方法可以在发布之前将JavaScript对象存储在FormData对象中,这样就可以使用form.is_valid()和form.save() 但为了简单起见,我避免了这一点。

的index.html

<!-- 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>

views.py

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)

models.py

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")

forms.py

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"]

urls.py

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^$', views.index, name="index"),
]