django -dynami c -formset проблема при удалении - PullRequest
1 голос
/ 15 января 2020

Когда я пытаюсь удалить строку, набор форм отправляет мне следующую ошибку [{}, {}, {}, {'id': ['This field is required']}]. Если я изменю следующий параметр can_delete=True внутри modelformset_factory, я могу удалить объект, но строки будут отображаться даже после нажатия кнопки удаления. Я попытался добавить {% if form.instance.pk %}{{ form.DELETE }}{% endif %} в шаблон, это ничего не изменило.

Я использую django 2.2 и django -dynami c -formset , country_fr / en происходит от modeltranslation .

Просмотры

@login_required
def view_countries(request):
    CountryFormSet = modelformset_factory(
        Country,
        fields=('country_fr', 'country_en'),
        formset=BaseCountryFormSet,
        can_delete=True)
    if request.method == 'POST':
        formset = CountryFormSet(request.POST)
        if formset.is_valid():
            formset.save()
    else:
        formset = CountryFormSet()
    context = {
        'formset': formset,
        'menu': 'cards',
        'menu_cards': 'countries',
        'model': _('countries'),
        'fields': [_('countries')+' [fr]', _('countries')+' [en]'],
    }
    return render(request, 'cards/index_formset.html', context)

Html

<form method="post" class="mt-2">
  {% csrf_token %}
  {{ formset.management_form }}

  {% for form in formset %}
  <div id="form" class="row_formset d-flex text-center mb-1">
    {% if form.instance.pk %}{{ form.DELETE }}{% endif %}
    {% for field in form.hidden_fields %}
    <div class="invisible">
      {{ field }}
    </div>
    {% endfor %}
    {% for field in form.visible_fields %}
    <div class="flex-fill field">
      {{ field }}
    </div>
    {% endfor %}
  </div>
  {% endfor %}

  <div class="d-flex mt-2 justify-content-center">
    <input type="submit" value="{% trans 'submit'|capfirst %}" class="btn btn-primary"/>
  </div>
</form>

Формы

class BaseCountryFormSet(BaseModelFormSet):
    def clean(self):
        if any(self.errors):
            raise forms.ValidationError(
                _('Errors : ')+f'{self.errors}'+'.',
                code='unknow_error'
            )
        countries_fr = []
        countries_en = []
        duplicates = False
        for form in self.forms:
            if form.cleaned_data:
                country_fr = form.cleaned_data['country_fr']
                country_en = form.cleaned_data['country_en']

                # Check that no row have the same country_fr or country_en
                if country_fr and country_en:
                    if country_fr in countries_fr:
                        duplicates = True
                    countries_fr.append(country_fr)

                    if country_en in countries_en:
                        duplicates = True
                    countries_en.append(country_en)

                if duplicates:
                    raise forms.ValidationError(
                        _('Some entries are duplicated.'),
                        code='duplicate_row'
                    )

                # Check that all row have both country_fr and country_en
                if country_en and not country_fr:
                    raise forms.ValidationError(
                        _('Some french entries are missing.'),
                        code='missing_country_fr'
                    )
                elif country_fr and not country_en:
                    raise forms.ValidationError(
                        _('Some english entries are missing.'),
                        code='missing_country_en'
                    )

Модели

class Country(models.Model):
    country = models.CharField(_('country'), max_length=100)
    slug = models.SlugField(editable=False, max_length=100)

    def save(self, *args, **kwargs):
        self.slug_fr = slugify(self.country_fr, allow_unicode=False)
        self.slug_en = slugify(self.country_en, allow_unicode=False)
        super().save(*args, **kwargs)

1 Ответ

0 голосов
/ 17 января 2020

Таким образом, проблема возникает из bootstrap, d-flex каждой формы набора форм содержит атрибут !important, который переопределяет display: none; django -dynami c -formset-script.

Я создал собственный класс css, чтобы заменить d-flex. Я сохранил can_delete=True, это очевидно полезно; и я удалил {% if form.instance.pk %}{{ form.DELETE }}{% endif %}.

...