Django内联formset添加另一个并删除

时间:2015-02-17 04:51:25

标签: django django-forms django-templates django-views

我正在尝试在django中构建以下链接功能, http://demo.smarttutorials.net/jquery-autocomplete/

这里选择serial_no,其余字段名称和作者应自动填充。自动填充适用于第一个内联formset并能够保存它但是当我添加另一个内联formset时,自动填充不起作用,我无法删除它或保存它。

models.py

from django.db import models

class Book(models.Model):
    serial_no = models.IntegerField(max_length = 100, unique = True)
    name = models.CharField(max_length = 50)
    author = models.CharField(max_length = 50)

    def __unicode__(self):
        return self.name

class CustomerOrder(models.Model):
    name = models.CharField(max_length=256)

    def __unicode__(self):
        return self.name

class Order(models.Model):
    customer  =  models.ForeignKey(CustomerOrder)
    serial_no = models.IntegerField(max_length = 100, unique = True)
    name = models.CharField(max_length = 50)
    author = models.CharField(max_length = 50)
    quantity = models.IntegerField(max_length = 100)

    def __unicode__(self):
        return self.name

forms.py

from django import forms
from bookapp.models import CustomerOrder


class CustomerOrderForm(forms.ModelForm):
    class Meta:
        model = CustomerOrder
        exclude = ('customer',)

views.py

from django.http import HttpResponse
from django.shortcuts import render
from bookapp.models import *
from bookapp.forms import CustomerOrderForm
import json
from django.core.exceptions import ObjectDoesNotExist
from django.http import HttpResponseRedirect
from django.template import RequestContext
from django.core.context_processors import csrf
from django.shortcuts import render_to_response, get_object_or_404
from django.forms.models import inlineformset_factory


def home(request):
    context =  RequestContext(request)
    OrderFormSet =   inlineformset_factory(CustomerOrder, Order  ,extra=1, exclude=('customer',))
    if request.method == "POST":
        customerorderform = CustomerOrderForm(request.POST)
        orderformset = OrderFormSet(request.POST)
        if customerorderform.is_valid() and orderformset.is_valid():
            a = customerorderform.save()
            orderformset.save(commit=False)
            orderformset.instance = a
            orderformset.save()
            return HttpResponse('Added')
    else:
        customerorderform = CustomerOrderForm()
        orderformset = OrderFormSet()
        for orderform in orderformset:
            orderform.fields['serial_no'].widget.attrs = {'id' : 'sno', 'onkeydown':"myFunction()"}
            orderform.fields['name'].widget.attrs = {'id' : 'bname'}
            orderform.fields['author'].widget.attrs = {'id' : 'bauthor'}

    args = {}
    args.update(csrf(request))
    args = {'customerorderform':customerorderform, 'orderformset':orderformset}
    return render_to_response('home.html',args,context)

def fetch_serial_nos(request):
    serial_nos = map(lambda x: str(x.serial_no), Book.objects.all())
    return HttpResponse(content = json.dumps({'serial_nos': serial_nos}), content_type = "application/json; charset=UTF-8")

def get_entry_corresponds_to_serial_no(request):
    serial_no = request.GET['serial_no']
    try: 
        entry = Book.objects.get(serial_no=int(serial_no))
        data = {'name': entry.name, 'author': entry.author}
    except (ObjectDoesNotExist, ValueError):
        data = {'name': '', 'author': ''}
    return HttpResponse(content = json.dumps(data), content_type = "application/json; charset=UTF-8")

home.html的

<script src="{{ STATIC_URL }}js/min.js"></script>
<script src="{{ STATIC_URL }}js/jquery.formset.js"></script>


<p>Enter S.NO</p>
<script type="text/javascript">
    $(function() {
        $(".inline.{{ orderformset.prefix }}").formset({
            prefix: "{{ orderformset.prefix }}",
        })
    })
</script>
<body>
    <div>
        <h1>Orders</h1>
        <form action="/"  method="post">{% csrf_token %}
            <div>
                <legend>Customer</legend>
                {{customerorderform}}
            </div>
           <fieldset>
                <legend>Order</legend>
                {{ orderformset.management_form }}
                {{ orderformset.non_form_errors }}
                {% for form in orderformset %}
                    {{ form.id }}
                    <div class="inline {{ orderformset.prefix }}">
                        {{form}}
                    </div>
                {% endfor %}
            </fieldset>
            <input type="submit" value="Add order" class="submit" />
        </form>
    </div>
</body>
<p id="demo"></p>


<script>
$(function(){
    $.ajax({
        type: "GET",
        url: '/serial_nos/',        
        success: function (response) {
        serial_nos = response['serial_nos'];
        $( "#sno" ).autocomplete({
            source: serial_nos
         });
        },        
    });   
    });
function myFunction(){ 
    var sno = document.getElementById("sno").value;
    console.log(sno)
    document.getElementById("demo").innerHTML = "You selected: " + sno;
    $.ajax({
        type: "GET",
        url: '/entry/',
        data : {
            serial_no : sno,
        },        
        success: function (response) {
            console.log('success') 
            bname.value = response['name'];
            bauthor.value = response['author'];

        },        
    });
  }  
</script>

1 个答案:

答案 0 :(得分:2)

您的代码中存在多个问题。

  1. 您为多个HTML元素设置了相同的ID,这完全不正确。 ID的含义是唯一的。当您按ID搜索元素时,它将只返回一个(第一个匹配的元素)。
  2. 仅在初始页面加载时初始化自动填充。相反,您需要为formset javascript创建的每个新行初始化它。这可以通过使用added选项中配置的formset回调来完成。请在文档https://code.google.com/p/django-dynamic-formset/wiki/Usage#Formset_options
  3. 中查找详细信息

    我也有一些建议让你的代码在意识形态上更正确。

    1. 不要使用from module import *
    2. 重新排序您的导入(第一个从标准库中导入,第二个从框架中导入,最后从您的项目中输入)
    3. 不要设置onkeydownonclick等python属性。使用Javascrirpt。 (这可能比前两个更重要)