Opened 17 years ago
Closed 17 years ago
#4312 closed (wontfix)
addition of defaults argument to newforms save()
Reported by: | Owned by: | Adrian Holovaty | |
---|---|---|---|
Component: | Forms | Version: | dev |
Severity: | Keywords: | ||
Cc: | Triage Stage: | Design decision needed | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I'd like the ability to call save() on a form and insert some values for fields (e.g., non-editable or to the instance before it is saved. This way, calling save(False) to return an object which is subsequently manipulated then saved again can be avoided. I'm not sure if 'defaults' is the best name for this argument, but that's what I've implemented for now. For example:
Given these models:
from django.db import models class Foo(models.Model): name = models.CharField(maxlength=16) class Bar(models.Model): name = models.CharField(maxlength=16) foo = models.ForeignKey(Foo, editable=False)
Here is the example:
>>> from django import newforms as forms >>> from mysite.myapp.models import * >>> >>> my_foo = Foo(name='My Foo') >>> my_foo.save() >>> Form1 = forms.form_for_model(Bar) >>> form = Form1({ 'name': 'My Bar'}) >>> form.is_valid() True >>> form.save(defaults={ 'foo': my_foo }) <Bar: Bar object> >>> Form2 = forms.form_for_model(Bar, fields=('baz')) >>> form = Form2({}) >>> form.is_valid() True >>> form.save(defaults={ 'name': 'My Bar 2', 'foo': my_foo }) <Bar: Bar object> >>>
Attachments (1)
Change History (4)
by , 17 years ago
Attachment: | models.diff added |
---|
follow-up: 2 comment:1 by , 17 years ago
Triage Stage: | Unreviewed → Design decision needed |
---|
comment:2 by , 17 years ago
Replying to Simon G. <dev@simon.net.nz>:
Hmm.. what benefits does this have over using initial values?
I'm not sure that "defaults" was the right terminology for this. This was not intended to provide an initial value for the Form field or a default value for the Model attribute. Instead, this was meant as a "hook" that would allow the developer to supply values for Model attributes that are not intended to be a form field (neither hidden nor visible)--usually fields that are not "editable" or are not included in the "fields" argument to newforms.models.form_for_instance() or newforms.models.form_for_model().
A better example might be something like this:
from django.db import models from django.contrib.auth.models import User class Blog(models.Model): name = models.CharField(maxlength=16) class Entry(models.Model): blog = models.ForeignKey(Blog, editable=False) user = models.ForeignKey(User, editable=False) text = models.TextField()
When an Entry is created, the blog and user attributes are required, but they won't be part of the form--they must be supplied by some other means (e.g., the session, URL, or query string). Then they are added to the instance by passing them into the "defaults" argument of the Form's save method. This way save(False) doesn't need to be called before the attributes are set. In this case it's mostly needed when creating the instance. If there is many_to_many data, then that would also have to be handled somehow (see docs for save_instance()).
There may be other ways to do this, but I found this to be backwards compatible and relatively simple solution...
comment:3 by , 17 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
This functionality is already provided by the save(False) approach. Attaching data to the form that isn't required for form presentation isn't really a good idea, IMHO.
There is a problem with the save(False) approach when it comes to m2m data. This problem is described in ticket #4001, but that problem is solvable. The solution is to fix #4001, not to make form_for_model a behemoth. Remember, form_for_model is a helper, not the end of the story on newforms.
Hmm.. what benefits does this have over using initial values?