Ticket #3727: newforms_models_for_instance_exclude.diff

File newforms_models_for_instance_exclude.diff, 4.2 KB (added by Matias Hermanrud Fjeld <mhf@…>, 8 years ago)

diff against r4607.

  • django/newforms/models.py

     
    1212__all__ = ('save_instance', 'form_for_model', 'form_for_instance', 'form_for_fields',
    1313           'ModelChoiceField', 'ModelMultipleChoiceField')
    1414
    15 def model_save(self, commit=True):
    16     """
    17     Creates and returns model instance according to self.clean_data.
     15def make_model_save(exclude=[]):
     16    def save(self, commit=True):
     17        """
     18        Creates and returns model instance according to self.clean_data.
     19   
     20        This method is created for any form_for_model Form.
     21        """
     22        if self.errors:
     23            raise ValueError("The %s could not be created because the data didn't validate." % self._model._meta.object_name)
     24        return save_instance(self, self._model(), commit, exclude=exclude)
     25    return save
    1826
    19     This method is created for any form_for_model Form.
     27def save_instance(form, instance, commit=True, exclude=[]):
    2028    """
    21     if self.errors:
    22         raise ValueError("The %s could not be created because the data didn't validate." % self._model._meta.object_name)
    23     return save_instance(self, self._model(), commit)
    24 
    25 def save_instance(form, instance, commit=True):
    26     """
    2729    Saves bound Form ``form``'s clean_data into model instance ``instance``.
    2830
    2931    Assumes ``form`` has a field for every non-AutoField database field in
     
    3638        raise ValueError("The %s could not be changed because the data didn't validate." % opts.object_name)
    3739    clean_data = form.clean_data
    3840    for f in opts.fields:
    39         if not f.editable or isinstance(f, models.AutoField):
     41        if not f.editable or isinstance(f, models.AutoField) or f.name in exclude:
    4042            continue
    4143        setattr(instance, f.name, clean_data[f.name])
    4244    if commit:
     
    4951    # exception in that case.
    5052    return instance
    5153
    52 def make_instance_save(instance):
     54def make_instance_save(instance, exclude=[]):
    5355    "Returns the save() method for a form_for_instance Form."
    5456    def save(self, commit=True):
    55         return save_instance(self, instance, commit)
     57        return save_instance(self, instance, commit, exclude=exclude)
    5658    return save
    5759
    58 def form_for_model(model, form=BaseForm, formfield_callback=lambda f: f.formfield()):
     60def form_for_model(model, form=BaseForm, formfield_callback=lambda f: f.formfield(), exclude=[]):
    5961    """
    6062    Returns a Form class for the given Django model class.
    6163
     
    6870    opts = model._meta
    6971    field_list = []
    7072    for f in opts.fields + opts.many_to_many:
    71         if not f.editable:
     73        if not f.editable or f.name in exclude:
    7274            continue
    7375        formfield = formfield_callback(f)
    7476        if formfield:
    7577            field_list.append((f.name, formfield))
    7678    fields = SortedDictFromList(field_list)
    77     return type(opts.object_name + 'Form', (form,), {'base_fields': fields, '_model': model, 'save': model_save})
     79    return type(opts.object_name + 'Form', (form,), {'base_fields': fields, '_model': model, 'save': make_model_save(exclude)})
    7880
    79 def form_for_instance(instance, form=BaseForm, formfield_callback=lambda f, **kwargs: f.formfield(**kwargs)):
     81def form_for_instance(instance, form=BaseForm, formfield_callback=lambda f, **kwargs: f.formfield(**kwargs), exclude=[]):
    8082    """
    8183    Returns a Form class for the given Django model instance.
    8284
     
    9193    opts = model._meta
    9294    field_list = []
    9395    for f in opts.fields + opts.many_to_many:
    94         if not f.editable:
     96        if not f.editable or f.name in exclude:
    9597            continue
    9698        current_value = f.value_from_object(instance)
    9799        formfield = formfield_callback(f, initial=current_value)
     
    99101            field_list.append((f.name, formfield))
    100102    fields = SortedDictFromList(field_list)
    101103    return type(opts.object_name + 'InstanceForm', (form,),
    102         {'base_fields': fields, '_model': model, 'save': make_instance_save(instance)})
     104        {'base_fields': fields, '_model': model, 'save': make_instance_save(instance, exclude)})
    103105
    104106def form_for_fields(field_list):
    105107    "Returns a Form class for the given list of Django database field instances."
Back to Top