如果引发 ValidationError,删除链接会在 Django 管理内联表单集中消失

发布于 2024-12-06 09:19:39 字数 1553 浏览 0 评论 0原文

我有一个带有 KeywordInline 的表单。当我使用表单内联表单集添加新对象时,有一个 js 链接将新表单添加到表单集中。新添加的表单有一个启用js的删除按钮(右侧的x标记)。

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)

现在,如果我点击保存按钮并且 ValidationError 上升,那么这些删除按钮就会从 fromset 中消失。因此,如果我错误地添加了错误的关键字,我将无法删除它。

这是正常行为吗?我怎样才能让删除链接持续存在?

非常感谢任何帮助。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

活泼老夫 2024-12-13 09:19:40

触发 ValidationError 的内联没有删除链接,因为它们尚未保存到数据库中,因此没有删除链接。

我意识到这是不一致的行为(因为您可以在点击“保存”按钮之前删除这些行,但是一旦它们触发验证错误就不能),但这是 Django 的正常默认方式。

要解决此问题,您可以覆盖内联模板 并使删除按钮显示,尽管验证错误。

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.

千秋岁 2024-12-13 09:19:40

我在 django 2.2 首先遇到这个问题

(不工作)我尝试创建删除链接

  • 重复的 admin/edit_inline/tabular.html 以在项目中编辑

  • 更改为使用新模板

     类 MyAdminInline(admin.TabularInline):
          # ...其他东西
          模板 = 'admin/edit_inline/tabular.html'
    
  • 添加一些脚本

     {% load i18n admin_urls static admin_modify %}
      <脚本类型=“text/javascript”>
          函数removeRowById(id,索引){
          document.getElementById(id).remove();
      }
      
    
  • 编辑如何显示删除链接

     
          {% if inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }}{% endif %}
          {% if not inline_admin_form.original %}  {% 结束 %}
      
    
  • 它显示链接按钮,但在保存时。 django 向我抛出另一个错误。
    所以这种方式不会在 inline_admin_formset 内更新

第二个(工作)我尝试另一种方式

  • 只是更改删除复选框的显示方式

     
          {% if inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }}{% endif %}
      
    

    <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>

字段不是原始字段(有 pk)并且存在验证错误时显示删除复选框

在此处输入图像描述

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

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文