#29087: Impossible to delete pending new inline in admin when invalid (delete
button missing)
-------------------------------+------------------------------------
     Reporter:  Owen Heisler   |                    Owner:  frnhr
         Type:  Bug            |                   Status:  assigned
    Component:  contrib.admin  |                  Version:  2.0
     Severity:  Normal         |               Resolution:
     Keywords:                 |             Triage Stage:  Accepted
    Has patch:  1              |      Needs documentation:  0
  Needs tests:  0              |  Patch needs improvement:  0
Easy pickings:  0              |                    UI/UX:  1
-------------------------------+------------------------------------
Description changed by frnhr:

Old description:

> When adding a new inline record in the Django Admin, it is impossible to
> delete the record if it has had a validation error. This is the most
> evident to the user if he/she accidentally attempts to use the wrong
> inline for some data. For example, if a ContactAdmin has both PhoneInline
> and EmailInline, the user may accidentally enter a phone number in an
> EmailInline record. When attempting to submit the changes, a validation
> error is raised. Seeing the problem, the user would now like to just
> delete the new record that is pending. However, at this point there is no
> '''Delete''' button. Thus the user is forced to either (a) reload the
> change page, discarding any other unrelated pending changes on the page;
> or (b) change the data to make it valid, click '''Save and continue
> editing''', and then delete the offending record before finally saving
> the changes again.
>
> ==== Test code
>
> Consider the following code, where the Django Admin provides access to a
> '''Groups''' page with a '''Persons''' inline.
>
> models.py:
> {{{#!python
> from django.db import models
>
> class Group(models.Model):
>     name = models.CharField(max_length=30)
>
> class Person(models.Model):
>     group = models.ForeignKey(Group, on_delete=models.CASCADE)
>     first_name = models.CharField(max_length=30)
>     last_name = models.CharField(max_length=30)
> }}}
>
> admin.py:
> {{{#!python
> from django.contrib import admin
> from .models import *
>
> class PersonInline(admin.StackedInline):
>     model = Person
>     extra = 0
>
> @admin.register(Group)
> class GroupAdmin(admin.ModelAdmin):
>     inlines = [PersonInline]
> }}}
>
> ==== Steps to reproduce
>
> 1. Go to the Group add page (for example,
> <http://localhost:8000/admin/myapp/group/add/>). Enter a Group name, add
> a Person with first_name and last_name, and click '''Save and continue
> editing'''.
> 2. Change the Group name. Add a second Person for the group, but enter a
> first_name only. A delete button ({{{X}}} icon) is available to discard
> the pending record:
> [[Image(https://s13.postimg.org/6wv1azzyv/image.png)]]
> 3. Click '''SAVE'''. There will be a validation error, as expected,
> because last_name is not provided. However, the '''Delete''' button is
> missing: [[Image(https://s13.postimg.org/3q0hrduyf/image.png)]]
> 4. '''The user is now forced to either (a) fix the validation error or
> (b) reload the page, discarding all unrelated changes on the page. It is
> not possible for the user to fix the validation error by simply
> canceling/deleting the pending new record.'''
>

>
> ----
>
> ==== It is actually worse than that...
>
> Another cause of validation errors can be uniqueness constraints. These
> errors can be difficult to fix and sometimes actually cannot be fixed. So
> it is totally possible that because of a validation error the user is
> **forced to reload the page**, there is no other choice.
>
> Building on the models above, here is an example of a validation error
> that can be unsalvageable for users without the `create` permission for
> groups. New `Council` model is added, a foreign key from `Person` to
> `Council` is created and also a constraint with `unique_together =
> ('council', 'group')` is set.
>
> [[Image(https://i.ibb.co/41gpvgS/Screenshot-2019-08-30-at-21-08-13.png)]]

New description:

 When adding a new inline record in the Django Admin, it is impossible to
 delete the record if it has had a validation error. This is the most
 evident to the user if he/she accidentally attempts to use the wrong
 inline for some data. For example, if a ContactAdmin has both PhoneInline
 and EmailInline, the user may accidentally enter a phone number in an
 EmailInline record. When attempting to submit the changes, a validation
 error is raised. Seeing the problem, the user would now like to just
 delete the new record that is pending. However, at this point there is no
 '''Delete''' button. Thus the user is forced to either (a) reload the
 change page, discarding any other unrelated pending changes on the page;
 or (b) change the data to make it valid, click '''Save and continue
 editing''', and then delete the offending record before finally saving the
 changes again.

 ==== Test code

 Consider the following code, where the Django Admin provides access to a
 '''Groups''' page with a '''Persons''' inline.

 models.py:
 {{{#!python
 from django.db import models

 class Group(models.Model):
     name = models.CharField(max_length=30)

 class Person(models.Model):
     group = models.ForeignKey(Group, on_delete=models.CASCADE)
     first_name = models.CharField(max_length=30)
     last_name = models.CharField(max_length=30)
 }}}

 admin.py:
 {{{#!python
 from django.contrib import admin
 from .models import *

 class PersonInline(admin.StackedInline):
     model = Person
     extra = 0

 @admin.register(Group)
 class GroupAdmin(admin.ModelAdmin):
     inlines = [PersonInline]
 }}}

 ==== Steps to reproduce

 1. Go to the Group add page (for example,
 <http://localhost:8000/admin/myapp/group/add/>). Enter a Group name, add a
 Person with first_name and last_name, and click '''Save and continue
 editing'''.
 2. Change the Group name. Add a second Person for the group, but enter a
 first_name only. A delete button ({{{X}}} icon) is available to discard
 the pending record: [[Image(https://s13.postimg.org/6wv1azzyv/image.png)]]
 3. Click '''SAVE'''. There will be a validation error, as expected,
 because last_name is not provided. However, the '''Delete''' button is
 missing: [[Image(https://s13.postimg.org/3q0hrduyf/image.png)]]
 4. '''The user is now forced to either (a) fix the validation error or (b)
 reload the page, discarding all unrelated changes on the page. It is not
 possible for the user to fix the validation error by simply
 canceling/deleting the pending new record.'''



 ----

 ==== It is actually worse than that...

 Another cause of validation errors can be uniqueness constraints. These
 errors can be difficult to fix and sometimes actually cannot be fixed. So
 it is totally possible that because of a validation error the user is
 **forced to reload the page**, there is no other choice.

 Building on the models above, here is an example of a validation error
 that can be unsalvageable for users without the `create` permission for
 groups. New `Council` model is added, a foreign key from `Person` to
 `Council` is created and also a constraint with `unique_together =
 ('council', 'group')` is set.

 [[Image(https://i.ibb.co/K2ndRGT/Screenshot-2019-08-30-at-21-08-13.png)]]

--

-- 
Ticket URL: <https://code.djangoproject.com/ticket/29087#comment:7>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/066.1f98171141cb66eeef974938ee50d018%40djangoproject.com.

Reply via email to