Как снять флажок «Удалить» в дополнительных формах во встроенном наборе форм Django

Я использую встроенные наборы форм в Django и для каждого элемента, показывающего одну «дополнительную» форму, для добавления другого объекта.

Формы для существующих объектов имеют флажки «Удалить» для удаления этого объекта, что имеет смысл.

Но также в «лишних» формах есть эти флажки «Удалить»… что не имеет смысла, потому что там нечего удалять. Встроенные формы в панели администратора Django не отображают эти флажки «Удалить» для «дополнительных» форм.

Как я могу удалить эти флажки в «лишних» встроенных формах?

Часть встроенных наборов форм в моем шаблоне выглядит примерно так (упрощенная, полная версия на GitHub):

{% for bookimage_form in form.forms %}
  {% for hidden_field in bookimage_form.hidden_fields %}
    {{ hidden_field.errors }}
  {% endfor %}

  {{ bookimage_form.as_table }}
{% endfor %}

А вот и галочка «Удалить», которая кажется лишней:

пример скриншота


person Phil Gyford    schedule 22.03.2018    source источник


Ответы (5)


Вы можете использовать can_delete настройка класса InlineModelAdmin (TabularInline наследуется от InlineModelAdmin):

class BookImageInline(admin.TabularInline):
    model = BookImage
    extra = 1
    can_delete = False
person bonidjukic    schedule 22.03.2018
comment
Спасибо, но... я не хочу менять это в админке. И если я устанавливаю can_delete=False при создании встроенных наборов форм с помощью inlineformset_factory(), то это отключает все флажки Удалить — я хочу сохранить их в формах, содержащих существующие объекты. - person Phil Gyford; 22.03.2018
comment
Ах, извините, я не получил эту часть. Я предполагаю, что этот флажок существует на случай, если вы заполните данные в этом наборе форм, передумаете и не захотите сбрасывать все поля одно за другим. Можно ли скрыть этот флажок с помощью css? - person bonidjukic; 22.03.2018
comment
Это можно скрыть с помощью CSS, но я бы предпочел сделать это правильно. И если это цель этого поля «Удалить», почему их нет во встроенных формах в админке? (Я не жду от вас ответа!) Это очень странно. - person Phil Gyford; 22.03.2018

вот способ добраться туда в шаблоне, когда вы перебираете формы:

{% if bookimage_form.instance.pk %}
  <small><b>{{ bookimage_form.DELETE.label_tag }}</b></small><br>
  {{ bookimage_form.DELETE}}
{% else %}
{% endif %}

я не думаю, что вы сможете использовать метод as_table(). Вам нужно будет выразить каждое другое поле в форме.

Вот еще одна вещь, которую вы можете попробовать после инициализации формы, но до того, как она войдет в контекст:

for f in form.forms: 
    if not f.instance.pk: 
        f.fields['DELETE'] = None 

Не знаю, как это отразится в таблице, но вы можете поэкспериментировать с этой идеей.

person rick debbout    schedule 15.10.2018

Обновление для Django 3.2+ (ссылка ), теперь вы можете передать can_delete_extra как False в formset_factory или его расширенные классы, чтобы удалить флажок из дополнительных форм

can_delete_extra Новое в Django 3.2.

BaseFormSet.can_delete_extra

По умолчанию: Истина

При установке can_delete=True указание can_delete_extra=False удалит возможность удаления дополнительных форм.

Для тех, кто имеет версию Django ниже 3.2 и не хочет обновляться, используйте следующий метод переопределения BaseFormSet:

class CustomFormSetBase(BaseModelFormSet):
        
    def add_fields(self, form, index):
        super().add_fields(form, index)
        if 'DELETE' in form.fields and form.instance.pk: # check if have instance
            form.fields['DELETE'] = forms.BooleanField(
                label=_('Delete'),
                widget=forms.CheckboxInput(
                    attrs={
                        'class': 'form-check-input'
                    }
                ),
                required=False
            )
        else:
            form.fields.pop('DELETE', None)


YourFormSet = modelformset_factory(
                formset=CustomFormSetBase,
                can_delete=True,
                extra=2
            )

им потребовалось всего 13 лет, чтобы добавить это ›.› https://code.djangoproject.com/ticket/9061

person Linh Nguyen    schedule 20.04.2021

Я предлагаю отобразить шаблон во вложенных циклах for и добавить следующее:

 {% if forloop.parentloop.last and forloop.last%}
     not render form filds
 {% else %}
     render field
 {% endif %}
person Lorenzo Fiamingo    schedule 29.12.2018