Fixed #7830 -- Removed all of the remaining, deprecated, non-oldforms features:
* Support for representing files as strings was removed. Use `django.core.files.base.ContentFile` instead. * Support for representing uploaded files as dictionaries was removed. Use `django.core.files.uploadedfile.SimpleUploadedFile` instead. * The `filename`, `file_name`, `file_size`, and `chuck` properties of `UploadedFile` were removed. Use the `name`, `name`, `size`, and `chunks` properties instead, respectively. * The `get_FIELD_filename`, `get_FIELD_url`, `get_FIELD_size`, and `save_FIELD_file` methods for Models with `FileField` fields were removed. Instead, use the `path`, `url`, and `size` attributes and `save` method on the field itself, respectively. * The `get_FIELD_width` and `get_FIELD_height` methods for Models with `ImageField` fields were removed. Use the `width` and `height` attributes on the field itself instead. * The dispatcher `connect`, `disconnect`, `send`, and `sendExact` functions were removed. Use the signal object's own `connect`, `disconnect`, `send`, and `send` methods instead, respectively. * The `form_for_model` and `form_for_instance` functions were removed. Use a `ModelForm` subclass instead. * Support for importing `django.newforms` was removed. Use `django.forms` instead. * Support for importing `django.utils.images` was removed. Use `django.core.files.images` instead. * Support for the `follow` argument in the `create_object` and `update_object` generic views was removed. Use the `django.forms` package and the new `form_class` argument instead. git-svn-id: http://code.djangoproject.com/svn/django/trunk@8291 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
94e8f4fb35
commit
ef48a3e69c
|
@ -36,19 +36,6 @@ class Storage(object):
|
||||||
Saves new content to the file specified by name. The content should be a
|
Saves new content to the file specified by name. The content should be a
|
||||||
proper File object, ready to be read from the beginning.
|
proper File object, ready to be read from the beginning.
|
||||||
"""
|
"""
|
||||||
# Check for old-style usage. Warn here first since there are multiple
|
|
||||||
# locations where we need to support both new and old usage.
|
|
||||||
if isinstance(content, basestring):
|
|
||||||
import warnings
|
|
||||||
warnings.warn(
|
|
||||||
message = "Representing files as strings is deprecated." \
|
|
||||||
"Use django.core.files.base.ContentFile instead.",
|
|
||||||
category = DeprecationWarning,
|
|
||||||
stacklevel = 2
|
|
||||||
)
|
|
||||||
from django.core.files.base import ContentFile
|
|
||||||
content = ContentFile(content)
|
|
||||||
|
|
||||||
# Get the proper name for the file, as it will actually be saved.
|
# Get the proper name for the file, as it will actually be saved.
|
||||||
if name is None:
|
if name is None:
|
||||||
name = content.name
|
name = content.name
|
||||||
|
|
|
@ -3,7 +3,6 @@ Classes representing uploaded files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import warnings
|
|
||||||
try:
|
try:
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -11,34 +10,10 @@ except ImportError:
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.files.base import File
|
from django.core.files.base import File
|
||||||
|
|
||||||
from django.core.files import temp as tempfile
|
from django.core.files import temp as tempfile
|
||||||
|
|
||||||
__all__ = ('UploadedFile', 'TemporaryUploadedFile', 'InMemoryUploadedFile', 'SimpleUploadedFile')
|
__all__ = ('UploadedFile', 'TemporaryUploadedFile', 'InMemoryUploadedFile',
|
||||||
|
'SimpleUploadedFile')
|
||||||
# Because we fooled around with it a bunch, UploadedFile has a bunch
|
|
||||||
# of deprecated properties. This little shortcut helps define 'em
|
|
||||||
# without too much code duplication.
|
|
||||||
def deprecated_property(old, new, readonly=False):
|
|
||||||
def issue_warning():
|
|
||||||
warnings.warn(
|
|
||||||
message = "UploadedFile.%s is deprecated; use UploadedFile.%s instead." % (old, new),
|
|
||||||
category = DeprecationWarning,
|
|
||||||
stacklevel = 3
|
|
||||||
)
|
|
||||||
|
|
||||||
def getter(self):
|
|
||||||
issue_warning()
|
|
||||||
return getattr(self, new)
|
|
||||||
|
|
||||||
def setter(self, value):
|
|
||||||
issue_warning()
|
|
||||||
setattr(self, new, value)
|
|
||||||
|
|
||||||
if readonly:
|
|
||||||
return property(getter)
|
|
||||||
else:
|
|
||||||
return property(getter, setter)
|
|
||||||
|
|
||||||
class UploadedFile(File):
|
class UploadedFile(File):
|
||||||
"""
|
"""
|
||||||
|
@ -77,21 +52,6 @@ class UploadedFile(File):
|
||||||
|
|
||||||
name = property(_get_name, _set_name)
|
name = property(_get_name, _set_name)
|
||||||
|
|
||||||
# Deprecated properties
|
|
||||||
filename = deprecated_property(old="filename", new="name")
|
|
||||||
file_name = deprecated_property(old="file_name", new="name")
|
|
||||||
file_size = deprecated_property(old="file_size", new="size")
|
|
||||||
chunk = deprecated_property(old="chunk", new="chunks", readonly=True)
|
|
||||||
|
|
||||||
def _get_data(self):
|
|
||||||
warnings.warn(
|
|
||||||
message = "UploadedFile.data is deprecated; use UploadedFile.read() instead.",
|
|
||||||
category = DeprecationWarning,
|
|
||||||
stacklevel = 2
|
|
||||||
)
|
|
||||||
return self.read()
|
|
||||||
data = property(_get_data)
|
|
||||||
|
|
||||||
# Abstract methods; subclasses *must* define read() and probably should
|
# Abstract methods; subclasses *must* define read() and probably should
|
||||||
# define open/close.
|
# define open/close.
|
||||||
def read(self, num_bytes=None):
|
def read(self, num_bytes=None):
|
||||||
|
@ -103,27 +63,6 @@ class UploadedFile(File):
|
||||||
def close(self):
|
def close(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Backwards-compatible support for uploaded-files-as-dictionaries.
|
|
||||||
def __getitem__(self, key):
|
|
||||||
warnings.warn(
|
|
||||||
message = "The dictionary access of uploaded file objects is deprecated. Use the new object interface instead.",
|
|
||||||
category = DeprecationWarning,
|
|
||||||
stacklevel = 2
|
|
||||||
)
|
|
||||||
backwards_translate = {
|
|
||||||
'filename': 'name',
|
|
||||||
'content-type': 'content_type',
|
|
||||||
}
|
|
||||||
|
|
||||||
if key == 'content':
|
|
||||||
return self.read()
|
|
||||||
elif key == 'filename':
|
|
||||||
return self.name
|
|
||||||
elif key == 'content-type':
|
|
||||||
return self.content_type
|
|
||||||
else:
|
|
||||||
return getattr(self, key)
|
|
||||||
|
|
||||||
class TemporaryUploadedFile(UploadedFile):
|
class TemporaryUploadedFile(UploadedFile):
|
||||||
"""
|
"""
|
||||||
A file uploaded to a temporary location (i.e. stream-to-disk).
|
A file uploaded to a temporary location (i.e. stream-to-disk).
|
||||||
|
|
|
@ -3,7 +3,6 @@ import types
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
from itertools import izip
|
from itertools import izip
|
||||||
from warnings import warn
|
|
||||||
try:
|
try:
|
||||||
set
|
set
|
||||||
except NameError:
|
except NameError:
|
||||||
|
@ -477,43 +476,6 @@ class Model(object):
|
||||||
setattr(self, cachename, obj)
|
setattr(self, cachename, obj)
|
||||||
return getattr(self, cachename)
|
return getattr(self, cachename)
|
||||||
|
|
||||||
def _get_FIELD_filename(self, field):
|
|
||||||
warn("instance.get_%s_filename() is deprecated. Use instance.%s.path instead." % \
|
|
||||||
(field.attname, field.attname), DeprecationWarning, stacklevel=3)
|
|
||||||
try:
|
|
||||||
return getattr(self, field.attname).path
|
|
||||||
except ValueError:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def _get_FIELD_url(self, field):
|
|
||||||
warn("instance.get_%s_url() is deprecated. Use instance.%s.url instead." % \
|
|
||||||
(field.attname, field.attname), DeprecationWarning, stacklevel=3)
|
|
||||||
try:
|
|
||||||
return getattr(self, field.attname).url
|
|
||||||
except ValueError:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def _get_FIELD_size(self, field):
|
|
||||||
warn("instance.get_%s_size() is deprecated. Use instance.%s.size instead." % \
|
|
||||||
(field.attname, field.attname), DeprecationWarning, stacklevel=3)
|
|
||||||
return getattr(self, field.attname).size
|
|
||||||
|
|
||||||
def _save_FIELD_file(self, field, filename, content, save=True):
|
|
||||||
warn("instance.save_%s_file() is deprecated. Use instance.%s.save() instead." % \
|
|
||||||
(field.attname, field.attname), DeprecationWarning, stacklevel=3)
|
|
||||||
return getattr(self, field.attname).save(filename, content, save)
|
|
||||||
|
|
||||||
_save_FIELD_file.alters_data = True
|
|
||||||
|
|
||||||
def _get_FIELD_width(self, field):
|
|
||||||
warn("instance.get_%s_width() is deprecated. Use instance.%s.width instead." % \
|
|
||||||
(field.attname, field.attname), DeprecationWarning, stacklevel=3)
|
|
||||||
return getattr(self, field.attname).width()
|
|
||||||
|
|
||||||
def _get_FIELD_height(self, field):
|
|
||||||
warn("instance.get_%s_height() is deprecated. Use instance.%s.height instead." % \
|
|
||||||
(field.attname, field.attname), DeprecationWarning, stacklevel=3)
|
|
||||||
return getattr(self, field.attname).height()
|
|
||||||
|
|
||||||
|
|
||||||
############################################
|
############################################
|
||||||
|
|
|
@ -192,10 +192,6 @@ class FileField(Field):
|
||||||
def contribute_to_class(self, cls, name):
|
def contribute_to_class(self, cls, name):
|
||||||
super(FileField, self).contribute_to_class(cls, name)
|
super(FileField, self).contribute_to_class(cls, name)
|
||||||
setattr(cls, self.name, FileDescriptor(self))
|
setattr(cls, self.name, FileDescriptor(self))
|
||||||
setattr(cls, 'get_%s_filename' % self.name, curry(cls._get_FIELD_filename, field=self))
|
|
||||||
setattr(cls, 'get_%s_url' % self.name, curry(cls._get_FIELD_url, field=self))
|
|
||||||
setattr(cls, 'get_%s_size' % self.name, curry(cls._get_FIELD_size, field=self))
|
|
||||||
setattr(cls, 'save_%s_file' % self.name, lambda instance, name, content, save=True: instance._save_FIELD_file(self, name, content, save))
|
|
||||||
signals.post_delete.connect(self.delete_file, sender=cls)
|
signals.post_delete.connect(self.delete_file, sender=cls)
|
||||||
|
|
||||||
def delete_file(self, instance, sender, **kwargs):
|
def delete_file(self, instance, sender, **kwargs):
|
||||||
|
@ -262,17 +258,6 @@ class FileField(Field):
|
||||||
|
|
||||||
class ImageFieldFile(ImageFile, FieldFile):
|
class ImageFieldFile(ImageFile, FieldFile):
|
||||||
def save(self, name, content, save=True):
|
def save(self, name, content, save=True):
|
||||||
|
|
||||||
if not hasattr(content, 'read'):
|
|
||||||
import warnings
|
|
||||||
warnings.warn(
|
|
||||||
message = "Representing files as strings is deprecated." \
|
|
||||||
"Use django.core.files.base.ContentFile instead.",
|
|
||||||
category = DeprecationWarning,
|
|
||||||
stacklevel = 2
|
|
||||||
)
|
|
||||||
content = ContentFile(content)
|
|
||||||
|
|
||||||
# Repopulate the image dimension cache.
|
# Repopulate the image dimension cache.
|
||||||
self._dimensions_cache = get_image_dimensions(content)
|
self._dimensions_cache = get_image_dimensions(content)
|
||||||
|
|
||||||
|
@ -300,15 +285,6 @@ class ImageField(FileField):
|
||||||
def get_manipulator_field_objs(self):
|
def get_manipulator_field_objs(self):
|
||||||
return [oldforms.ImageUploadField, oldforms.HiddenField]
|
return [oldforms.ImageUploadField, oldforms.HiddenField]
|
||||||
|
|
||||||
def contribute_to_class(self, cls, name):
|
|
||||||
super(ImageField, self).contribute_to_class(cls, name)
|
|
||||||
# Add get_BLAH_width and get_BLAH_height methods, but only if the
|
|
||||||
# image field doesn't have width and height cache fields.
|
|
||||||
if not self.width_field:
|
|
||||||
setattr(cls, 'get_%s_width' % self.name, curry(cls._get_FIELD_width, field=self))
|
|
||||||
if not self.height_field:
|
|
||||||
setattr(cls, 'get_%s_height' % self.name, curry(cls._get_FIELD_height, field=self))
|
|
||||||
|
|
||||||
def formfield(self, **kwargs):
|
def formfield(self, **kwargs):
|
||||||
defaults = {'form_class': forms.ImageField}
|
defaults = {'form_class': forms.ImageField}
|
||||||
defaults.update(kwargs)
|
defaults.update(kwargs)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import weakref
|
import weakref
|
||||||
import warnings
|
|
||||||
try:
|
try:
|
||||||
set
|
set
|
||||||
except NameError:
|
except NameError:
|
||||||
|
@ -197,47 +196,3 @@ class Signal(object):
|
||||||
for idx, (r_key, _) in enumerate(self.receivers):
|
for idx, (r_key, _) in enumerate(self.receivers):
|
||||||
if r_key == key:
|
if r_key == key:
|
||||||
del self.receivers[idx]
|
del self.receivers[idx]
|
||||||
|
|
||||||
def connect(receiver, signal, sender=None, weak=True):
|
|
||||||
"""
|
|
||||||
For backward compatibility only. See Signal.connect()
|
|
||||||
"""
|
|
||||||
warnings.warn(
|
|
||||||
category = DeprecationWarning,
|
|
||||||
message = "dispatcher.connect() is deprecated; use Signal.connect() instead.",
|
|
||||||
stacklevel = 2
|
|
||||||
)
|
|
||||||
return signal.connect(receiver, sender, weak)
|
|
||||||
|
|
||||||
def disconnect(receiver, signal, sender=None, weak=True):
|
|
||||||
"""
|
|
||||||
For backward compatibility only. See Signal.disconnect()
|
|
||||||
"""
|
|
||||||
warnings.warn(
|
|
||||||
category = DeprecationWarning,
|
|
||||||
message = "dispatcher.disconnect() is deprecated; use Signal.disconnect() instead.",
|
|
||||||
stacklevel = 2
|
|
||||||
)
|
|
||||||
signal.disconnect(receiver, sender, weak)
|
|
||||||
|
|
||||||
def send(signal, sender=None, **named):
|
|
||||||
"""
|
|
||||||
For backward compatibility only. See Signal.send()
|
|
||||||
"""
|
|
||||||
warnings.warn(
|
|
||||||
category = DeprecationWarning,
|
|
||||||
message = "dispatcher.send() is deprecated; use Signal.send() instead.",
|
|
||||||
stacklevel = 2
|
|
||||||
)
|
|
||||||
return signal.send(sender=sender, **named)
|
|
||||||
|
|
||||||
def sendExact(signal, sender, **named ):
|
|
||||||
"""
|
|
||||||
This function is deprecated, as it now has the same meaning as send.
|
|
||||||
"""
|
|
||||||
warnings.warn(
|
|
||||||
category = DeprecationWarning,
|
|
||||||
message = "dispatcher.sendExact() is deprecated; use Signal.send() instead.",
|
|
||||||
stacklevel = 2
|
|
||||||
)
|
|
||||||
return signal.send(sender=sender, **named)
|
|
||||||
|
|
|
@ -442,16 +442,7 @@ class FileField(Field):
|
||||||
elif not data and initial:
|
elif not data and initial:
|
||||||
return initial
|
return initial
|
||||||
|
|
||||||
if isinstance(data, dict):
|
# UploadedFile objects should have name and size attributes.
|
||||||
# We warn once, then support both ways below.
|
|
||||||
import warnings
|
|
||||||
warnings.warn(
|
|
||||||
message = "Representing uploaded files as dictionaries is deprecated. Use django.core.files.uploadedfile.SimpleUploadedFile instead.",
|
|
||||||
category = DeprecationWarning,
|
|
||||||
stacklevel = 2
|
|
||||||
)
|
|
||||||
data = UploadedFile(data['filename'], data['content'])
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
file_name = data.name
|
file_name = data.name
|
||||||
file_size = data.size
|
file_size = data.size
|
||||||
|
|
|
@ -3,8 +3,6 @@ Helper functions for creating Form classes from Django models
|
||||||
and database field objects.
|
and database field objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from warnings import warn
|
|
||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.utils.encoding import smart_unicode
|
from django.utils.encoding import smart_unicode
|
||||||
from django.utils.datastructures import SortedDict
|
from django.utils.datastructures import SortedDict
|
||||||
|
@ -18,8 +16,8 @@ from formsets import BaseFormSet, formset_factory, DELETION_FIELD_NAME
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'ModelForm', 'BaseModelForm', 'model_to_dict', 'fields_for_model',
|
'ModelForm', 'BaseModelForm', 'model_to_dict', 'fields_for_model',
|
||||||
'save_instance', 'form_for_model', 'form_for_instance', 'form_for_fields',
|
'save_instance', 'form_for_fields', 'ModelChoiceField',
|
||||||
'ModelChoiceField', 'ModelMultipleChoiceField',
|
'ModelMultipleChoiceField',
|
||||||
)
|
)
|
||||||
|
|
||||||
def save_instance(form, instance, fields=None, fail_message='saved',
|
def save_instance(form, instance, fields=None, fail_message='saved',
|
||||||
|
@ -74,65 +72,6 @@ def make_instance_save(instance, fields, fail_message):
|
||||||
return save_instance(self, instance, fields, fail_message, commit)
|
return save_instance(self, instance, fields, fail_message, commit)
|
||||||
return save
|
return save
|
||||||
|
|
||||||
def form_for_model(model, form=BaseForm, fields=None,
|
|
||||||
formfield_callback=lambda f: f.formfield()):
|
|
||||||
"""
|
|
||||||
Returns a Form class for the given Django model class.
|
|
||||||
|
|
||||||
Provide ``form`` if you want to use a custom BaseForm subclass.
|
|
||||||
|
|
||||||
Provide ``formfield_callback`` if you want to define different logic for
|
|
||||||
determining the formfield for a given database field. It's a callable that
|
|
||||||
takes a database Field instance and returns a form Field instance.
|
|
||||||
"""
|
|
||||||
warn("form_for_model is deprecated. Use ModelForm instead.",
|
|
||||||
PendingDeprecationWarning, stacklevel=3)
|
|
||||||
opts = model._meta
|
|
||||||
field_list = []
|
|
||||||
for f in opts.fields + opts.many_to_many:
|
|
||||||
if not f.editable:
|
|
||||||
continue
|
|
||||||
if fields and not f.name in fields:
|
|
||||||
continue
|
|
||||||
formfield = formfield_callback(f)
|
|
||||||
if formfield:
|
|
||||||
field_list.append((f.name, formfield))
|
|
||||||
base_fields = SortedDict(field_list)
|
|
||||||
return type(opts.object_name + 'Form', (form,),
|
|
||||||
{'base_fields': base_fields, '_model': model,
|
|
||||||
'save': make_model_save(model, fields, 'created')})
|
|
||||||
|
|
||||||
def form_for_instance(instance, form=BaseForm, fields=None,
|
|
||||||
formfield_callback=lambda f, **kwargs: f.formfield(**kwargs)):
|
|
||||||
"""
|
|
||||||
Returns a Form class for the given Django model instance.
|
|
||||||
|
|
||||||
Provide ``form`` if you want to use a custom BaseForm subclass.
|
|
||||||
|
|
||||||
Provide ``formfield_callback`` if you want to define different logic for
|
|
||||||
determining the formfield for a given database field. It's a callable that
|
|
||||||
takes a database Field instance, plus **kwargs, and returns a form Field
|
|
||||||
instance with the given kwargs (i.e. 'initial').
|
|
||||||
"""
|
|
||||||
warn("form_for_instance is deprecated. Use ModelForm instead.",
|
|
||||||
PendingDeprecationWarning, stacklevel=3)
|
|
||||||
model = instance.__class__
|
|
||||||
opts = model._meta
|
|
||||||
field_list = []
|
|
||||||
for f in opts.fields + opts.many_to_many:
|
|
||||||
if not f.editable:
|
|
||||||
continue
|
|
||||||
if fields and not f.name in fields:
|
|
||||||
continue
|
|
||||||
current_value = f.value_from_object(instance)
|
|
||||||
formfield = formfield_callback(f, initial=current_value)
|
|
||||||
if formfield:
|
|
||||||
field_list.append((f.name, formfield))
|
|
||||||
base_fields = SortedDict(field_list)
|
|
||||||
return type(opts.object_name + 'InstanceForm', (form,),
|
|
||||||
{'base_fields': base_fields, '_model': model,
|
|
||||||
'save': make_instance_save(instance, fields, 'changed')})
|
|
||||||
|
|
||||||
def form_for_fields(field_list):
|
def form_for_fields(field_list):
|
||||||
"""
|
"""
|
||||||
Returns a Form class for the given list of Django database field instances.
|
Returns a Form class for the given list of Django database field instances.
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
import warnings
|
|
||||||
warnings.warn(
|
|
||||||
category = DeprecationWarning,
|
|
||||||
message = "django.newforms is no longer new. Import django.forms instead.",
|
|
||||||
stacklevel = 2
|
|
||||||
)
|
|
||||||
from django.forms import *
|
|
|
@ -1,5 +0,0 @@
|
||||||
import warnings
|
|
||||||
|
|
||||||
from django.core.files.images import get_image_dimensions
|
|
||||||
|
|
||||||
warnings.warn("django.utils.images has been moved to django.core.files.images.", DeprecationWarning)
|
|
|
@ -7,19 +7,6 @@ from django.utils.translation import ugettext
|
||||||
from django.contrib.auth.views import redirect_to_login
|
from django.contrib.auth.views import redirect_to_login
|
||||||
from django.views.generic import GenericViewError
|
from django.views.generic import GenericViewError
|
||||||
|
|
||||||
def deprecate_follow(follow):
|
|
||||||
"""
|
|
||||||
Issues a DeprecationWarning if follow is anything but None.
|
|
||||||
|
|
||||||
The old Manipulator-based forms used a follow argument that is no longer
|
|
||||||
needed for newforms-based forms.
|
|
||||||
"""
|
|
||||||
if follow is not None:
|
|
||||||
import warnings
|
|
||||||
msg = ("Generic views have been changed to use newforms, and the"
|
|
||||||
" 'follow' argument is no longer used. Please update your code"
|
|
||||||
" to not use the 'follow' argument.")
|
|
||||||
warnings.warn(msg, DeprecationWarning, stacklevel=3)
|
|
||||||
|
|
||||||
def apply_extra_context(extra_context, context):
|
def apply_extra_context(extra_context, context):
|
||||||
"""
|
"""
|
||||||
|
@ -105,8 +92,7 @@ def lookup_object(model, object_id, slug, slug_field):
|
||||||
|
|
||||||
def create_object(request, model=None, template_name=None,
|
def create_object(request, model=None, template_name=None,
|
||||||
template_loader=loader, extra_context=None, post_save_redirect=None,
|
template_loader=loader, extra_context=None, post_save_redirect=None,
|
||||||
login_required=False, follow=None, context_processors=None,
|
login_required=False, context_processors=None, form_class=None):
|
||||||
form_class=None):
|
|
||||||
"""
|
"""
|
||||||
Generic object-creation function.
|
Generic object-creation function.
|
||||||
|
|
||||||
|
@ -115,7 +101,6 @@ def create_object(request, model=None, template_name=None,
|
||||||
form
|
form
|
||||||
the form for the object
|
the form for the object
|
||||||
"""
|
"""
|
||||||
deprecate_follow(follow)
|
|
||||||
if extra_context is None: extra_context = {}
|
if extra_context is None: extra_context = {}
|
||||||
if login_required and not request.user.is_authenticated():
|
if login_required and not request.user.is_authenticated():
|
||||||
return redirect_to_login(request.path)
|
return redirect_to_login(request.path)
|
||||||
|
@ -143,9 +128,9 @@ def create_object(request, model=None, template_name=None,
|
||||||
|
|
||||||
def update_object(request, model=None, object_id=None, slug=None,
|
def update_object(request, model=None, object_id=None, slug=None,
|
||||||
slug_field='slug', template_name=None, template_loader=loader,
|
slug_field='slug', template_name=None, template_loader=loader,
|
||||||
extra_context=None, post_save_redirect=None,
|
extra_context=None, post_save_redirect=None, login_required=False,
|
||||||
login_required=False, follow=None, context_processors=None,
|
context_processors=None, template_object_name='object',
|
||||||
template_object_name='object', form_class=None):
|
form_class=None):
|
||||||
"""
|
"""
|
||||||
Generic object-update function.
|
Generic object-update function.
|
||||||
|
|
||||||
|
@ -156,7 +141,6 @@ def update_object(request, model=None, object_id=None, slug=None,
|
||||||
object
|
object
|
||||||
the original object being edited
|
the original object being edited
|
||||||
"""
|
"""
|
||||||
deprecate_follow(follow)
|
|
||||||
if extra_context is None: extra_context = {}
|
if extra_context is None: extra_context = {}
|
||||||
if login_required and not request.user.is_authenticated():
|
if login_required and not request.user.is_authenticated():
|
||||||
return redirect_to_login(request.path)
|
return redirect_to_login(request.path)
|
||||||
|
|
|
@ -483,8 +483,7 @@ accepted lookup types to ``exact`` and ``in``::
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Returns the default form field to use when this field is displayed
|
Returns the default form field to use when this field is displayed
|
||||||
in a model. This method is called by the `helper functions`_
|
in a model.
|
||||||
``form_for_model()`` and ``form_for_instance()``.
|
|
||||||
|
|
||||||
All of the ``kwargs`` dictionary is passed directly to the form field's
|
All of the ``kwargs`` dictionary is passed directly to the form field's
|
||||||
``__init__()`` method. Normally, all you need to do is set up a good default
|
``__init__()`` method. Normally, all you need to do is set up a good default
|
||||||
|
|
|
@ -2313,37 +2313,6 @@ For a full example, see the `lookup API sample model`_.
|
||||||
|
|
||||||
.. _lookup API sample model: ../models/lookup/
|
.. _lookup API sample model: ../models/lookup/
|
||||||
|
|
||||||
get_FOO_filename()
|
|
||||||
------------------
|
|
||||||
|
|
||||||
**Deprecated in Django development version**; use ``object.FOO.name`` instead.
|
|
||||||
See `managing files`_ for details.
|
|
||||||
|
|
||||||
get_FOO_url()
|
|
||||||
-------------
|
|
||||||
|
|
||||||
**Deprecated in Django development version**; use ``object.FOO.url`` instead.
|
|
||||||
See `managing files`_ for details.
|
|
||||||
|
|
||||||
get_FOO_size()
|
|
||||||
--------------
|
|
||||||
|
|
||||||
**Deprecated in Django development version**; use ``object.FOO.size`` instead.
|
|
||||||
See `managing files`_ for details.
|
|
||||||
|
|
||||||
save_FOO_file(filename, raw_contents)
|
|
||||||
-------------------------------------
|
|
||||||
|
|
||||||
**Deprecated in Django development version**; use ``object.FOO.save()`` instead.
|
|
||||||
See `managing files`_ for details.
|
|
||||||
|
|
||||||
get_FOO_height() and get_FOO_width()
|
|
||||||
------------------------------------
|
|
||||||
|
|
||||||
**Deprecated in Django development version**; use ``object.FOO.width`` and
|
|
||||||
``object.FOO.height`` instead. See `managing files`_ for details.
|
|
||||||
|
|
||||||
.. _`managing files`: ../files/
|
|
||||||
|
|
||||||
Shortcuts
|
Shortcuts
|
||||||
=========
|
=========
|
||||||
|
|
|
@ -1,425 +0,0 @@
|
||||||
Generating forms for models
|
|
||||||
===========================
|
|
||||||
|
|
||||||
.. admonition:: Note
|
|
||||||
|
|
||||||
The APIs described in this document have been deprecated. If you're
|
|
||||||
developing new code, use `ModelForms`_ instead.
|
|
||||||
|
|
||||||
.. _ModelForms: ../modelforms/
|
|
||||||
|
|
||||||
If you're building a database-driven app, chances are you'll have forms that
|
|
||||||
map closely to Django models. For instance, you might have a ``BlogComment``
|
|
||||||
model, and you want to create a form that lets people submit comments. In this
|
|
||||||
case, it would be redundant to define the field types in your form, because
|
|
||||||
you've already defined the fields in your model.
|
|
||||||
|
|
||||||
For this reason, Django provides a few helper functions that let you create a
|
|
||||||
``Form`` class from a Django model.
|
|
||||||
|
|
||||||
``form_for_model()``
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
The method ``django.forms.form_for_model()`` creates a form based on the
|
|
||||||
definition of a specific model. Pass it the model class, and it will return a
|
|
||||||
``Form`` class that contains a form field for each model field.
|
|
||||||
|
|
||||||
For example::
|
|
||||||
|
|
||||||
>>> from django.forms import form_for_model
|
|
||||||
|
|
||||||
# Create the form class.
|
|
||||||
>>> ArticleForm = form_for_model(Article)
|
|
||||||
|
|
||||||
# Create an empty form instance.
|
|
||||||
>>> f = ArticleForm()
|
|
||||||
|
|
||||||
It bears repeating that ``form_for_model()`` takes the model *class*, not a
|
|
||||||
model instance, and it returns a ``Form`` *class*, not a ``Form`` instance.
|
|
||||||
|
|
||||||
Field types
|
|
||||||
~~~~~~~~~~~
|
|
||||||
|
|
||||||
The generated ``Form`` class will have a form field for every model field. Each
|
|
||||||
model field has a corresponding default form field. For example, a
|
|
||||||
``CharField`` on a model is represented as a ``CharField`` on a form. A
|
|
||||||
model ``ManyToManyField`` is represented as a ``MultipleChoiceField``. Here is
|
|
||||||
the full list of conversions:
|
|
||||||
|
|
||||||
=============================== ========================================
|
|
||||||
Model field Form field
|
|
||||||
=============================== ========================================
|
|
||||||
``AutoField`` Not represented in the form
|
|
||||||
``BooleanField`` ``BooleanField``
|
|
||||||
``CharField`` ``CharField`` with ``max_length`` set to
|
|
||||||
the model field's ``max_length``
|
|
||||||
``CommaSeparatedIntegerField`` ``CharField``
|
|
||||||
``DateField`` ``DateField``
|
|
||||||
``DateTimeField`` ``DateTimeField``
|
|
||||||
``DecimalField`` ``DecimalField``
|
|
||||||
``EmailField`` ``EmailField``
|
|
||||||
``FileField`` ``FileField``
|
|
||||||
``FilePathField`` ``CharField``
|
|
||||||
``FloatField`` ``FloatField``
|
|
||||||
``ForeignKey`` ``ModelChoiceField`` (see below)
|
|
||||||
``ImageField`` ``ImageField``
|
|
||||||
``IntegerField`` ``IntegerField``
|
|
||||||
``IPAddressField`` ``IPAddressField``
|
|
||||||
``ManyToManyField`` ``ModelMultipleChoiceField`` (see
|
|
||||||
below)
|
|
||||||
``NullBooleanField`` ``CharField``
|
|
||||||
``PhoneNumberField`` ``USPhoneNumberField``
|
|
||||||
(from ``django.contrib.localflavor.us``)
|
|
||||||
``PositiveIntegerField`` ``IntegerField``
|
|
||||||
``PositiveSmallIntegerField`` ``IntegerField``
|
|
||||||
``SlugField`` ``CharField``
|
|
||||||
``SmallIntegerField`` ``IntegerField``
|
|
||||||
``TextField`` ``CharField`` with ``widget=Textarea``
|
|
||||||
``TimeField`` ``TimeField``
|
|
||||||
``URLField`` ``URLField`` with ``verify_exists`` set
|
|
||||||
to the model field's ``verify_exists``
|
|
||||||
``USStateField`` ``CharField`` with
|
|
||||||
``widget=USStateSelect``
|
|
||||||
(``USStateSelect`` is from
|
|
||||||
``django.contrib.localflavor.us``)
|
|
||||||
``XMLField`` ``CharField`` with ``widget=Textarea``
|
|
||||||
=============================== ========================================
|
|
||||||
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
The ``FloatField`` form field and ``DecimalField`` model and form fields
|
|
||||||
are new in the development version.
|
|
||||||
|
|
||||||
As you might expect, the ``ForeignKey`` and ``ManyToManyField`` model field
|
|
||||||
types are special cases:
|
|
||||||
|
|
||||||
* ``ForeignKey`` is represented by ``django.forms.ModelChoiceField``,
|
|
||||||
which is a ``ChoiceField`` whose choices are a model ``QuerySet``.
|
|
||||||
|
|
||||||
* ``ManyToManyField`` is represented by
|
|
||||||
``django.forms.ModelMultipleChoiceField``, which is a
|
|
||||||
``MultipleChoiceField`` whose choices are a model ``QuerySet``.
|
|
||||||
|
|
||||||
In addition, each generated form field has attributes set as follows:
|
|
||||||
|
|
||||||
* If the model field has ``blank=True``, then ``required`` is set to
|
|
||||||
``False`` on the form field. Otherwise, ``required=True``.
|
|
||||||
|
|
||||||
* The form field's ``label`` is set to the ``verbose_name`` of the model
|
|
||||||
field, with the first character capitalized.
|
|
||||||
|
|
||||||
* The form field's ``help_text`` is set to the ``help_text`` of the model
|
|
||||||
field.
|
|
||||||
|
|
||||||
* If the model field has ``choices`` set, then the form field's ``widget``
|
|
||||||
will be set to ``Select``, with choices coming from the model field's
|
|
||||||
``choices``. The choices will normally include the blank choice which is
|
|
||||||
selected by default. If the field is required, this forces the user to
|
|
||||||
make a selection. The blank choice will not be included if the model
|
|
||||||
field has ``blank=False`` and an explicit ``default`` value (the
|
|
||||||
``default`` value will be initially selected instead).
|
|
||||||
|
|
||||||
Finally, note that you can override the form field used for a given model
|
|
||||||
field. See "Overriding the default field types" below.
|
|
||||||
|
|
||||||
A full example
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Consider this set of models::
|
|
||||||
|
|
||||||
from django.db import models
|
|
||||||
|
|
||||||
TITLE_CHOICES = (
|
|
||||||
('MR', 'Mr.'),
|
|
||||||
('MRS', 'Mrs.'),
|
|
||||||
('MS', 'Ms.'),
|
|
||||||
)
|
|
||||||
|
|
||||||
class Author(models.Model):
|
|
||||||
name = models.CharField(max_length=100)
|
|
||||||
title = models.CharField(max_length=3, choices=TITLE_CHOICES)
|
|
||||||
birth_date = models.DateField(blank=True, null=True)
|
|
||||||
|
|
||||||
def __unicode__(self):
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
class Book(models.Model):
|
|
||||||
name = models.CharField(max_length=100)
|
|
||||||
authors = models.ManyToManyField(Author)
|
|
||||||
|
|
||||||
With these models, a call to ``form_for_model(Author)`` would return a ``Form``
|
|
||||||
class equivalent to this::
|
|
||||||
|
|
||||||
class AuthorForm(forms.Form):
|
|
||||||
name = forms.CharField(max_length=100)
|
|
||||||
title = forms.CharField(max_length=3,
|
|
||||||
widget=forms.Select(choices=TITLE_CHOICES))
|
|
||||||
birth_date = forms.DateField(required=False)
|
|
||||||
|
|
||||||
A call to ``form_for_model(Book)`` would return a ``Form`` class equivalent to
|
|
||||||
this::
|
|
||||||
|
|
||||||
class BookForm(forms.Form):
|
|
||||||
name = forms.CharField(max_length=100)
|
|
||||||
authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all())
|
|
||||||
|
|
||||||
The ``save()`` method
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Every form produced by ``form_for_model()`` also has a ``save()`` method. This
|
|
||||||
method creates and saves a database object from the data bound to the form. For
|
|
||||||
example::
|
|
||||||
|
|
||||||
# Create a form instance from POST data.
|
|
||||||
>>> f = ArticleForm(request.POST)
|
|
||||||
|
|
||||||
# Save a new Article object from the form's data.
|
|
||||||
>>> new_article = f.save()
|
|
||||||
|
|
||||||
Note that ``save()`` will raise a ``ValueError`` if the data in the form
|
|
||||||
doesn't validate -- i.e., ``if form.errors``.
|
|
||||||
|
|
||||||
This ``save()`` method accepts an optional ``commit`` keyword argument, which
|
|
||||||
accepts either ``True`` or ``False``. If you call ``save()`` with
|
|
||||||
``commit=False``, then it will return an object that hasn't yet been saved to
|
|
||||||
the database. In this case, it's up to you to call ``save()`` on the resulting
|
|
||||||
model instance. This is useful if you want to do custom processing on the
|
|
||||||
object before saving it. ``commit`` is ``True`` by default.
|
|
||||||
|
|
||||||
Another side effect of using ``commit=False`` is seen when your model has
|
|
||||||
a many-to-many relation with another model. If your model has a many-to-many
|
|
||||||
relation and you specify ``commit=False`` when you save a form, Django cannot
|
|
||||||
immediately save the form data for the many-to-many relation. This is because
|
|
||||||
it isn't possible to save many-to-many data for an instance until the instance
|
|
||||||
exists in the database.
|
|
||||||
|
|
||||||
To work around this problem, every time you save a form using ``commit=False``,
|
|
||||||
Django adds a ``save_m2m()`` method to the form created by ``form_for_model``.
|
|
||||||
After you've manually saved the instance produced by the form, you can invoke
|
|
||||||
``save_m2m()`` to save the many-to-many form data. For example::
|
|
||||||
|
|
||||||
# Create a form instance with POST data.
|
|
||||||
>>> f = AuthorForm(request.POST)
|
|
||||||
|
|
||||||
# Create, but don't save the new author instance.
|
|
||||||
>>> new_author = f.save(commit=False)
|
|
||||||
|
|
||||||
# Modify the author in some way.
|
|
||||||
>>> new_author.some_field = 'some_value'
|
|
||||||
|
|
||||||
# Save the new instance.
|
|
||||||
>>> new_author.save()
|
|
||||||
|
|
||||||
# Now, save the many-to-many data for the form.
|
|
||||||
>>> f.save_m2m()
|
|
||||||
|
|
||||||
Calling ``save_m2m()`` is only required if you use ``save(commit=False)``.
|
|
||||||
When you use a simple ``save()`` on a form, all data -- including
|
|
||||||
many-to-many data -- is saved without the need for any additional method calls.
|
|
||||||
For example::
|
|
||||||
|
|
||||||
# Create a form instance with POST data.
|
|
||||||
>>> f = AuthorForm(request.POST)
|
|
||||||
|
|
||||||
# Create and save the new author instance. There's no need to do anything else.
|
|
||||||
>>> new_author = f.save()
|
|
||||||
|
|
||||||
Using an alternate base class
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
If you want to add custom methods to the form generated by
|
|
||||||
``form_for_model()``, write a class that extends ``django.forms.BaseForm``
|
|
||||||
and contains your custom methods. Then, use the ``form`` argument to
|
|
||||||
``form_for_model()`` to tell it to use your custom form as its base class.
|
|
||||||
For example::
|
|
||||||
|
|
||||||
# Create the new base class.
|
|
||||||
>>> class MyBase(BaseForm):
|
|
||||||
... def my_method(self):
|
|
||||||
... # Do whatever the method does
|
|
||||||
|
|
||||||
# Create the form class with a different base class.
|
|
||||||
>>> ArticleForm = form_for_model(Article, form=MyBase)
|
|
||||||
|
|
||||||
# Instantiate the form.
|
|
||||||
>>> f = ArticleForm()
|
|
||||||
|
|
||||||
# Use the base class method.
|
|
||||||
>>> f.my_method()
|
|
||||||
|
|
||||||
Using a subset of fields on the form
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
In some cases, you may not want all the model fields to appear on the generated
|
|
||||||
form. There are two ways of telling ``form_for_model()`` to use only a subset
|
|
||||||
of the model fields:
|
|
||||||
|
|
||||||
1. Set ``editable=False`` on the model field. As a result, *any* form
|
|
||||||
created from the model via ``form_for_model()`` will not include that
|
|
||||||
field.
|
|
||||||
|
|
||||||
2. Use the ``fields`` argument to ``form_for_model()``. This argument, if
|
|
||||||
given, should be a list of field names to include in the form.
|
|
||||||
|
|
||||||
For example, if you want a form for the ``Author`` model (defined above)
|
|
||||||
that includes only the ``name`` and ``title`` fields, you would specify
|
|
||||||
``fields`` like this::
|
|
||||||
|
|
||||||
PartialArticleForm = form_for_model(Author, fields=('name', 'title'))
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
If you specify ``fields`` when creating a form with ``form_for_model()``,
|
|
||||||
then the fields that are *not* specified will not be set by the form's
|
|
||||||
``save()`` method. Django will prevent any attempt to save an incomplete
|
|
||||||
model, so if the model does not allow the missing fields to be empty, and
|
|
||||||
does not provide a default value for the missing fields, any attempt to
|
|
||||||
``save()`` a ``form_for_model`` with missing fields will fail. To avoid
|
|
||||||
this failure, you must use ``save(commit=False)`` and manually set any
|
|
||||||
extra required fields::
|
|
||||||
|
|
||||||
instance = form.save(commit=False)
|
|
||||||
instance.required_field = 'new value'
|
|
||||||
instance.save()
|
|
||||||
|
|
||||||
See the `section on saving forms`_ for more details on using
|
|
||||||
``save(commit=False)``.
|
|
||||||
|
|
||||||
.. _section on saving forms: `The save() method`_
|
|
||||||
|
|
||||||
Overriding the default field types
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The default field types, as described in the "Field types" table above, are
|
|
||||||
sensible defaults; if you have a ``DateField`` in your model, chances are you'd
|
|
||||||
want that to be represented as a ``DateField`` in your form. But
|
|
||||||
``form_for_model()`` gives you the flexibility of changing the form field type
|
|
||||||
for a given model field. You do this by specifying a **formfield callback**.
|
|
||||||
|
|
||||||
A formfield callback is a function that, when provided with a model field,
|
|
||||||
returns a form field instance. When constructing a form, ``form_for_model()``
|
|
||||||
asks the formfield callback to provide form field types.
|
|
||||||
|
|
||||||
By default, ``form_for_model()`` calls the ``formfield()`` method on the model
|
|
||||||
field::
|
|
||||||
|
|
||||||
def default_callback(field, **kwargs):
|
|
||||||
return field.formfield(**kwargs)
|
|
||||||
|
|
||||||
The ``kwargs`` are any keyword arguments that might be passed to the form
|
|
||||||
field, such as ``required=True`` or ``label='Foo'``.
|
|
||||||
|
|
||||||
For example, if you wanted to use ``MyDateFormField`` for any ``DateField``
|
|
||||||
field on the model, you could define the callback::
|
|
||||||
|
|
||||||
>>> def my_callback(field, **kwargs):
|
|
||||||
... if isinstance(field, models.DateField):
|
|
||||||
... return MyDateFormField(**kwargs)
|
|
||||||
... else:
|
|
||||||
... return field.formfield(**kwargs)
|
|
||||||
|
|
||||||
>>> ArticleForm = form_for_model(Article, formfield_callback=my_callback)
|
|
||||||
|
|
||||||
Note that your callback needs to handle *all* possible model field types, not
|
|
||||||
just the ones that you want to behave differently to the default. That's why
|
|
||||||
this example has an ``else`` clause that implements the default behavior.
|
|
||||||
|
|
||||||
.. warning::
|
|
||||||
The field that is passed into the ``formfield_callback`` function in
|
|
||||||
``form_for_model()`` and ``form_for_instance`` is the field instance from
|
|
||||||
your model's class. You **must not** alter that object at all; treat it
|
|
||||||
as read-only!
|
|
||||||
|
|
||||||
If you make any alterations to that object, it will affect any future
|
|
||||||
users of the model class, because you will have changed the field object
|
|
||||||
used to construct the class. This is almost certainly what you don't want
|
|
||||||
to have happen.
|
|
||||||
|
|
||||||
Finding the model associated with a form
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The model class that was used to construct the form is available
|
|
||||||
using the ``_model`` property of the generated form::
|
|
||||||
|
|
||||||
>>> ArticleForm = form_for_model(Article)
|
|
||||||
>>> ArticleForm._model
|
|
||||||
<class 'myapp.models.Article'>
|
|
||||||
|
|
||||||
``form_for_instance()``
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
``form_for_instance()`` is like ``form_for_model()``, but it takes a model
|
|
||||||
instance instead of a model class::
|
|
||||||
|
|
||||||
# Create an Author.
|
|
||||||
>>> a = Author(name='Joe Smith', title='MR', birth_date=None)
|
|
||||||
>>> a.save()
|
|
||||||
|
|
||||||
# Create a form for this particular Author.
|
|
||||||
>>> AuthorForm = form_for_instance(a)
|
|
||||||
|
|
||||||
# Instantiate the form.
|
|
||||||
>>> f = AuthorForm()
|
|
||||||
|
|
||||||
When a form created by ``form_for_instance()`` is created, the initial data
|
|
||||||
values for the form fields are drawn from the instance. However, this data is
|
|
||||||
not bound to the form. You will need to bind data to the form before the form
|
|
||||||
can be saved.
|
|
||||||
|
|
||||||
Unlike ``form_for_model()``, a choice field in form created by
|
|
||||||
``form_for_instance()`` will not include the blank choice if the respective
|
|
||||||
model field has ``blank=False``. The initial choice is drawn from the instance.
|
|
||||||
|
|
||||||
When you call ``save()`` on a form created by ``form_for_instance()``,
|
|
||||||
the database instance will be updated. As in ``form_for_model()``, ``save()``
|
|
||||||
will raise ``ValueError`` if the data doesn't validate.
|
|
||||||
|
|
||||||
``form_for_instance()`` has ``form``, ``fields`` and ``formfield_callback``
|
|
||||||
arguments that behave the same way as they do for ``form_for_model()``.
|
|
||||||
|
|
||||||
Let's modify the earlier `contact form`_ view example a little bit. Suppose we
|
|
||||||
have a ``Message`` model that holds each contact submission. Something like::
|
|
||||||
|
|
||||||
class Message(models.Model):
|
|
||||||
subject = models.CharField(max_length=100)
|
|
||||||
message = models.TextField()
|
|
||||||
sender = models.EmailField()
|
|
||||||
cc_myself = models.BooleanField(required=False)
|
|
||||||
|
|
||||||
You could use this model to create a form (using ``form_for_model()``). You
|
|
||||||
could also use existing ``Message`` instances to create a form for editing
|
|
||||||
messages. The `simple example view`_ can be changed slightly to accept the ``id`` value
|
|
||||||
of an existing ``Message`` and present it for editing::
|
|
||||||
|
|
||||||
def contact_edit(request, msg_id):
|
|
||||||
# Create the form from the message id.
|
|
||||||
message = get_object_or_404(Message, id=msg_id)
|
|
||||||
ContactForm = form_for_instance(message)
|
|
||||||
|
|
||||||
if request.method == 'POST':
|
|
||||||
form = ContactForm(request.POST)
|
|
||||||
if form.is_valid():
|
|
||||||
form.save()
|
|
||||||
return HttpResponseRedirect('/url/on_success/')
|
|
||||||
else:
|
|
||||||
form = ContactForm()
|
|
||||||
return render_to_response('contact.html', {'form': form})
|
|
||||||
|
|
||||||
Aside from how we create the ``ContactForm`` class here, the main point to
|
|
||||||
note is that the form display in the ``GET`` branch of the function
|
|
||||||
will use the values from the ``message`` instance as initial values for the
|
|
||||||
form field.
|
|
||||||
|
|
||||||
.. _contact form: ../forms/#simple-view-example
|
|
||||||
.. _`simple example view`: ../forms/#simple-view-example
|
|
||||||
|
|
||||||
When should you use ``form_for_model()`` and ``form_for_instance()``?
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The ``form_for_model()`` and ``form_for_instance()`` functions are meant to be
|
|
||||||
shortcuts for the common case. If you want to create a form whose fields map to
|
|
||||||
more than one model, or a form that contains fields that *aren't* on a model,
|
|
||||||
you shouldn't use these shortcuts. Creating a ``Form`` class the "long" way
|
|
||||||
isn't that difficult, after all.
|
|
|
@ -1828,11 +1828,7 @@ Generating forms for models
|
||||||
The prefered way of generating forms that work with models is explained in the
|
The prefered way of generating forms that work with models is explained in the
|
||||||
`ModelForms documentation`_.
|
`ModelForms documentation`_.
|
||||||
|
|
||||||
Looking for the ``form_for_model`` and ``form_for_instance`` documentation?
|
|
||||||
They've been deprecated, but you can still `view the documentation`_.
|
|
||||||
|
|
||||||
.. _ModelForms documentation: ../modelforms/
|
.. _ModelForms documentation: ../modelforms/
|
||||||
.. _view the documentation: ../form_for_model/
|
|
||||||
|
|
||||||
Media
|
Media
|
||||||
=====
|
=====
|
||||||
|
|
|
@ -308,12 +308,11 @@ For example, say your ``MEDIA_ROOT`` is set to ``'/home/media'``, and
|
||||||
upload a file on Jan. 15, 2007, it will be saved in the directory
|
upload a file on Jan. 15, 2007, it will be saved in the directory
|
||||||
``/home/media/photos/2007/01/15``.
|
``/home/media/photos/2007/01/15``.
|
||||||
|
|
||||||
If you want to retrieve the upload file's on-disk filename, or a URL that
|
Information about the uploaded ``File`` object, such as its on-disk filename,
|
||||||
refers to that file, or the file's size, you can use the
|
its size, or its URL, is available via attributes on the object itself. See the
|
||||||
``get_FOO_filename()``, ``get_FOO_url()`` and ``get_FOO_size()`` methods.
|
`managing files`__ documentation for more information about ``File`` objects.
|
||||||
They are all documented here__.
|
|
||||||
|
|
||||||
__ ../db-api/#get-foo-filename
|
__ ../files/
|
||||||
|
|
||||||
Note that whenever you deal with uploaded files, you should pay close attention
|
Note that whenever you deal with uploaded files, you should pay close attention
|
||||||
to where you're uploading them and what type of files they are, to avoid
|
to where you're uploading them and what type of files they are, to avoid
|
||||||
|
@ -392,19 +391,17 @@ image. Has two extra optional arguments, ``height_field`` and
|
||||||
``width_field``, which, if set, will be auto-populated with the height and
|
``width_field``, which, if set, will be auto-populated with the height and
|
||||||
width of the image each time a model instance is saved.
|
width of the image each time a model instance is saved.
|
||||||
|
|
||||||
In addition to the special ``get_FOO_*`` methods that are available for
|
In addition to the `standard attributes and methods`_ that are available for
|
||||||
``FileField``, an ``ImageField`` also has ``get_FOO_height()`` and
|
``FileField``, an ``ImageField`` also has ``width`` and ``height`` attributes.
|
||||||
``get_FOO_width()`` methods. These are documented elsewhere_.
|
|
||||||
|
|
||||||
Requires the `Python Imaging Library`_.
|
Requires the `Python Imaging Library`_.
|
||||||
|
|
||||||
.. _Python Imaging Library: http://www.pythonware.com/products/pil/
|
|
||||||
.. _elsewhere: ../db-api/#get-foo-height-and-get-foo-width
|
|
||||||
|
|
||||||
**New in development version:** By default, ``ImageField`` instances are
|
**New in development version:** By default, ``ImageField`` instances are
|
||||||
created as ``varchar(100)`` columns in your database. As with other fields, you
|
created as ``varchar(100)`` columns in your database. As with other fields, you
|
||||||
can change the maximum length using the ``max_length`` argument.
|
can change the maximum length using the ``max_length`` argument.
|
||||||
|
|
||||||
|
.. _standard attributes and methods: ../files/#file-attributes-and-methods
|
||||||
|
.. _Python Imaging Library: http://www.pythonware.com/products/pil/
|
||||||
|
|
||||||
``IntegerField``
|
``IntegerField``
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -363,9 +363,8 @@ from the form can't provide a value for that field!
|
||||||
<tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr>
|
<tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr>
|
||||||
<tr><th>Pub date:</th><td><input type="text" name="pub_date" /></td></tr>
|
<tr><th>Pub date:</th><td><input type="text" name="pub_date" /></td></tr>
|
||||||
|
|
||||||
Use form_for_instance to create a Form from a model instance. The difference
|
When the ModelForm is passed an instance, that instance's current values are
|
||||||
between this Form and one created via form_for_model is that the object's
|
inserted as 'initial' data in each Field.
|
||||||
current values are inserted as 'initial' data in each Field.
|
|
||||||
>>> w = Writer.objects.get(name='Mike Royko')
|
>>> w = Writer.objects.get(name='Mike Royko')
|
||||||
>>> class RoykoForm(ModelForm):
|
>>> class RoykoForm(ModelForm):
|
||||||
... class Meta:
|
... class Meta:
|
||||||
|
|
|
@ -25,7 +25,7 @@ class FileForm(django_forms.Form):
|
||||||
file1 = django_forms.FileField()
|
file1 = django_forms.FileField()
|
||||||
|
|
||||||
__test__ = {'API_TESTS': """
|
__test__ = {'API_TESTS': """
|
||||||
>>> from django.forms import form_for_model, form_for_instance
|
>>> from django.forms.models import ModelForm
|
||||||
>>> from django.core.files.uploadedfile import SimpleUploadedFile
|
>>> from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
|
|
||||||
# FileModel with unicode filename and data #########################
|
# FileModel with unicode filename and data #########################
|
||||||
|
@ -37,7 +37,9 @@ True
|
||||||
>>> m = FileModel.objects.create(file=f.cleaned_data['file1'])
|
>>> m = FileModel.objects.create(file=f.cleaned_data['file1'])
|
||||||
|
|
||||||
# Boundary conditions on a PostitiveIntegerField #########################
|
# Boundary conditions on a PostitiveIntegerField #########################
|
||||||
>>> BoundaryForm = form_for_model(BoundaryModel)
|
>>> class BoundaryForm(ModelForm):
|
||||||
|
... class Meta:
|
||||||
|
... model = BoundaryModel
|
||||||
>>> f = BoundaryForm({'positive_integer': 100})
|
>>> f = BoundaryForm({'positive_integer': 100})
|
||||||
>>> f.is_valid()
|
>>> f.is_valid()
|
||||||
True
|
True
|
||||||
|
@ -51,7 +53,9 @@ False
|
||||||
# Formfield initial values ########
|
# Formfield initial values ########
|
||||||
If the model has default values for some fields, they are used as the formfield
|
If the model has default values for some fields, they are used as the formfield
|
||||||
initial values.
|
initial values.
|
||||||
>>> DefaultsForm = form_for_model(Defaults)
|
>>> class DefaultsForm(ModelForm):
|
||||||
|
... class Meta:
|
||||||
|
... model = Defaults
|
||||||
>>> DefaultsForm().fields['name'].initial
|
>>> DefaultsForm().fields['name'].initial
|
||||||
u'class default value'
|
u'class default value'
|
||||||
>>> DefaultsForm().fields['def_date'].initial
|
>>> DefaultsForm().fields['def_date'].initial
|
||||||
|
@ -59,14 +63,14 @@ datetime.date(1980, 1, 1)
|
||||||
>>> DefaultsForm().fields['value'].initial
|
>>> DefaultsForm().fields['value'].initial
|
||||||
42
|
42
|
||||||
|
|
||||||
In form_for_instance(), the initial values come from the instance's values, not
|
In a ModelForm that is passed an instance, the initial values come from the
|
||||||
the model's defaults.
|
instance's values, not the model's defaults.
|
||||||
>>> foo_instance = Defaults(name=u'instance value', def_date=datetime.date(1969, 4, 4), value=12)
|
>>> foo_instance = Defaults(name=u'instance value', def_date=datetime.date(1969, 4, 4), value=12)
|
||||||
>>> InstanceForm = form_for_instance(foo_instance)
|
>>> instance_form = DefaultsForm(instance=foo_instance)
|
||||||
>>> InstanceForm().fields['name'].initial
|
>>> instance_form.initial['name']
|
||||||
u'instance value'
|
u'instance value'
|
||||||
>>> InstanceForm().fields['def_date'].initial
|
>>> instance_form.initial['def_date']
|
||||||
datetime.date(1969, 4, 4)
|
datetime.date(1969, 4, 4)
|
||||||
>>> InstanceForm().fields['value'].initial
|
>>> instance_form.initial['value']
|
||||||
12
|
12
|
||||||
"""}
|
"""}
|
||||||
|
|
Loading…
Reference in New Issue