Ошибка Multi FormSet «Запрещается вызов modelformset_factory без явного определения полей или исключения» - PullRequest
0 голосов
/ 21 октября 2019

modelformset_factory error

"Вызов modelformset_factory без явного определения полей или исключений" запрещен. "

Я хочу создать динамическую форму с несколькими входамиполя добавить или удалить с помощью jQuery. Но я получаю ошибку, когда пытаюсь запустить свой код. Я упомянул мой код, пожалуйста, проверьте и помогите мне решить эту проблему. Спасибо

Я следую инструкциям и коду Github. Вот ссылка

Youtube: https://www.youtube.com/watch?v=Tg6Ft_ZV19M

Код Github: https://github.com/shitalluitel/formset

views.py

def acc_journal(request):
    journalEntryFormset = modelformset_factory(
        AccountsJournalVoucherEntery, form=AccountsPymtVoucherForm)
    form = AccountJournalVoucherForm(request.POST or None)
    journalEntryset = journalEntryFormset(
        request.POST or None, queryset=AccountsJournalVoucherEntery.objects.none(), prefix='journalentries')
    if request.method == 'POST':
        if form.is_valid() and journalEntryset.is_valid():
            try:
                with transaction.atomic():
                    journalvc = form.save(commit=False)
                    journalvc.save()

                    for journalEntry in journalEntryset:
                        entery = journalEntry.save(commit=False)
                        entery.journalvc = journalvc
                        entery.save()
            except IntegrityError:
                print('Error Encountered')
            return redirect('accunts-journal')
    context = {
        'acc_journal_acti': 'active',
        'main_header': 'Accounts',
        'header_heading': 'Journal',
        'acc_journals': Accounts_journal_voucher.objects.all(),
        'form': form,
        'formset': journalEntryset
    }
    return render(request, 'accounts/journal.html', context)

model.py

class Accounts_journal_voucher(models.Model):
    journal_voucher_id = models.AutoField(primary_key=True)
    acc_jurnl_vc_num = models.CharField(max_length=50, blank=False)
    acc_jurnl_vc_loc = models.CharField(max_length=50, blank=False)
    acc_jurnl_vc_date = models.DateField(auto_now=False)
    acc_jurnl_vc_ref_num = models.CharField(max_length=50, blank=True)
    acc_jurnl_vc_total_debit = models.DecimalField(
        max_digits=30, decimal_places=2, blank=True, null=True)
    acc_jurnl_vc_total_credit = models.DecimalField(
        max_digits=30, decimal_places=2, blank=True, null=True)
    acc_jurnl_vc_info = models.TextField(blank=True)
    acc_jurnl_vc_added_by = models.CharField(max_length=200, blank=True)
    acc_jurnl_vc_date_added = models.DateTimeField(
        default=datetime.now, blank=True)

    def __str__(self):
        return self.acc_jurnl_vc_num


class AccountsJournalVoucherEntery(models.Model):
    ajve_id = models.AutoField(primary_key=True)
    ajve_journal_vc = models.ForeignKey(
        Accounts_journal_voucher, related_name='journalvc', on_delete=models.CASCADE)
    ajve_group = models.CharField(max_length=200)
    ajve_account = models.CharField(max_length=200)
    ajve_location = models.CharField(max_length=200, default='')
    ajve_narration = models.CharField(max_length=200, default='')
    ajve_currency = models.CharField(max_length=100)
    ajve_ex_rate = models.IntegerField()
    ajve_debit_amt = models.DecimalField(
        max_digits=99, decimal_places=2, default='')
    ajve_credit_amt = models.DecimalField(
        max_digits=99, decimal_places=2, default='')
    ajve_debit_base = models.DecimalField(
        max_digits=99, decimal_places=2, default='')
    ajve_credit_base = models.DecimalField(
        max_digits=99, decimal_places=2, default='')
    ajve_balance = models.DecimalField(
        max_digits=99, decimal_places=2, default='')
    ajve_added_by = models.CharField(max_length=200, blank=True)
    ajve_date_added = models.DateTimeField(
        default=datetime.now, blank=True)

    def __str__(self):
        return self.ajve_journal_vc

forms.py

