Bug is located in the admin app, in the change form of a model. It
prevents adding an inline object when the inline contains only fields with
their default values.
== Steps to reproduce
* Using the tutorial's project, with the following modifications :
{{{
# models.py
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
class Choice(models.Model):
CHOICE_ANSWER = (("y", "Yes"),
("n", "No"),
("m", "Maybe"),
)
question = models.ForeignKey(Question, on_delete=models.CASCADE)
answer = models.CharField("answer", max_length=2,
choices=CHOICE_ANSWER, default="y")
# admin.py
from django.contrib import admin
from .models import Choice, Question
class ChoiceInline(admin.TabularInline):
model = Choice
extra = 0
class QuestionAdmin(admin.ModelAdmin):
inlines = [ChoiceInline]
admin.site.register(Question, QuestionAdmin)
}}}
* In the admin, create a new question object
* Add a new choice inline
* Leave choice's default value ("Yes")
* Save the question object
== Result
The question object is saved without its choice inline.
== Expected result
The choice inline of the created question object should be saved, no
matter its value (default or not).
== Versions affected
At least 2.0.2, 2.1.2 and 2.1.3.
--
Ticket URL: <https://code.djangoproject.com/ticket/29947>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
Comment (by Tim Graham):
The behavior stems from the fact that forms aren't saved unless the user
has changed them. I'm not sure how we could change behavior for this edge
case while maintaining backwards compatibility. Do you have a suggestion?
--
Ticket URL: <https://code.djangoproject.com/ticket/29947#comment:1>
Comment (by ksl):
I understand that forms undergo some processing to decide whether they
have been changed and therefore need to be saved.
The point here is that a field with its default value should be considered
a "sane" (changed, if you will) input, and not an empty input. Don't you
agree? Is that technically feasible?
--
Ticket URL: <https://code.djangoproject.com/ticket/29947#comment:2>
Comment (by Tim Graham):
Considering fields with defaults as "changed" would be backwards
incompatible. Consider a set of three initial inline forms that include a
default field. The user fills in the fields of the first form but doesn't
touch the other two. The first form is considered changed while the second
two are unchanged and ignored while saving. If defaults are treated as
changed fields, all three forms would be considered "changed" and the
user couldn't save the page without filling out all three of the forms.
--
Ticket URL: <https://code.djangoproject.com/ticket/29947#comment:3>
Comment (by ksl):
I see your point now. It then all boils down to the meaning of a field's
default.
I always thought of "default" as a way for my users to be provided with a
sensible default (hey!) value so that they are not forced to pick that
value in a select (for instance). On the other hand, what you are
describing is a "default" that almost behaves as a "blank value".
Since having `blank=False` along with a `default` value for a given field
does not lead to the desired result (ie: the field being saved with its
default value) and that changing that would be backwards-incompatible, may
I propose an additional boolean flag (`save_default`?) on `Field`, as
follows?
{{{
age = models.PositiveSmallIntegerField(_("age"), blank=False, null=False,
default=0, save_default=True)
}}}
If not doable, maybe some list borne by the `ModelAdmin`: `save_defaults =
[age]`?
--
Ticket URL: <https://code.djangoproject.com/ticket/29947#comment:4>
Comment (by Tim Graham):
I don't think the use case (a form with all of its fields having defaults)
is common enough to warrant a change in Django. Probably this problem
could be solved with a custom form (override `Form.has_changed()` to
return True, perhaps).
--
Ticket URL: <https://code.djangoproject.com/ticket/29947#comment:5>
* status: new => closed
* resolution: => wontfix
Comment:
I agree with Tim's backward compatibility concerns regarding ''has
changed'' detection based off `initial_data` .
Thank you for report but given this is an uncommon use case that can be
worked around by overriding `Form.has_changed` or ` changed_data` I'll
close this ticket as ''wontfix''.
[https://docs.djangoproject.com/en/2.1/internals/contributing/bugs-and-
features/#reporting-bugs-and-requesting-features You can bring the
discussion on the developer list] to attempt to achieve a different
consensus if you disagree with the resolution here.
--
Ticket URL: <https://code.djangoproject.com/ticket/29947#comment:6>