Django

Code

Ticket #4001: save_instance_m2m.patch

File save_instance_m2m.patch, 1.8 kB (added by SmileyChris, 2 years ago)
  • django/newforms/models.py

    old new  
    3535    if form.errors: 
    3636        raise ValueError("The %s could not be changed because the data didn't validate." % opts.object_name) 
    3737    clean_data = form.clean_data 
     38    # If many-to-many data is given and the record doesn't exist in the 
     39    # database yet, the many-to-many data will be lost. This happens because 
     40    # many-to-many options cannot be set on an object until after it's saved. 
     41    if not commit: 
     42        many_to_many_data = False 
     43        for f in opts.many_to_many: 
     44            if clean_data.get(f.name): 
     45                many_to_many_data = True 
     46                break 
     47        if many_to_many_data: 
     48            try: 
     49                instance.__class__._default_manager.get(pk=instance._get_pk_val()) 
     50            except instance.DoesNotExist: 
     51                raise ValueError("The %s could not be created because many-to-many data was provided for this unsaved record." % opts.object_name) 
    3852    for f in opts.fields: 
    3953        if not f.editable or isinstance(f, models.AutoField) or not f.name in clean_data: 
    4054            continue 
    4155        setattr(instance, f.name, clean_data[f.name]) 
    4256    if commit: 
    4357        instance.save() 
     58    if instance._get_pk_val(): 
    4459        for f in opts.many_to_many: 
    4560            if f.name in clean_data: 
    4661                setattr(instance, f.attname, clean_data[f.name]) 
    47     # GOTCHA: If many-to-many data is given and commit=False, the many-to-many 
    48     # data will be lost. This happens because a many-to-many options cannot be 
    49     # set on an object until after it's saved. Maybe we should raise an 
    50     # exception in that case. 
    5162    return instance 
    5263 
    5364def make_instance_save(instance):