class AccountJournalVoucherForm(forms.Form):
    acc_jurnl_vc_num = forms.CharField(label='Voucher Number', initial='JRNL-000369', required=True, widget=forms.TextInput(
        attrs={
            'class': 'form-control'
        }
    ))
    acc_jurnl_vc_loc = forms.CharField(label='Location', required=True, widget=forms.TextInput(
        attrs={
            'class': 'form-control',
            'placeholder': 'LOCATION'
        }
    ))
    acc_jurnl_vc_date = forms.DateField(label='Date', required=True, widget=forms.DateInput(
        attrs={
            'class': 'form-control datepicker',
            'placeholder': '2020-01-12'
        }
    ))
    acc_jurnl_vc_ref_num = forms.CharField(label='Reference No', required=False, widget=forms.TextInput(
        attrs={
            'class': 'form-control',
            'placeholder': 'REFERENCE NUMBER',
        }
    ))
    acc_jurnl_vc_total_debit = forms.DecimalField(label='Total Debit', disabled=True, widget=forms.NumberInput(
        attrs={
            'class': 'form-control'
        }
    ))
    acc_jurnl_vc_total_credit = forms.DecimalField(label='Total Credit', disabled=True, widget=forms.NumberInput(
        attrs={
            'class': 'form-control'
        }
    ))
    acc_jurnl_vc_info = forms.CharField(label='Info', required=False, widget=forms.Textarea(
        attrs={
            'class': 'form-control',
            'placeholder': 'Enter info....'
        }
    ))


class AccountsPymtVoucherForm(forms.Form):
    accountLedger = Accounts_ledger.objects.all().order_by('accunt_ledgr_under')
    accountGroup = Accounts_group.objects.all().order_by('accunt_group_under')
    allAccounts = accountLedger and accountGroup
    ajve_group = forms.ChoiceField(label='Group', required=True, choices=Accountschoices, widget=forms.Select(
        attrs={
            'class': 'form-control',
        }
    ))
    ajve_account = forms.ModelChoiceField(label='Account', required=True, queryset=allAccounts, empty_label='SELECT ACCOUNT', widget=forms.Select(
        attrs={
            'class': 'form-control'
        }
    ))
    ajve_location = forms.ChoiceField(label='Location', required=True, choices=(('Main', 'Main'), ('Abu Dhabi', 'Abu Dhabi')), widget=forms.Select(
        attrs={
            'class': 'form-control'
        }
    ))
    ajve_narration = forms.CharField(label='Narration', required=False, widget=forms.TextInput(
        attrs={
            'class': 'form-control'
        }
    ))
    ajve_currency = forms.ModelChoiceField(label='Currency', required=True, queryset=Master_currency.objects.all().order_by('currency_name'), widget=forms.Select(
        attrs={
            'class': 'form-control'
        }
    ))
    ajve_ex_rate = forms.IntegerField(label='EX. Rate', required=True, widget=forms.NumberInput(
        attrs={
            'class': 'form-control'
        }
    ))
    ajve_debit_amt = forms.DecimalField(label_suffix='Dr. Amount', widget=forms.NumberInput(
        attrs={
            'class': 'form-control'
        }
    ))
    ajve_credit_amt = forms.DecimalField(label_suffix='Cr. Amount', widget=forms.NumberInput(
        attrs={
            'class': 'form-control'
        }
    ))
    ajve_debit_base = forms.DecimalField(label_suffix='Dr. Base', widget=forms.NumberInput(
        attrs={
            'class': 'form-control'
        }
    ))
    ajve_credit_base = forms.DecimalField(label_suffix='Cr. Base', widget=forms.NumberInput(
        attrs={
            'class': 'form-control'
        }
    ))
    ajve_balance = forms.DecimalField(label_suffix='Balance', widget=forms.NumberInput(
        attrs={
            'class': 'form-control'
        }
    ))

HTML-шаблон

{% load crispy_forms_tags %}
<form method="POST">
    {% csrf_token %}
    <fieldset>
        <div class="row">
            <div class="form-group">
                <div class="col-md-3 col-sm-6 col-xs-12">
                    {{ form.acc_jurnl_vc_num|as_crispy_field }}
                </div>
                <div class="col-md-3 col-sm-6 col-xs-12">
                    {{ form.acc_jurnl_vc_date|as_crispy_field }}
                </div>
                <div class="col-md-3 col-sm-6 col-xs-12">
                    {{ form.acc_jurnl_vc_loc|as_crispy_field }}
                </div>
                <div class="col-md-3 col-sm-6 col-xs-12">
                    {{ form.acc_jurnl_vc_ref_num|as_crispy_field }}
                </div>
            </div>
        </div>
    </fieldset>
    <br>
    <br>
    <div class="col-md-12 col-sm-12 col-xs-12">
        {% for entries in formset %}
        <div class="row">
            <div class="form-group">
                <div class="col-md-3 col-sm-4 col-xs-12">
                    {{ entries.ajve_group|as_crispy_field }}
                </div>
                <div class="col-md-3 col-sm-4 col-xs-12">
                    {{ entries.ajve_account|as_crispy_field }}
                </div>
                <div class="col-md-2 col-sm-4 col-xs-12">
                    {{ entries.ajve_location|as_crispy_field }}
                </div>
                <div class="col-md-2 col-sm-4 col-xs-12">
                    {{ entries.ajve_narration|as_crispy_field }}
                </div>
                <div class="col-md-2 col-sm-4 col-xs-12">
                    {{ entries.ajve_currency|as_crispy_field }}
                </div>
                <div class="col-md-2 col-sm-4 col-xs-12">
                    {{ entries.ajve_ex_rate|as_crispy_field }}
                </div>
                <div class="col-md-1 col-sm-4 col-xs-12">
                    {{ entries.ajve_debit_amt|as_crispy_field }}
                </div>
                <div class="col-md-2 col-sm-4 col-xs-12">
                    {{ entries.ajve_credit_amt|as_crispy_field }}
                </div>
                <div class="col-md-2 col-sm-4 col-xs-12">
                    {{ entries.ajve_debit_base|as_crispy_field }}
                </div>
                <div class="col-md-2 col-sm-4 col-xs-12">
                    {{ entries.ajve_credit_base|as_crispy_field }}
                </div>
                <div class="col-md-2 col-sm-4 col-xs-12">
                    {{ entries.ajve_balance|as_crispy_field }}
                </div>
                <div class="col-md-1 col-sm-4 col-xs-12">
                    <button class="btn btn-sm btn-danger remove-form-row" id="{{ formset.prefix }}">X</button>
                </div>
                <div class="col-md-1 col-sm-4 col-xs-12">
                    <button class="btn btn-sm btn-success add-form-row" id="{{ formset.prefix }}">Add</button>
                </div>
            </div>
        </div>
        {% endfor %}
    </div>
    {{ formset.management_form }}
    <div class="row">
        <div class="col-md-12 col-sm-12 col-xs-12">
            <button type="submit" name="submit" class="btn btn-featured btn-blue btn-inverse margin-top-30">
                <span>SAVE NEW JOURNAL VOUCHER</span>
                <i class="et-book-open"></i>
            </button>
        </div>
    </div>
