【问题标题】:Django dynamic fields - cannot get data from multiples added rows from TemplateDjango动态字段 - 无法从模板中获取多个添加行的数据
【发布时间】:2020-02-02 07:15:08
【问题描述】:

我正在开发一个动态生成多行的模板。

当我提交表单时,我无法从模板中获取所有生成的行。只保存最后一个。

我想我缺少从生成的行中获取数据的东西。

这是我的代码:

models.py

class Product(models.Model):
    contractNumber = models.ForeignKey('SupportContract', on_delete=models.SET_NULL, null=True)
    serialNumber = models.CharField(max_length=800, null=True)
    reference = models.ForeignKey('ProductDescription', on_delete=models.SET_NULL, null=True)
    quantity = models.IntegerField()

    def __str__(self):
        return str(self.serialNumber) if self.serialNumber else ''

form.py

class ProductForm(forms.ModelForm):
    contractNumber = forms.ModelChoiceField(required=False, queryset=SupportContract.objects.all().order_by('number'), label='contractNumber', widget=forms.TextInput(attrs={'class': 'form-control','placeholder': 'Contract number'}))
    serialNumber = forms.CharField(required=True, label='serialNumber',widget=forms.TextInput(attrs={'class': 'form-control','placeholder': 'Enter serial number'}))
    reference = forms.ModelChoiceField(required=False, queryset=ProductDescription.objects.all().order_by('name'), label='reference',widget=forms.TextInput(attrs={'class': 'form-control','placeholder': 'Product descrition'}))
    quantity = forms.IntegerField(initial=1, required=True, label='quantity',widget=forms.NumberInput(attrs={'class': 'form-control','placeholder': 'Enter a quantity'}))

    class Meta:
        model = Product
        fields = '__all__'

    def clean(self):
        super().clean()
        contractNumber = self.cleaned_data.get('contract_number')
        serialNumber = self.cleaned_data.get('serial_number')
        reference = self.cleaned_data.get('product_reference')
        quantity = self.cleaned_data.get('quantity')

ProductFormset = formset_factory(ProductForm, extra=1)

template.html

<div data-role="dynamic-fields">
    {{ form_Product.management_form }}
    <div class="form-inline"  style="margin-left: -15px">
        <div class="form-group col-md-2">
            {{ form_Product.quantity }}
        </div>
        <div class="form-group col-md-2">
            {{ form_Product.serialNumber }}
        </div>
        <div class="form-group col-md-2">
    <button class="btn btn-danger" data-role="remove">
        <span class="fas fa-minus"></span>
    </button>
    <button class="btn btn-primary" data-role="add">
        <span class="fas fa-plus"></span>
    </button>
</div></div></div>

views.py

def form_exhibit_c(request):

    template_name = 'supportContract/ExhibitCtemplate.html'
    if request.method == 'GET':
        formset = ProductFormset(request.GET or None)
        form_SupportContract = SupportContractForm(request.GET or None)
        form_ProductDescription = ProductDescriptionForm(request.GET or None)
    elif request.method == 'POST':
        formset = ProductFormset(request.POST)
        form_SupportContract = SupportContractForm(request.POST)
        form_ProductDescription = ProductDescriptionForm(request.POST)

        form_SupportContract.save(commit=False)
        form_ProductDescription.save(commit=False)

        if formset.is_valid():
            for form in formset:
                serialNumber = form.cleaned_data.get('serialNumber')

                if serialNumber :
                    p = Product.objects.create(serialNumber=serialNumber, quantity='1')
    else:
        form_SupportContract = SupportContractForm()
        form_ProductDescription = ProductDescriptionForm()
        formset = ProductForm()

    return render(request, template_name, {'form_Product' : formset, 'form_ProductDescription': form_ProductDescription, 'form_SupportContract' : form_SupportContract})

dynamicFields.js

    // Remove button click
    $(document).on(
        'click',
        '[data-role="dynamic-fields"] > .form-inline [data-role="remove"]',
        function(e) {
            e.preventDefault();
            $(this).closest('.form-inline').remove();
        });
    // Add button click
    $(document).on(
        'click',
        '[data-role="dynamic-fields"] > .form-inline [data-role="add"]',
        function(e) {
            e.preventDefault();
            var container = $(this).closest('[data-role="dynamic-fields"]');
            new_field_group = container.children().filter('.form-inline:first-child').clone();
            new_field_group.find('input').each(function(){
                if (this.name == 'quantity') {
                    $(this).val('1');
                }else{
                    $(this).val('');
                }
            });
            container.append(new_field_group);
        });
});

【问题讨论】:

    标签: javascript python django templates dynamic


    【解决方案1】:

    我让它在 js 中为 ID 表单添加增量/减量。

    代码如下:

    $(function() {
        function updateIdForm(container, nb_fields){
            field_group = container.children().filter('.form-inline:visible');
            var cpt = 0;
            var flag_input = 0;
            field_group.find('input').each(function(){
                if(flag_input >= nb_fields){
                    cpt++;
                    flag_input=0;
                };
                flag_input++;
                var input = $(this);
                var name = input.attr('name').split('-', 3);
                var id = input.attr('id').split('-', 3);
                $(this).attr('id', id[0] + '-' + cpt + '-' + id[2]);
                $(this).attr('name', name[0] + '-' + cpt + '-' + name[2]);
            });
        };
    
        function countFields(container, row_nb_row){
            var l_cpt=0;
            field_group = container.children().filter('.form-inline:visible');
            field_group.find('input').each(function(){
                l_cpt++;
            });
            var fields = l_cpt/(row_nb_row+1);
            return fields;
        };
    
        var nb_row = 0;
    
        // Remove button click
        $(document).on(
            'click',
            '[data-role="dynamic-fields"] > .form-inline [data-role="remove"]',
            function(e) {
                e.preventDefault();
                var container = $(this).closest('[data-role="dynamic-fields"]');
                $('#id_form-TOTAL_FORMS').val(parseInt($('#id_form-TOTAL_FORMS').val()) - 1);
                var nb_fields = countFields(container, nb_row);
                $(this).closest('.form-inline').remove();
                updateIdForm(container, nb_fields);
                nb_row--;
            }
        );
        // Add button click
        $(document).on(
                'click',
                '[data-role="dynamic-fields"] > .form-inline [data-role="add"]',
                function(e) {
                    e.preventDefault();
                    nb_row++;
                    var container = $(this).closest('[data-role="dynamic-fields"]');
                    new_field_group = container.children().filter('.form-inline:first-child').clone();
                    new_field_group.find('input').each(function(){
                        var input = $(this);
                        var name = input.attr('name').split('-', 3);
                        var id = input.attr('id').split('-', 3);
                        $(this).attr('id', id[0] + '-' + nb_row + '-' + id[2] )
                        $(this).attr('name', name[0] + '-' + nb_row + '-' + name[2] )
                        $(this).val('');
                    });
                    $('#id_form-TOTAL_FORMS').val(parseInt($('#id_form-TOTAL_FORMS').val()) + 1);
                    container.append(new_field_group);
                    var nb_fields = countFields(container, nb_row);
                    updateIdForm(container, nb_fields);
                });
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-24
      • 2023-03-30
      • 2016-08-11
      • 2016-07-18
      相关资源
      最近更新 更多