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
精彩评论