</form>

jQuery script

function updateElementIndex(el, prefix, ndx) {
        var id_regex = new RegExp('(' + prefix + '-\\d+-)');
        var replacement = prefix + '-' + ndx + '-';
        if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex,
            replacement));
        if (el.id) el.id = el.id.replace(id_regex, replacement);
        if (el.name) el.name = el.name.replace(id_regex, replacement);
    }

    function addForm(btn, prefix) {
        var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
        if (formCount < 1000) {
            // Clone a form (without event handlers) from the first form
            var row = $(".item:last").clone(false).get(0);

            // Insert it after the last form
            $(row).removeAttr('id').hide().insertAfter(".item:last").slideDown(300);

            // Remove the bits we don't want in the new row/form
            // e.g. error messages
            $(".errorlist", row).remove();
            $(row).children().removeClass("error");

            // Relabel or rename all the relevant bits
            $(row).find('.formset-field').each(function () {
                updateElementIndex(this, prefix, formCount);
                $(this).val('');
                $(this).removeAttr('value');
                $(this).prop('checked', false);
            });

            // Add an event handler for the delete item/form link
            $(row).find(".delete").click(function () {
                return deleteForm(this, prefix);
            });
            // Update the total form count
            $("#id_" + prefix + "-TOTAL_FORMS").val(formCount + 1);

        } // End if

        return false;
    }


    function deleteForm(btn, prefix) {
        var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
        if (formCount > 1) {
            // Delete the item/form
            var goto_id = $(btn).find('input').val();
            if (goto_id) {
                $.ajax({
                    url: "/" + window.location.pathname.split("/")[1] + "/formset-data-delete/" + goto_id + "/?next=" + window.location.pathname,
                    error: function () {
                        console.log("error");
                    },
                    success: function (data) {
                        $(btn).parents('.item').remove();
                    },
                    type: 'GET'
                });
            } else {
                $(btn).parents('.item').remove();
            }

            var forms = $('.item'); // Get all the forms
            // Update the total number of forms (1 less than before)
            $('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
            var i = 0;
            // Go through the forms and set their indices, names and IDs
            for (formCount = forms.length; i < formCount; i++) {
                $(forms.get(i)).find('.formset-field').each(function () {
                    updateElementIndex(this, prefix, i);
                });
            }
        } // End if

        return false;
    }

    $("body").on('click', '.remove-form-row', function () {
        deleteForm($(this), String($('.add-form-row').attr('id')));
    });

    $("body").on('click', '.add-form-row', function () {
        return addForm($(this), String($(this).attr('id')));
    });

Я хочу добавить multi formSet в свой проект. Я следовал https://github.com/shitalluitel/formset этому коду. Но покажите это сообщение об ошибке в моем терминале: «ImproperlyConfigured: вызов modelformset_factory без явного определения полей или исключений запрещен».

1 Ответ

0 голосов
/ 21 октября 2019

inside views.py изменить эту строку

journalEntryFormset = modelformset_factory( AccountsJournalVouch­erEntery, form=AccountsPymtVoucherF­orm)

на эту

journalEntryFormset = modelformset_factory( AccountsJournalVouch­erEntery, form=AccountsPymtVoucherF­orm, fields={'field_1', 'field_2', 'field_....'})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...