Django

Code

Changeset 8291

Show
Ignore:
Timestamp:
08/10/08 16:10:47 (11 months ago)
Author:
gwilson
Message:

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.
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/core/files/storage.py

    r8262 r8291  
    3737        proper File object, ready to be read from the beginning. 
    3838        """ 
    39         # Check for old-style usage. Warn here first since there are multiple 
    40         # locations where we need to support both new and old usage. 
    41         if isinstance(content, basestring): 
    42             import warnings 
    43             warnings.warn( 
    44                 message = "Representing files as strings is deprecated." \ 
    45                           "Use django.core.files.base.ContentFile instead.", 
    46                 category = DeprecationWarning, 
    47                 stacklevel = 2 
    48             ) 
    49             from django.core.files.base import ContentFile 
    50             content = ContentFile(content) 
    51  
    5239        # Get the proper name for the file, as it will actually be saved. 
    5340        if name is None: 
  • django/trunk/django/core/files/uploadedfile.py

    r8244 r8291  
    44 
    55import os 
    6 import warnings 
    76try: 
    87    from cStringIO import StringIO 
     
    1211from django.conf import settings 
    1312from django.core.files.base import File 
    14  
    1513from django.core.files import temp as tempfile 
    1614 
    17 __all__ = ('UploadedFile', 'TemporaryUploadedFile', 'InMemoryUploadedFile', 'SimpleUploadedFile') 
    18  
    19 # Because we fooled around with it a bunch, UploadedFile has a bunch 
    20 # of deprecated properties. This little shortcut helps define 'em 
    21 # without too much code duplication. 
    22 def deprecated_property(old, new, readonly=False): 
    23     def issue_warning(): 
    24         warnings.warn( 
    25             message = "UploadedFile.%s is deprecated; use UploadedFile.%s instead." % (old, new), 
    26             category = DeprecationWarning, 
    27             stacklevel = 3 
    28         ) 
    29      
    30     def getter(self): 
    31         issue_warning() 
    32         return getattr(self, new) 
    33          
    34     def setter(self, value): 
    35         issue_warning() 
    36         setattr(self, new, value) 
    37          
    38     if readonly: 
    39         return property(getter) 
    40     else: 
    41         return property(getter, setter) 
     15__all__ = ('UploadedFile', 'TemporaryUploadedFile', 'InMemoryUploadedFile', 
     16           'SimpleUploadedFile') 
    4217 
    4318class UploadedFile(File): 
     
    7853    name = property(_get_name, _set_name) 
    7954 
    80     # Deprecated properties 
    81     filename = deprecated_property(old="filename", new="name") 
    82     file_name = deprecated_property(old="file_name", new="name") 
    83     file_size = deprecated_property(old="file_size", new="size") 
    84     chunk = deprecated_property(old="chunk", new="chunks", readonly=True) 
    85  
    86     def _get_data(self): 
    87         warnings.warn( 
    88             message = "UploadedFile.data is deprecated; use UploadedFile.read() instead.", 
    89             category = DeprecationWarning, 
    90             stacklevel = 2 
    91         ) 
    92         return self.read() 
    93     data = property(_get_data) 
    94  
    9555    # Abstract methods; subclasses *must* define read() and probably should 
    9656    # define open/close. 
     
    10363    def close(self): 
    10464        pass 
    105  
    106     # Backwards-compatible support for uploaded-files-as-dictionaries. 
    107     def __getitem__(self, key): 
    108         warnings.warn( 
    109             message = "The dictionary access of uploaded file objects is deprecated. Use the new object interface instead.", 
    110             category = DeprecationWarning, 
    111             stacklevel = 2 
    112         ) 
    113         backwards_translate = { 
    114             'filename': 'name', 
    115             'content-type': 'content_type', 
    116         } 
    117  
    118         if key == 'content': 
    119             return self.read() 
    120         elif key == 'filename': 
    121             return self.name 
    122         elif key == 'content-type': 
    123             return self.content_type 
    124         else: 
    125             return getattr(self, key) 
    12665 
    12766class TemporaryUploadedFile(UploadedFile): 
     
    14180        """ 
    14281        return self._file.name 
    143      
     82 
    14483    # Most methods on this object get proxied to NamedTemporaryFile. 
    14584    # We can't directly subclass because NamedTemporaryFile is actually a 
     
    16099                # before the exception 
    161100                return 
    162             else:  
     101            else: 
    163102                raise e 
    164          
     103 
    165104class InMemoryUploadedFile(UploadedFile): 
    166105    """ 
  • django/trunk/django/db/models/base.py

    r8267 r8291  
    44import os 
    55from itertools import izip 
    6 from warnings import warn 
    76try: 
    87    set 
     
    478477        return getattr(self, cachename) 
    479478 
    480     def _get_FIELD_filename(self, field): 
    481         warn("instance.get_%s_filename() is deprecated. Use instance.%s.path instead." % \ 
    482             (field.attname, field.attname), DeprecationWarning, stacklevel=3) 
    483         try: 
    484             return getattr(self, field.attname).path 
    485         except ValueError: 
    486             return '' 
    487  
    488     def _get_FIELD_url(self, field): 
    489         warn("instance.get_%s_url() is deprecated. Use instance.%s.url instead." % \ 
    490             (field.attname, field.attname), DeprecationWarning, stacklevel=3) 
    491         try: 
    492             return getattr(self, field.attname).url 
    493         except ValueError: 
    494             return '' 
    495  
    496     def _get_FIELD_size(self, field): 
    497         warn("instance.get_%s_size() is deprecated. Use instance.%s.size instead." % \ 
    498             (field.attname, field.attname), DeprecationWarning, stacklevel=3) 
    499         return getattr(self, field.attname).size 
    500  
    501     def _save_FIELD_file(self, field, filename, content, save=True): 
    502         warn("instance.save_%s_file() is deprecated. Use instance.%s.save() instead." % \ 
    503             (field.attname, field.attname), DeprecationWarning, stacklevel=3) 
    504         return getattr(self, field.attname).save(filename, content, save) 
    505  
    506     _save_FIELD_file.alters_data = True 
    507  
    508     def _get_FIELD_width(self, field): 
    509         warn("instance.get_%s_width() is deprecated. Use instance.%s.width instead." % \ 
    510             (field.attname, field.attname), DeprecationWarning, stacklevel=3) 
    511         return getattr(self, field.attname).width() 
    512  
    513     def _get_FIELD_height(self, field): 
    514         warn("instance.get_%s_height() is deprecated. Use instance.%s.height instead." % \ 
    515             (field.attname, field.attname), DeprecationWarning, stacklevel=3) 
    516         return getattr(self, field.attname).height() 
    517479 
    518480 
  • django/trunk/django/db/models/fields/files.py

    r8244 r8291  
    193193        super(FileField, self).contribute_to_class(cls, name) 
    194194        setattr(cls, self.name, FileDescriptor(self)) 
    195         setattr(cls, 'get_%s_filename' % self.name, curry(cls._get_FIELD_filename, field=self)) 
    196         setattr(cls, 'get_%s_url' % self.name, curry(cls._get_FIELD_url, field=self)) 
    197         setattr(cls, 'get_%s_size' % self.name, curry(cls._get_FIELD_size, field=self)) 
    198         setattr(cls, 'save_%s_file' % self.name, lambda instance, name, content, save=True: instance._save_FIELD_file(self, name, content, save)) 
    199195        signals.post_delete.connect(self.delete_file, sender=cls) 
    200196 
     
    263259class ImageFieldFile(ImageFile, FieldFile): 
    264260    def save(self, name, content, save=True): 
    265  
    266         if not hasattr(content, 'read'): 
    267             import warnings 
    268             warnings.warn( 
    269                 message = "Representing files as strings is deprecated." \ 
    270                           "Use django.core.files.base.ContentFile instead.", 
    271                 category = DeprecationWarning, 
    272                 stacklevel = 2 
    273             ) 
    274             content = ContentFile(content) 
    275  
    276261        # Repopulate the image dimension cache. 
    277262        self._dimensions_cache = get_image_dimensions(content) 
    278          
     263 
    279264        # Update width/height fields, if needed 
    280265        if self.field.width_field: 
     
    282267        if self.field.height_field: 
    283268            setattr(self.instance, self.field.height_field, self.height) 
    284          
     269 
    285270        super(ImageFieldFile, self).save(name, content, save) 
    286271 
     
    301286        return [oldforms.ImageUploadField, oldforms.HiddenField] 
    302287 
    303     def contribute_to_class(self, cls, name): 
    304         super(ImageField, self).contribute_to_class(cls, name) 
    305         # Add get_BLAH_width and get_BLAH_height methods, but only if the 
    306         # image field doesn't have width and height cache fields. 
    307         if not self.width_field: 
    308             setattr(cls, 'get_%s_width' % self.name, curry(cls._get_FIELD_width, field=self)) 
    309         if not self.height_field: 
    310             setattr(cls, 'get_%s_height' % self.name, curry(cls._get_FIELD_height, field=self)) 
    311  
    312288    def formfield(self, **kwargs): 
    313289        defaults = {'form_class': forms.ImageField} 
  • django/trunk/django/dispatch/dispatcher.py

    r8223 r8291  
    11import weakref 
    2 import warnings 
    32try: 
    43    set 
     
    198197                if r_key == key: 
    199198                    del self.receivers[idx] 
    200  
    201 def connect(receiver, signal, sender=None, weak=True): 
    202     """ 
    203     For backward compatibility only. See Signal.connect() 
    204     """ 
    205     warnings.warn( 
    206         category   = DeprecationWarning, 
    207         message    = "dispatcher.connect() is deprecated; use Signal.connect() instead.", 
    208         stacklevel = 2 
    209     ) 
    210     return signal.connect(receiver, sender, weak) 
    211  
    212 def disconnect(receiver, signal, sender=None, weak=True): 
    213     """ 
    214     For backward compatibility only. See Signal.disconnect() 
    215     """ 
    216     warnings.warn( 
    217         category   = DeprecationWarning, 
    218         message    = "dispatcher.disconnect() is deprecated; use Signal.disconnect() instead.", 
    219         stacklevel = 2 
    220     ) 
    221     signal.disconnect(receiver, sender, weak) 
    222  
    223 def send(signal, sender=None, **named): 
    224     """ 
    225     For backward compatibility only. See Signal.send() 
    226     """ 
    227     warnings.warn( 
    228         category   = DeprecationWarning, 
    229         message    = "dispatcher.send() is deprecated; use Signal.send() instead.", 
    230         stacklevel = 2 
    231     ) 
    232     return signal.send(sender=sender, **named) 
    233  
    234 def sendExact(signal, sender, **named ): 
    235     """ 
    236     This function is deprecated, as it now has the same meaning as send. 
    237     """ 
    238     warnings.warn( 
    239         category   = DeprecationWarning, 
    240         message    = "dispatcher.sendExact() is deprecated; use Signal.send() instead.", 
    241         stacklevel = 2 
    242     ) 
    243     return signal.send(sender=sender, **named) 
  • django/trunk/django/forms/fields.py

    r8148 r8291  
    443443            return initial 
    444444 
    445         if isinstance(data, dict): 
    446             # We warn once, then support both ways below. 
    447             import warnings 
    448             warnings.warn( 
    449                 message = "Representing uploaded files as dictionaries is deprecated. Use django.core.files.uploadedfile.SimpleUploadedFile instead.", 
    450                 category = DeprecationWarning, 
    451                 stacklevel = 2 
    452             ) 
    453             data = UploadedFile(data['filename'], data['content']) 
    454  
     445        # UploadedFile objects should have name and size attributes. 
    455446        try: 
    456447            file_name = data.name 
     
    508499            trial_image = Image.open(file) 
    509500            trial_image.verify() 
    510         except ImportError:  
     501        except ImportError: 
    511502            # Under PyPy, it is possible to import PIL. However, the underlying 
    512             # _imaging C module isn't available, so an ImportError will be  
    513             # raised. Catch and re-raise.  
     503            # _imaging C module isn't available, so an ImportError will be 
     504            # raised. Catch and re-raise. 
    514505            raise 
    515506        except Exception: # Python Imaging Library doesn't recognize it as an image 
     
    644635                    return True 
    645636        return False 
    646          
     637 
    647638class MultipleChoiceField(ChoiceField): 
    648639    hidden_widget = MultipleHiddenInput 
  • django/trunk/django/forms/models.py

    r8243 r8291  
    33and database field objects. 
    44""" 
    5  
    6 from warnings import warn 
    75 
    86from django.utils.translation import ugettext_lazy as _ 
     
    1917__all__ = ( 
    2018    'ModelForm', 'BaseModelForm', 'model_to_dict', 'fields_for_model', 
    21     'save_instance', 'form_for_model', 'form_for_instance', 'form_for_fields', 
    22     'ModelChoiceField', 'ModelMultipleChoiceField', 
     19    'save_instance', 'form_for_fields', 'ModelChoiceField', 
     20    'ModelMultipleChoiceField', 
    2321) 
    2422 
     
    7573    return save 
    7674 
    77 def form_for_model(model, form=BaseForm, fields=None, 
    78                    formfield_callback=lambda f: f.formfield()): 
    79     """ 
    80     Returns a Form class for the given Django model class. 
    81  
    82     Provide ``form`` if you want to use a custom BaseForm subclass. 
    83  
    84     Provide ``formfield_callback`` if you want to define different logic for 
    85     determining the formfield for a given database field. It's a callable that 
    86     takes a database Field instance and returns a form Field instance. 
    87     """ 
    88     warn("form_for_model is deprecated. Use ModelForm instead.", 
    89         PendingDeprecationWarning, stacklevel=3) 
    90     opts = model._meta 
    91     field_list = [] 
    92     for f in opts.fields + opts.many_to_many: 
    93         if not f.editable: 
    94             continue 
    95         if fields and not f.name in fields: 
    96             continue 
    97         formfield = formfield_callback(f) 
    98         if formfield: 
    99             field_list.append((f.name, formfield)) 
    100     base_fields = SortedDict(field_list) 
    101     return type(opts.object_name + 'Form', (form,), 
    102         {'base_fields': base_fields, '_model': model, 
    103          'save': make_model_save(model, fields, 'created')}) 
    104  
    105 def form_for_instance(instance, form=BaseForm, fields=None, 
    106                       formfield_callback=lambda f, **kwargs: f.formfield(**kwargs)): 
    107     """ 
    108     Returns a Form class for the given Django model instance. 
    109  
    110     Provide ``form`` if you want to use a custom BaseForm subclass. 
    111  
    112     Provide ``formfield_callback`` if you want to define different logic for 
    113     determining the formfield for a given database field. It's a callable that 
    114     takes a database Field instance, plus **kwargs, and returns a form Field 
    115     instance with the given kwargs (i.e. 'initial'). 
    116     """ 
    117     warn("form_for_instance is deprecated. Use ModelForm instead.", 
    118         PendingDeprecationWarning, stacklevel=3) 
    119     model = instance.__class__ 
    120     opts = model._meta 
    121     field_list = [] 
    122     for f in opts.fields + opts.many_to_many: 
    123         if not f.editable: 
    124             continue 
    125         if fields and not f.name in fields: 
    126             continue 
    127         current_value = f.value_from_object(instance) 
    128         formfield = formfield_callback(f, initial=current_value) 
    129         if formfield: 
    130             field_list.append((f.name, formfield)) 
    131     base_fields = SortedDict(field_list) 
    132     return type(opts.object_name + 'InstanceForm', (form,), 
    133         {'base_fields': base_fields, '_model': model, 
    134          'save': make_instance_save(instance, fields, 'changed')}) 
    135  
    13675def form_for_fields(field_list): 
    13776    """ 
     
    290229    setattr(Meta, 'exclude', exclude) 
    291230    class_name = model.__name__ + 'Form' 
    292     return ModelFormMetaclass(class_name, (form,), {'Meta': Meta,  
     231    return ModelFormMetaclass(class_name, (form,), {'Meta': Meta, 
    293232                              'formfield_callback': formfield_callback}) 
    294233 
     
    411350        self.rel_name = RelatedObject(self.fk.rel.to, self.model, self.fk).get_accessor_name() 
    412351        super(BaseInlineFormSet, self).__init__(data, files, prefix=prefix or self.rel_name) 
    413      
     352 
    414353    def _construct_forms(self): 
    415354        if self.save_as_new: 
     
    420359    def get_queryset(self): 
    421360        """ 
    422         Returns this FormSet's queryset, but restricted to children of  
     361        Returns this FormSet's queryset, but restricted to children of 
    423362        self.instance 
    424363        """ 
     
    444383            fk = fks_to_parent[0] 
    445384            if not isinstance(fk, ForeignKey) or \ 
    446                     (fk.rel.to != parent_model and  
     385                    (fk.rel.to != parent_model and 
    447386                     fk.rel.to not in parent_model._meta.parents.keys()): 
    448387                raise Exception("fk_name '%s' is not a ForeignKey to %s" % (fk_name, parent_model)) 
     
    452391        # Try to discover what the ForeignKey from model to parent_model is 
    453392        fks_to_parent = [ 
    454             f for f in opts.fields  
    455             if isinstance(f, ForeignKey)  
    456             and (f.rel.to == parent_model  
     393            f for f in opts.fields 
     394            if isinstance(f, ForeignKey) 
     395            and (f.rel.to == parent_model 
    457396                or f.rel.to in parent_model._meta.parents.keys()) 
    458397        ] 
     
    479418    fk = _get_foreign_key(parent_model, model, fk_name=fk_name) 
    480419    # let the formset handle object deletion by default 
    481      
     420 
    482421    if exclude is not None: 
    483422        exclude.append(fk.name) 
     
    529468        self.empty_label = empty_label 
    530469        self.cache_choices = cache_choices 
    531          
     470 
    532471        # Call Field instead of ChoiceField __init__() because we don't need 
    533472        # ChoiceField.__init__(). 
     
    546485    queryset = property(_get_queryset, _set_queryset) 
    547486 
    548     # this method will be used to create object labels by the QuerySetIterator.  
    549     # Override it to customize the label.  
     487    # this method will be used to create object labels by the QuerySetIterator. 
     488    # Override it to customize the label. 
    550489    def label_from_instance(self, obj): 
    551490        """ 
     
    555494        """ 
    556495        return smart_unicode(obj) 
    557      
     496 
    558497    def _get_choices(self): 
    559498        # If self._choices is set, then somebody must have manually set 
  • django/trunk/django/views/generic/create_update.py

    r8106 r8291  
    88from django.views.generic import GenericViewError 
    99 
    10 def deprecate_follow(follow): 
    11     """ 
    12     Issues a DeprecationWarning if follow is anything but None. 
    13  
    14     The old Manipulator-based forms used a follow argument that is no longer 
    15     needed for newforms-based forms. 
    16     """ 
    17     if follow is not None: 
    18         import warnings 
    19         msg = ("Generic views have been changed to use newforms, and the" 
    20                " 'follow' argument is no longer used.  Please update your code" 
    21                " to not use the 'follow' argument.") 
    22         warnings.warn(msg, DeprecationWarning, stacklevel=3) 
    2310 
    2411def apply_extra_context(extra_context, context): 
     
    10693def create_object(request, model=None, template_name=None, 
    10794        template_loader=loader, extra_context=None, post_save_redirect=None, 
    108         login_required=False, follow=None, context_processors=None, 
    109         form_class=None): 
     95        login_required=False, context_processors=None, form_class=None): 
    11096    """ 
    11197    Generic object-creation function. 
     
    116102            the form for the object 
    117103    """ 
    118     deprecate_follow(follow) 
    119104    if extra_context is None: extra_context = {} 
    120105    if login_required and not request.user.is_authenticated(): 
     
    144129def update_object(request, model=None, object_id=None, slug=None, 
    145130        slug_field='slug', template_name=None, template_loader=loader, 
    146         extra_context=None, post_save_redirect=None, 
    147         login_required=False, follow=None, context_processors=None
    148         template_object_name='object', form_class=None): 
     131        extra_context=None, post_save_redirect=None, login_required=False, 
     132        context_processors=None, template_object_name='object'
     133        form_class=None): 
    149134    """ 
    150135    Generic object-update function. 
     
    157142            the original object being edited 
    158143    """ 
    159     deprecate_follow(follow) 
    160144    if extra_context is None: extra_context = {} 
    161145    if login_required and not request.user.is_authenticated(): 
  • django/trunk/docs/custom_model_fields.txt

    r8244 r8291  
    484484 
    485485Returns the default form field to use when this field is displayed 
    486 in a model. This method is called by the `helper functions`_ 
    487 ``form_for_model()`` and ``form_for_instance()``. 
     486in a model. 
    488487 
    489488All of the ``kwargs`` dictionary is passed directly to the form field's 
  • django/trunk/docs/db-api.txt

    r8267 r8291  
    14191419You can also use a queryset to dynamically evaluate the list of values 
    14201420instead of providing a list of literal values. The queryset must be 
    1421 reduced to a list of individual values using the ``values()`` method,  
     1421reduced to a list of individual values using the ``values()`` method, 
    14221422and then converted into a query using the ``query`` attribute:: 
    14231423 
     
    21072107 
    21082108One-to-one relationships are very similar to many-to-one relationships. 
    2109 If you define a OneToOneField on your model, instances of that model will have  
     2109If you define a OneToOneField on your model, instances of that model will have 
    21102110access to the related object via a simple attribute of the model. 
    21112111 
     
    21292129a ``DoesNotExist`` exception. 
    21302130 
    2131 Instances can be assigned to the reverse relationship in the same way as  
     2131Instances can be assigned to the reverse relationship in the same way as 
    21322132you would assign the forward relationship:: 
    2133      
     2133 
    21342134    e.entrydetail = ed 
    21352135 
     
    23142314.. _lookup API sample model: ../models/lookup/ 
    23152315 
    2316 get_FOO_filename() 
    2317 ------------------ 
    2318  
    2319 **Deprecated in Django development version**; use ``object.FOO.name`` instead. 
    2320 See `managing files`_ for details. 
    2321  
    2322 get_FOO_url() 
    2323 ------------- 
    2324  
    2325 **Deprecated in Django development version**; use ``object.FOO.url`` instead. 
    2326 See `managing files`_ for details. 
    2327  
    2328 get_FOO_size() 
    2329 -------------- 
    2330  
    2331 **Deprecated in Django development version**; use ``object.FOO.size`` instead. 
    2332 See `managing files`_ for details. 
    2333  
    2334 save_FOO_file(filename, raw_contents) 
    2335 ------------------------------------- 
    2336  
    2337 **Deprecated in Django development version**; use ``object.FOO.save()`` instead. 
    2338 See `managing files`_ for details. 
    2339  
    2340 get_FOO_height() and get_FOO_width() 
    2341 ------------------------------------ 
    2342  
    2343 **Deprecated in Django development version**; use ``object.FOO.width`` and 
    2344 ``object.FOO.height`` instead. See `managing files`_ for details. 
    2345  
    2346 .. _`managing files`: ../files/ 
    23472316 
    23482317Shortcuts 
  • django/trunk/docs/forms.txt

    r8201 r8291  
    18291829`ModelForms documentation`_. 
    18301830 
    1831 Looking for the ``form_for_model`` and ``form_for_instance`` documentation? 
    1832 They've been deprecated, but you can still `view the documentation`_. 
    1833  
    18341831.. _ModelForms documentation: ../modelforms/ 
    1835 .. _view the documentation: ../form_for_model/ 
    18361832 
    18371833Media 
  • django/trunk/docs/model-api.txt

    r8244 r8291  
    309309``/home/media/photos/2007/01/15``. 
    310310 
    311 If you want to retrieve the upload file's on-disk filename, or a URL that 
    312 refers to that file, or the file's size, you can use the 
    313 ``get_FOO_filename()``, ``get_FOO_url()`` and ``get_FOO_size()`` methods. 
    314 They are all documented here__. 
    315  
    316 __ ../db-api/#get-foo-filename 
     311Information about the uploaded ``File`` object, such as its on-disk filename, 
     312its size, or its URL, is available via attributes on the object itself. See the 
     313`managing files`__ documentation for more information about ``File`` objects. 
     314 
     315__ ../files/ 
    317316 
    318317Note that whenever you deal with uploaded files, you should pay close attention 
     
    393392width of the image each time a model instance is saved. 
    394393 
    395 In addition to the special ``get_FOO_*`` methods that are available for 
    396 ``FileField``, an ``ImageField`` also has ``get_FOO_height()`` and 
    397 ``get_FOO_width()`` methods. These are documented elsewhere_. 
     394In addition to the `standard attributes and methods`_ that are available for 
     395``FileField``, an ``ImageField`` also has ``width`` and ``height`` attributes. 
    398396 
    399397Requires the `Python Imaging Library`_. 
    400  
    401 .. _Python Imaging Library: http://www.pythonware.com/products/pil/ 
    402 .. _elsewhere: ../db-api/#get-foo-height-and-get-foo-width 
    403398 
    404399**New in development version:**  By default, ``ImageField`` instances are 
     
    406401can change the maximum length using the ``max_length`` argument. 
    407402 
     403.. _standard attributes and methods: ../files/#file-attributes-and-methods 
     404.. _Python Imaging Library: http://www.pythonware.com/products/pil/ 
    408405 
    409406``IntegerField`` 
     
    606603    ) 
    607604 
    608 The first element in each tuple is the name to apply to the group. The  
     605The first element in each tuple is the name to apply to the group. The 
    609606second element is an iterable of 2-tuples, with each 2-tuple containing 
    610 a value and a human-readable name for an option. Grouped options may be  
    611 combined with ungrouped options within a single list (such as the  
     607a value and a human-readable name for an option. Grouped options may be 
     608combined with ungrouped options within a single list (such as the 
    612609`unknown` option in this example). 
    613610 
     
    982979~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    983980 
    984 **New in Django development version**  
     981**New in Django development version** 
    985982 
    986983When you're only dealing with simple many-to-many relationships such as 
    987984mixing and matching pizzas and toppings, a standard ``ManyToManyField`` 
    988985is all you need. However, sometimes you may need to associate data with the 
    989 relationship between two models.  
     986relationship between two models. 
    990987 
    991988For example, consider the case of an application tracking the musical groups 
     
    10221019        invite_reason = models.CharField(max_length=64) 
    10231020 
    1024 When you set up the intermediary model, you explicitly specify foreign  
     1021When you set up the intermediary model, you explicitly specify foreign 
    10251022keys to the models that are involved in the ManyToMany relation. This 
    10261023explicit declaration defines how the two models are related. 
     
    10311028      on the target model (this would be ``Person`` in our example). If you 
    10321029      have more than one foreign key, a validation error will be raised. 
    1033    
    1034     * Your intermediate model must contain one - and *only* one - foreign key  
     1030 
     1031    * Your intermediate model must contain one - and *only* one - foreign key 
    10351032      on the source model (this would be ``Group`` in our example). If you 
    10361033      have more than one foreign key, a validation error will be raised. 
     
    10411038      will be treated as the two (different) sides of the many-to-many 
    10421039      relation. 
    1043      
     1040 
    10441041    * When defining a many-to-many relationship from a model to 
    10451042      itself, using an intermediary model, you *must* use 
     
    10471044      ``ManyToManyField`` above). 
    10481045 
    1049 Now that you have set up your ``ManyToManyField`` to use your intermediary  
     1046Now that you have set up your ``ManyToManyField`` to use your intermediary 
    10501047model (Membership, in this case), you're ready to start creating some 
    10511048many-to-many relationships. You do this by creating instances of the 
    10521049intermediate model:: 
    1053      
     1050 
    10541051    >>> ringo = Person.objects.create(name="Ringo Starr") 
    10551052    >>> paul = Person.objects.create(name="Paul McCartney") 
    10561053    >>> beatles = Group.objects.create(name="The Beatles") 
    10571054    >>> m1 = Membership(person=ringo, group=beatles, 
    1058     ...     date_joined=date(1962, 8, 16),  
     1055    ...     date_joined=date(1962, 8, 16), 
    10591056    ...     invite_reason= "Needed a new drummer.") 
    10601057    >>> m1.save() 
     
    10641061    [<Group: The Beatles>] 
    10651062    >>> m2 = Membership.objects.create(person=paul, group=beatles, 
    1066     ...     date_joined=date(1960, 8, 1),  
     1063    ...     date_joined=date(1960, 8, 1), 
    10671064    ...     invite_reason= "Wanted to form a band.") 
    10681065    >>> beatles.members.all() 
     
    10781075    # AND NEITHER WILL THIS 
    10791076    >>> beatles.members = [john, paul, ringo, george] 
    1080      
     1077 
    10811078Why? You can't just create a relationship between a Person and a Group - you 
    10821079need to specify all the detail for the relationship required by the 
     
    10951092 
    10961093Once you have established the many-to-many relationships by creating instances 
    1097 of your intermediate model, you can issue queries. Just as with normal  
    1098 many-to-many relationships, you can query using the attributes of the  
     1094of your intermediate model, you can issue queries. Just as with normal 
     1095many-to-many relationships, you can query using the attributes of the 
    10991096many-to-many-related model:: 
    11001097 
     
    11031100    [<Group: The Beatles>] 
    11041101 
    1105 As you are using an intermediate table, you can also query on the attributes  
     1102As you are using an intermediate table, you can also query on the attributes 
    11061103of the intermediate model:: 
    11071104 
     
    11111108    ...     membership__date_joined__gt=date(1961,1,1)) 
    11121109    [<Person: Ringo Starr] 
    1113      
     1110 
    11141111One-to-one relationships 
    11151112~~~~~~~~~~~~~~~~~~~~~~~~ 
     
    15561553    class MyManager(models.Manager):: 
    15571554        use_for_related_fields = True 
    1558          
     1555 
    15591556        ... 
    15601557 
  • django/trunk/tests/modeltests/model_forms/models.py

    r8257 r8291  
    364364<tr><th>Pub date:</th><td><input type="text" name="pub_date" /></td></tr> 
    365365 
    366 Use form_for_instance to create a Form from a model instance. The difference 
    367 between this Form and one created via form_for_model is that the object's 
    368 current values are inserted as 'initial' data in each Field. 
     366When the ModelForm is passed an instance, that instance's current values are 
     367inserted as 'initial' data in each Field. 
    369368>>> w = Writer.objects.get(name='Mike Royko') 
    370369>>> class RoykoForm(ModelForm): 
  • django/trunk/tests/regressiontests/forms/models.py

    r8013 r8291  
    2626 
    2727__test__ = {'API_TESTS': """ 
    28 >>> from django.forms import form_for_model, form_for_instance 
     28>>> from django.forms.models import ModelForm 
    2929>>> from django.core.files.uploadedfile import SimpleUploadedFile 
    3030 
     
    3838 
    3939# Boundary conditions on a PostitiveIntegerField ######################### 
    40 >>> BoundaryForm = form_for_model(BoundaryModel) 
    41 >>> f = BoundaryForm({'positive_integer':100}) 
     40>>> class BoundaryForm(ModelForm): 
     41...     class Meta: 
     42...         model = BoundaryModel 
     43>>> f = BoundaryForm({'positive_integer': 100}) 
    4244>>> f.is_valid() 
    4345True 
    44 >>> f = BoundaryForm({'positive_integer':0}) 
     46>>> f = BoundaryForm({'positive_integer': 0}) 
    4547>>> f.is_valid() 
    4648True 
    47 >>> f = BoundaryForm({'positive_integer':-100}) 
     49>>> f = BoundaryForm({'positive_integer': -100}) 
    4850>>> f.is_valid() 
    4951False 
     
    5254If the model has default values for some fields, they are used as the formfield 
    5355initial values. 
    54 >>> DefaultsForm = form_for_model(Defaults) 
     56>>> class DefaultsForm(ModelForm): 
     57...     class Meta: 
     58...         model = Defaults 
    5559>>> DefaultsForm().fields['name'].initial 
    5660u'class default value' 
     
    606442 
    6165 
    62 In form_for_instance(), the initial values come from the instance's values, not 
    63 the model's defaults. 
    64 >>> foo_instance = Defaults(name=u'instance value', def_date = datetime.date(1969, 4, 4), value = 12) 
    65 >>> InstanceForm = form_for_instance(foo_instance) 
    66 >>> InstanceForm().fields['name'].initial 
     66In a ModelForm that is passed an instance, the initial values come from the 
     67instance's values, not the model's defaults. 
     68>>> foo_instance = Defaults(name=u'instance value', def_date=datetime.date(1969, 4, 4), value=12) 
     69>>> instance_form = DefaultsForm(instance=foo_instance) 
     70>>> instance_form.initial['name'] 
    6771u'instance value' 
    68 >>> InstanceForm().fields['def_date'].initial 
     72>>> instance_form.initial['def_date'] 
    6973datetime.date(1969, 4, 4) 
    70 >>> InstanceForm().fields['value'].initial 
     74>>> instance_form.initial['value'] 
    717512 
    7276"""}