开发者

Delete link disappears in Django admin inline formset if ValidationError raised

开发者 https://www.devze.com 2023-04-07 06:43 出处:网络
I have a form with KeywordInline. When I add new object using the form inlined formset has a js-link to add new form into formset. Newly added forms have a js-enabled delete button (x mark on the righ

I have a form with KeywordInline. When I add new object using the form inlined formset has a js-link to add new form into formset. Newly added forms have a js-enabled delete button (x mark on the right).

KeywordInline

class KeywordInline(admin.TabularInline):
    fields = ('word',)
    model = models.Keyword
    formset = forms.KeywordFromset
    verbose_name = _('Keyword')
    verbose_name_plural = _('Keywords')
    extra = 1
    can_delete = True

    def get_readonly_fields(self, request, obj=None):
        if obj:
            if str(obj.status) == 'Finished':
                self.extra = 0
                self.can_delete = False
                self.max_num = obj.keyword_set.count()
                return ('word',开发者_运维百科)

        self.extra = 1
        self.can_delete = True
        self.max_num = None
        return []

KeywordFromset

class KeywordFromset(BaseInlineFormSet):
    def clean(self):
        super(KeywordFromset, self).clean()
        formset_keywords = set()
        for form in self.forms:
            if not getattr(form, 'cleaned_data', {}).get('word', None):
                keyword = None
            else:
                keyword = form.cleaned_data['word']
            if keyword in formset_keywords:
                form._errors['word'] = ErrorList([_(self.get_unique_error_message([_('Keyword')]))])
            else:
                formset_keywords.add(keyword)

Now if I hit save button and ValidationError rises those delete buttons disappears from fromset. So if I've added wrong keyword mistakenly I cannot delete it.

Is this normal behaviour? And how can I make delete links persist?

Any help is much appreciated.


There's no delete link for the inlines that triggered ValidationError since they aren't yet saved to a database, hence no delete link.

I realize it's inconsistent behavior (since you can delete those rows before hitting "save" button, but you can't once they triggered validation errors), but its normal, default way of how Django does it.

To fix this, you could override the template for inline and make the delete buttons appear despite validation errors.


I have this issue with django 2.2

First (NOT WORKING) I try to create delete link

  • duplicate admin/edit_inline/tabular.html to edit in project

  • change to use new template

      class MyAdminInline(admin.TabularInline):
          # ... other stuff
          template = 'admin/edit_inline/tabular.html'
    
  • add somescript

      {% load i18n admin_urls static admin_modify %}
      <script type="text/javascript">
          function removeRowById(id, index) {
          document.getElementById(id).remove();
      }
      </script>
    
  • edit how to display delete link

      <td class="delete">
          {% if inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }}{% endif %}
          {% if not inline_admin_form.original %} <div><a class="inline-deletelink" onclick="removeRowById('{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}', {{ forloop.counter0 }})">Remove</a></div> {% endif %}
      </td>
    
  • it shows the links button but when saved. django throw another error to me. so this way not update inside the inline_admin_formset

Second (WORKING) I try another way

  • just change how delete checkbox appear from

      <td class="delete">
          {% if inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }}{% endif %}
      </td>
    

to

    <td class="delete">
      {% if inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }}
      {% elif not inline_admin_form.original %}
          {% if inline_admin_form.form.non_field_errors %}
            {{ inline_admin_form.deletion_field.field }}
          {% endif %}
      {% endif %}
    </td>

to display delete checkbox if field is not original (has pk) and has validation error on it

Delete link disappears in Django admin inline formset if ValidationError raised

0

精彩评论

暂无评论...
验证码 换一张
取 消