Opened 6 years ago
Closed 6 years ago
#29947 closed Bug (wontfix)
Inlines containing a field with default value are considered empty and not saved
Reported by: | ksl | Owned by: | nobody |
---|---|---|---|
Component: | contrib.admin | Version: | 2.1 |
Severity: | Normal | Keywords: | inline default |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Abstract
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.
Change History (6)
comment:1 by , 6 years ago
comment:2 by , 6 years ago
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?
comment:3 by , 6 years ago
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.
comment:4 by , 6 years ago
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]
?
comment:5 by , 6 years ago
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).
comment:6 by , 6 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
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.
You can bring the discussion on the developer list to attempt to achieve a different consensus if you disagree with the resolution here.
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?