Django set default form values
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Default values in Django forms look simple until a form needs to behave differently for new objects, edit screens, and repeated submissions. Django gives you several places to set those values, and choosing the wrong one often leads to forms that overwrite user input or show stale data.
Choosing the Right Default Mechanism
The first distinction is between a form that is unbound and a form that already contains submitted data. Defaults are only meant to populate an unbound form. Once a request posts data, Django should render the submitted values back to the user, even if they are invalid.
For static defaults, set initial on the field itself:
This works well for values that do not depend on the request, the current user, or a database lookup. If the same defaults apply everywhere, this is the lowest-friction option.
A view can also pass an initial dictionary when it builds the form:
That approach is useful when the defaults are known in the view layer, such as query parameters, session values, or tenant-specific settings.
Dynamic Defaults in __init__
If the default depends on runtime state, set it inside the form constructor. The key rule is to avoid changing field values when the form is bound.
And in the view:
The not self.is_bound check is the important part. Without it, a failed POST can be re-rendered with your defaults instead of the actual submitted values, which is confusing and can destroy user-entered data.
ModelForm Defaults and Existing Instances
ModelForm introduces another layer. A model field can have a default, and an existing instance can already contain stored values. Those two cases are different.
If you are creating a new object, model defaults can appear once the instance exists. If you are editing an existing object, pass instance so the form reflects the saved record.
If you also pass initial, Django uses it for fields not already populated by bound data or the instance. In practice, that means instance is your source of truth for edits, and initial is better for new-form hints.
Class-based views expose the same pattern through get_initial():
That keeps the logic close to the view instead of scattering it through templates.
Rendering and Validation Behavior
A default value is only presentation data until validation runs. It does not bypass validation, and it does not mean the field is optional. If a required field has an initial value, Django still validates the submitted value normally.
It is also worth distinguishing between initial and widget attributes such as placeholder. A placeholder is just a hint in the browser. initial actually fills the control with a value that will be submitted unless the user changes it.
Common Pitfalls
A frequent mistake is setting self.fields["name"].initial unconditionally inside __init__. That overwrites bound values after a POST and makes form errors harder to correct.
Another mistake is assuming model defaults and form defaults are identical. Model defaults belong to persistence, while form defaults belong to presentation. They often overlap, but they solve different problems.
Developers also sometimes use placeholders when they really want real defaults. A placeholder is not submitted, so server-side logic should not depend on it.
Finally, edit forms often break because the view forgets to pass instance. In that case the form shows blank or fallback defaults instead of the record being edited.
Summary
- Use field-level
initialfor simple static defaults. - Pass
initialfrom the view when defaults depend on request context. - In
__init__, guard dynamic defaults withnot self.is_bound. - Use
instancefor edit forms so saved model values win. - Treat model defaults and form defaults as related but separate concerns.

