Django

Code

Changeset 1677

Show
Ignore:
Timestamp:
12/15/05 18:01:19 (3 years ago)
Author:
rjwittams
Message:

Fix models/init.py

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/magic-removal/django/db/models/__init__.py

    r1675 r1677  
    10521052    delete.alters_data = True 
    10531053 
     1054    def __get_manipulator(cls): 
     1055        if hasattr(cls, 'MANIPULATOR'): 
     1056            man = cls.MANIPULATOR 
     1057        else: 
     1058            class man: 
     1059                pass 
     1060        return man 
     1061    __get_manipulator=classmethod(__get_manipulator) 
     1062 
    10541063    def __get_add_manipulator(cls): 
    1055         cls.AddManipulator = get_manipulator 
    1056          
     1064        class AddManipulator(cls.__get_manipulator(), ModelAddManipulator): 
     1065            pass 
     1066        AddManipulator.classinit(cls) 
     1067        cls.AddManipulator = AddManipulator 
     1068        return AddManipulator 
    10571069    AddManipulator = property(classmethod(__get_add_manipulator)) 
    10581070     
    10591071    def __get_change_manipulator(cls): 
    1060          
     1072        class ChangeManipulator(cls.__get_manipulator(), ModelChangeManipulator): 
     1073            pass 
     1074        ChangeManipulator.classinit(cls) 
     1075        cls.ChangeManipulator = ChangeManipulator 
     1076        return ChangeManipulator  
    10611077    ChangeManipulator = property(classmethod(__get_change_manipulator))  
    10621078     
     
    15041520    man.get_related_objects = curry(manipulator_get_related_objects, opts, klass, add, change) 
    15051521    man.flatten_data = curry(manipulator_flatten_data, opts, klass, add, change) 
    1506     for field_name_list in opts.unique_together: 
    1507         setattr(man, 'isUnique%s' % '_'.join(field_name_list), curry(manipulator_validator_unique_together, field_name_list, opts)) 
    1508     for f in opts.fields: 
    1509         if f.unique_for_date: 
    1510             setattr(man, 'isUnique%sFor%s' % (f.name, f.unique_for_date), curry(manipulator_validator_unique_for_date, f, opts.get_field(f.unique_for_date), opts, 'date')) 
    1511         if f.unique_for_month: 
    1512             setattr(man, 'isUnique%sFor%s' % (f.name, f.unique_for_month), curry(manipulator_validator_unique_for_date, f, opts.get_field(f.unique_for_month), opts, 'month')) 
    1513         if f.unique_for_year: 
    1514             setattr(man, 'isUnique%sFor%s' % (f.name, f.unique_for_year), curry(manipulator_validator_unique_for_date, f, opts.get_field(f.unique_for_year), opts, 'year')) 
    1515     for k, v in extra_methods.items(): 
    1516         setattr(man, k, v) 
     1522     
    15171523    return man 
    15181524 
    15191525class AutomaticManipulator(formfields.Manipulator): 
    1520     def __classinit__(cls, model): 
     1526    def classinit(cls, model): 
    15211527        cls.model = model 
    15221528        cls.manager = model._default_manager 
    1523     __classinit__ = classmethod(__classinit__) 
     1529        cls.opts = model._meta 
     1530        for field_name_list in cls.opts.unique_together: 
     1531            setattr(cls, 'isUnique%s' % '_'.join(field_name_list), curry(manipulator_validator_unique_together, field_name_list, opts)) 
     1532        for f in cls.opts.fields: 
     1533            if f.unique_for_date: 
     1534                setattr(man, 'isUnique%sFor%s' % (f.name, f.unique_for_date), curry(manipulator_validator_unique_for_date, f, opts.get_field(f.unique_for_date), opts, 'date')) 
     1535            if f.unique_for_month: 
     1536                setattr(man, 'isUnique%sFor%s' % (f.name, f.unique_for_month), curry(manipulator_validator_unique_for_date, f, opts.get_field(f.unique_for_month), opts, 'month')) 
     1537            if f.unique_for_year: 
     1538                setattr(man, 'isUnique%sFor%s' % (f.name, f.unique_for_year), curry(manipulator_validator_unique_for_date, f, opts.get_field(f.unique_for_year), opts, 'year')) 
     1539    classinit = classmethod(classinit) 
    15241540     
    15251541    def __init__(self, follow=None): 
     
    15361552                fol = self.follow[f.name] 
    15371553                self.fields.extend(f.get_manipulator_fields(opts, self, change, fol)) 
     1554        self.original_object = None 
    15381555         
    1539     def save(self): 
    1540         pass 
     1556    def save(self, new_data): 
     1557        add, change, opts, klass = self.add, self.change, self.opts, self.model 
     1558        # TODO: big cleanup when core fields go -> use recursive manipulators. 
     1559        from django.utils.datastructures import DotExpandedDict 
     1560        params = {} 
     1561        for f in opts.fields: 
     1562            # Fields with auto_now_add should keep their original value in the change stage. 
     1563            auto_now_add = change and getattr(f, 'auto_now_add', False) 
     1564            if self.follow.get(f.name, None) and not auto_now_add: 
     1565                param = f.get_manipulator_new_data(new_data) 
     1566            else: 
     1567                if change: 
     1568                    param = getattr(self.original_object, f.attname) 
     1569                else: 
     1570                    param = f.get_default() 
     1571            params[f.attname] = param 
     1572     
     1573        if change: 
     1574            params[opts.pk.attname] = self.obj_key 
     1575     
     1576        # First, save the basic object itself. 
     1577        new_object = klass(**params) 
     1578        new_object.save() 
     1579     
     1580        # Now that the object's been saved, save any uploaded files. 
     1581        for f in opts.fields: 
     1582            if isinstance(f, FileField): 
     1583                f.save_file(new_data, new_object, change and self.original_object or None, change, rel=False) 
     1584     
     1585        # Calculate which primary fields have changed. 
     1586        if change: 
     1587            self.fields_added, self.fields_changed, self.fields_deleted = [], [], [] 
     1588            for f in opts.fields: 
     1589                if not f.primary_key and str(getattr(self.original_object, f.attname)) != str(getattr(new_object, f.attname)): 
     1590                    self.fields_changed.append(f.verbose_name) 
     1591     
     1592        # Save many-to-many objects. Example: Poll.set_sites() 
     1593        for f in opts.many_to_many: 
     1594            if self.follow.get(f.name, None): 
     1595                if not f.rel.edit_inline: 
     1596                    if f.rel.raw_id_admin: 
     1597                        new_vals = new_data.get(f.name, ()) 
     1598                    else: 
     1599                        new_vals = new_data.getlist(f.name) 
     1600                    was_changed = getattr(new_object, 'set_%s' % f.name)(new_vals) 
     1601                    if change and was_changed: 
     1602                        self.fields_changed.append(f.verbose_name) 
     1603     
     1604        expanded_data = DotExpandedDict(dict(new_data)) 
     1605        # Save many-to-one objects. Example: Add the Choice objects for a Poll. 
     1606        for related in opts.get_all_related_objects(): 
     1607            # Create obj_list, which is a DotExpandedDict such as this: 
     1608            # [('0', {'id': ['940'], 'choice': ['This is the first choice']}), 
     1609            #  ('1', {'id': ['941'], 'choice': ['This is the second choice']}), 
     1610            #  ('2', {'id': [''], 'choice': ['']})] 
     1611            child_follow = self.follow.get(related.name, None) 
     1612     
     1613            if child_follow: 
     1614                obj_list = expanded_data[related.var_name].items() 
     1615                obj_list.sort(lambda x, y: cmp(int(x[0]), int(y[0]))) 
     1616                params = {} 
     1617     
     1618                # For each related item... 
     1619                for _, rel_new_data in obj_list: 
     1620     
     1621                    # Keep track of which core=True fields were provided. 
     1622                    # If all core fields were given, the related object will be saved. 
     1623                    # If none of the core fields were given, the object will be deleted. 
     1624                    # If some, but not all, of the fields were given, the validator would 
     1625                    # have caught that. 
     1626                    all_cores_given, all_cores_blank = True, True 
     1627     
     1628                    # Get a reference to the old object. We'll use it to compare the 
     1629                    # old to the new, to see which fields have changed. 
     1630                    old_rel_obj = None 
     1631                    if change: 
     1632                        if rel_new_data[related.opts.pk.name][0]: 
     1633                            try: 
     1634                                old_rel_obj = getattr(self.original_object, 'get_%s' % related.get_method_name_part() )(**{'%s__exact' % related.opts.pk.name: rel_new_data[related.opts.pk.attname][0]}) 
     1635                            except ObjectDoesNotExist: 
     1636                                pass 
     1637     
     1638                    for f in related.opts.fields: 
     1639                        if f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True) in (None, ''): 
     1640                            all_cores_given = False 
     1641                        elif f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True) not in (None, ''): 
     1642                            all_cores_blank = False 
     1643                        # If this field isn't editable, give it the same value it had 
     1644                        # previously, according to the given ID. If the ID wasn't 
     1645                        # given, use a default value. FileFields are also a special 
     1646                        # case, because they'll be dealt with later. 
     1647     
     1648                        if f == related.field: 
     1649                            param = getattr(new_object, related.field.rel.field_name) 
     1650                        elif add and isinstance(f, AutoField): 
     1651                            param = None 
     1652                        elif change and (isinstance(f, FileField) or not child_follow.get(f.name, None)): 
     1653                            if old_rel_obj: 
     1654                                param = getattr(old_rel_obj, f.column) 
     1655                            else: 
     1656                                param = f.get_default() 
     1657                        else: 
     1658                            param = f.get_manipulator_new_data(rel_new_data, rel=True) 
     1659                        if param != None: 
     1660                           params[f.attname] = param 
     1661     
     1662                    # Create the related item. 
     1663                    new_rel_obj = related.opts.get_model_module().Klass(**params) 
     1664     
     1665                    # If all the core fields were provided (non-empty), save the item. 
     1666                    if all_cores_given: 
     1667                        new_rel_obj.save() 
     1668     
     1669                        # Save any uploaded files. 
     1670                        for f in related.opts.fields: 
     1671                            if child_follow.get(f.name, None): 
     1672                                if isinstance(f, FileField) and rel_new_data.get(f.name, False): 
     1673                                    f.save_file(rel_new_data, new_rel_obj, change and old_rel_obj or None, old_rel_obj is not None, rel=True) 
     1674     
     1675                        # Calculate whether any fields have changed. 
     1676                        if change: 
     1677                            if not old_rel_obj: # This object didn't exist before. 
     1678                                self.fields_added.append('%s "%s"' % (related.opts.verbose_name, new_rel_obj)) 
     1679                            else: 
     1680                                for f in related.opts.fields: 
     1681                                    if not f.primary_key and f != related.field and str(getattr(old_rel_obj, f.attname)) != str(getattr(new_rel_obj, f.attname)): 
     1682                                        self.fields_changed.append('%s for %s "%s"' % (f.verbose_name, related.opts.verbose_name, new_rel_obj)) 
     1683     
     1684                        # Save many-to-many objects. 
     1685                        for f in related.opts.many_to_many: 
     1686                            if child_follow.get(f.name, None) and not f.rel.edit_inline: 
     1687                                was_changed = getattr(new_rel_obj, 'set_%s' % f.name)(rel_new_data[f.attname]) 
     1688                                if change and was_changed: 
     1689                                    self.fields_changed.append('%s for %s "%s"' % (f.verbose_name, related.opts.verbose_name, new_rel_obj)) 
     1690     
     1691                    # If, in the change stage, all of the core fields were blank and 
     1692                    # the primary key (ID) was provided, delete the item. 
     1693                    if change and all_cores_blank and old_rel_obj: 
     1694                        new_rel_obj.delete() 
     1695                        self.fields_deleted.append('%s "%s"' % (related.opts.verbose_name, old_rel_obj)) 
     1696     
     1697        # Save the order, if applicable. 
     1698        if change and opts.get_ordered_objects(): 
     1699            order = new_data['order_'] and map(int, new_data['order_'].split(',')) or [] 
     1700            for rel_opts in opts.get_ordered_objects(): 
     1701                getattr(new_object, 'set_%s_order' % rel_opts.object_name.lower())(order) 
     1702        return new_object 
    15411703     
    15421704    def get_related_objects(opts, klass, add, change, self): 
     
    15451707    def flatten_data(opts, klass, add, change, self): 
    15461708         new_data = {} 
    1547          obj = change and self.original_object or None 
    15481709         for f in opts.get_data_holders(self.follow): 
    15491710            fol = self.follow.get(f.name) 
    1550             new_data.update(f.flatten_data(fol, obj)) 
     1711            new_data.update(f.flatten_data(fol, self.original_object)) 
    15511712         return new_data 
    15521713 
    15531714class ModelAddManipulator(AutomaticManipulator): 
    1554     pass 
    1555  
    1556 class ModelSaveManipulator(AutomaticManipulator): 
     1715    change = False 
     1716    add = True 
     1717 
     1718class ModelChangeManipulator(AutomaticManipulator): 
     1719    change = False 
     1720    add = True 
     1721     
    15571722    def __init__(self, obj_key=None, follow=None): 
    1558         
    15591723        assert obj_key is not None, "ChangeManipulator.__init__() must be passed obj_key parameter." 
    15601724        self.obj_key = obj_key 
    15611725        try: 
    1562             self.original_object = self.manager.get_object(pk=obj_key) 
     1726            original_object = self.manager.get_object(pk=obj_key) 
    15631727        except ObjectDoesNotExist: 
    15641728            # If the object doesn't exist, this might be a manipulator for a 
     
    15751739                params = dict([(f.attname, f.get_default()) for f in opts.fields]) 
    15761740                params[opts.pk.attname] = obj_key 
    1577                 self.original_object = opts.get_model_module().Klass(**params) 
     1741                original_object = opts.get_model_module().Klass(**params) 
    15781742            else: 
    15791743                raise 
    15801744         
    15811745        super(ModelSaveManipulator, self).__init__(self, follow=follow) 
     1746        self.original_object = original_object 
    15821747         
    15831748        if  opts.get_ordered_objects(): 
    15841749            self.fields.append(formfields.CommaSeparatedIntegerField(field_name="order_")) 
    15851750 
    1586 def manipulator_init(opts, add, change, self, obj_key=None, follow=None): 
    1587     self.follow = opts.get_follow(follow) 
    1588  
    1589     if change: 
    1590         assert obj_key is not None, "ChangeManipulator.__init__() must be passed obj_key parameter." 
    1591         self.obj_key = obj_key 
    1592         try: 
    1593             self.original_object = opts.get_model_module().get_object(pk=obj_key) 
    1594         except ObjectDoesNotExist: 
    1595             # If the object doesn't exist, this might be a manipulator for a 
    1596             # one-to-one related object that hasn't created its subobject yet. 
    1597             # For example, this might be a Restaurant for a Place that doesn't 
    1598             # yet have restaurant information. 
    1599             if opts.one_to_one_field: 
    1600                 # Sanity check -- Make sure the "parent" object exists. 
    1601                 # For example, make sure the Place exists for the Restaurant. 
    1602                 # Let the ObjectDoesNotExist exception propogate up. 
    1603                 lookup_kwargs = opts.one_to_one_field.rel.limit_choices_to 
    1604                 lookup_kwargs['%s__exact' % opts.one_to_one_field.rel.field_name] = obj_key 
    1605                 _ = opts.one_to_one_field.rel.to._meta.get_model_module().get_object(**lookup_kwargs) 
    1606                 params = dict([(f.attname, f.get_default()) for f in opts.fields]) 
    1607                 params[opts.pk.attname] = obj_key 
    1608                 self.original_object = opts.get_model_module().Klass(**params) 
    1609             else: 
    1610                 raise 
    1611     self.fields = [] 
    1612  
    1613     for f in opts.fields + opts.many_to_many: 
    1614         if self.follow.get(f.name, False): 
    1615             self.fields.extend(f.get_manipulator_fields(opts, self, change)) 
    1616  
    1617     # Add fields for related objects. 
    1618     for f in opts.get_all_related_objects(): 
    1619         if self.follow.get(f.name, False): 
    1620             fol = self.follow[f.name] 
    1621             self.fields.extend(f.get_manipulator_fields(opts, self, change, fol)) 
    1622  
    1623     # Add field for ordering. 
    1624     if change and opts.get_ordered_objects(): 
    1625         self.fields.append(formfields.CommaSeparatedIntegerField(field_name="order_")) 
    1626  
    1627 def manipulator_save(opts, klass, add, change, self, new_data): 
    1628     # TODO: big cleanup when core fields go -> use recursive manipulators. 
    1629     from django.utils.datastructures import DotExpandedDict 
    1630     params = {} 
    1631     for f in opts.fields: 
    1632         # Fields with auto_now_add should keep their original value in the change stage. 
    1633         auto_now_add = change and getattr(f, 'auto_now_add', False) 
    1634         if self.follow.get(f.name, None) and not auto_now_add: 
    1635             param = f.get_manipulator_new_data(new_data) 
    1636         else: 
    1637             if change: 
    1638                 param = getattr(self.original_object, f.attname) 
    1639             else: 
    1640                 param = f.get_default() 
    1641         params[f.attname] = param 
    1642  
    1643     if change: 
    1644         params[opts.pk.attname] = self.obj_key 
    1645  
    1646     # First, save the basic object itself. 
    1647     new_object = klass(**params) 
    1648     new_object.save() 
    1649  
    1650     # Now that the object's been saved, save any uploaded files. 
    1651     for f in opts.fields: 
    1652         if isinstance(f, FileField): 
    1653             f.save_file(new_data, new_object, change and self.original_object or None, change, rel=False) 
    1654  
    1655     # Calculate which primary fields have changed. 
    1656     if change: 
    1657         self.fields_added, self.fields_changed, self.fields_deleted = [], [], [] 
    1658         for f in opts.fields: 
    1659             if not f.primary_key and str(getattr(self.original_object, f.attname)) != str(getattr(new_object, f.attname)): 
    1660                 self.fields_changed.append(f.verbose_name) 
    1661  
    1662     # Save many-to-many objects. Example: Poll.set_sites() 
    1663     for f in opts.many_to_many: 
    1664         if self.follow.get(f.name, None): 
    1665             if not f.rel.edit_inline: 
    1666                 if f.rel.raw_id_admin: 
    1667                     new_vals = new_data.get(f.name, ()) 
    1668                 else: 
    1669                     new_vals = new_data.getlist(f.name) 
    1670                 was_changed = getattr(new_object, 'set_%s' % f.name)(new_vals) 
    1671                 if change and was_changed: 
    1672                     self.fields_changed.append(f.verbose_name) 
    1673  
    1674     expanded_data = DotExpandedDict(dict(new_data)) 
    1675     # Save many-to-one objects. Example: Add the Choice objects for a Poll. 
    1676     for related in opts.get_all_related_objects(): 
    1677         # Create obj_list, which is a DotExpandedDict such as this: 
    1678         # [('0', {'id': ['940'], 'choice': ['This is the first choice']}), 
    1679         #  ('1', {'id': ['941'], 'choice': ['This is the second choice']}), 
    1680         #  ('2', {'id': [''], 'choice': ['']})] 
    1681         child_follow = self.follow.get(related.name, None) 
    1682  
    1683         if child_follow: 
    1684             obj_list = expanded_data[related.var_name].items() 
    1685             obj_list.sort(lambda x, y: cmp(int(x[0]), int(y[0]))) 
    1686             params = {} 
    1687  
    1688             # For each related item... 
    1689             for _, rel_new_data in obj_list: 
    1690  
    1691                 # Keep track of which core=True fields were provided. 
    1692                 # If all core fields were given, the related object will be saved. 
    1693                 # If none of the core fields were given, the object will be deleted. 
    1694                 # If some, but not all, of the fields were given, the validator would 
    1695                 # have caught that. 
    1696                 all_cores_given, all_cores_blank = True, True 
    1697  
    1698                 # Get a reference to the old object. We'll use it to compare the 
    1699                 # old to the new, to see which fields have changed. 
    1700                 old_rel_obj = None 
    1701                 if change: 
    1702                     if rel_new_data[related.opts.pk.name][0]: 
    1703                         try: 
    1704                             old_rel_obj = getattr(self.original_object, 'get_%s' % related.get_method_name_part() )(**{'%s__exact' % related.opts.pk.name: rel_new_data[related.opts.pk.attname][0]}) 
    1705                         except ObjectDoesNotExist: 
    1706                             pass 
    1707  
    1708                 for f in related.opts.fields: 
    1709                     if f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True) in (None, ''): 
    1710                         all_cores_given = False 
    1711                     elif f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True) not in (None, ''): 
    1712                         all_cores_blank = False 
    1713                     # If this field isn't editable, give it the same value it had 
    1714                     # previously, according to the given ID. If the ID wasn't 
    1715                     # given, use a default value. FileFields are also a special 
    1716                     # case, because they'll be dealt with later. 
    1717  
    1718                     if f == related.field: 
    1719                         param = getattr(new_object, related.field.rel.field_name) 
    1720                     elif add and isinstance(f, AutoField): 
    1721                         param = None 
    1722                     elif change and (isinstance(f, FileField) or not child_follow.get(f.name, None)): 
    1723                         if old_rel_obj: 
    1724                             param = getattr(old_rel_obj, f.column) 
    1725                         else: 
    1726                             param = f.get_default() 
    1727                     else: 
    1728                         param = f.get_manipulator_new_data(rel_new_data, rel=True) 
    1729                     if param != None: 
    1730                        params[f.attname] = param 
    1731  
    1732                 # Create the related item. 
    1733                 new_rel_obj = related.opts.get_model_module().Klass(**params) 
    1734  
    1735                 # If all the core fields were provided (non-empty), save the item. 
    1736                 if all_cores_given: 
    1737                     new_rel_obj.save() 
    1738  
    1739                     # Save any uploaded files. 
    1740                     for f in related.opts.fields: 
    1741                         if child_follow.get(f.name, None): 
    1742                             if isinstance(f, FileField) and rel_new_data.get(f.name, False): 
    1743                                 f.save_file(rel_new_data, new_rel_obj, change and old_rel_obj or None, old_rel_obj is not None, rel=True) 
    1744  
    1745                     # Calculate whether any fields have changed. 
    1746                     if change: 
    1747                         if not old_rel_obj: # This object didn't exist before. 
    1748                             self.fields_added.append('%s "%s"' % (related.opts.verbose_name, new_rel_obj)) 
    1749                         else: 
    1750                             for f in related.opts.fields: 
    1751                                 if not f.primary_key and f != related.field and str(getattr(old_rel_obj, f.attname)) != str(getattr(new_rel_obj, f.attname)): 
    1752                                     self.fields_changed.append('%s for %s "%s"' % (f.verbose_name, related.opts.verbose_name, new_rel_obj)) 
    1753  
    1754                     # Save many-to-many objects. 
    1755                     for f in related.opts.many_to_many: 
    1756                         if child_follow.get(f.name, None) and not f.rel.edit_inline: 
    1757                             was_changed = getattr(new_rel_obj, 'set_%s' % f.name)(rel_new_data[f.attname]) 
    1758                             if change and was_changed: 
    1759                                 self.fields_changed.append('%s for %s "%s"' % (f.verbose_name, related.opts.verbose_name, new_rel_obj)) 
    1760  
    1761                 # If, in the change stage, all of the core fields were blank and 
    1762                 # the primary key (ID) was provided, delete the item. 
    1763                 if change and all_cores_blank and old_rel_obj: 
    1764                     new_rel_obj.delete() 
    1765                     self.fields_deleted.append('%s "%s"' % (related.opts.verbose_name, old_rel_obj)) 
    1766  
    1767     # Save the order, if applicable. 
    1768     if change and opts.get_ordered_objects(): 
    1769         order = new_data['order_'] and map(int, new_data['order_'].split(',')) or [] 
    1770         for rel_opts in opts.get_ordered_objects(): 
    1771             getattr(new_object, 'set_%s_order' % rel_opts.object_name.lower())(order) 
    1772     return new_object 
     1751#def manipulator_init(opts, add, change, self, obj_key=None, follow=None): 
     1752#    self.follow = opts.get_follow(follow) 
     1753
     1754#    if change: 
     1755#        assert obj_key is not None, "ChangeManipulator.__init__() must be passed obj_key parameter." 
     1756#        self.obj_key = obj_key 
     1757#        try: 
     1758#            self.original_object = opts.get_model_module().get_object(pk=obj_key) 
     1759#        except ObjectDoesNotExist: 
     1760#            # If the object doesn't exist, this might be a manipulator for a 
     1761#            # one-to-one related object that hasn't created its subobject yet. 
     1762#            # For example, this might be a Restaurant for a Place that doesn't 
     1763#            # yet have restaurant information. 
     1764#            if opts.one_to_one_field: 
     1765#                # Sanity check -- Make sure the "parent" object exists. 
     1766#                # For example, make sure the Place exists for the Restaurant. 
     1767#                # Let the ObjectDoesNotExist exception propogate up. 
     1768#                lookup_kwargs = opts.one_to_one_field.rel.limit_choices_to 
     1769#                lookup_kwargs['%s__exact' % opts.one_to_one_field.rel.field_name] = obj_key 
     1770#                _ = opts.one_to_one_field.rel.to._meta.get_model_module().get_object(**lookup_kwargs) 
     1771#                params = dict([(f.attname, f.get_default()) for f in opts.fields]) 
     1772#                params[opts.pk.attname] = obj_key 
     1773#                self.original_object = opts.get_model_module().Klass(**params) 
     1774#            else: 
     1775#                raise 
     1776#    self.fields = [] 
     1777
     1778#    for f in opts.fields + opts.many_to_many: 
     1779#        if self.follow.get(f.name, False): 
     1780#            self.fields.extend(f.get_manipulator_fields(opts, self, change)) 
     1781
     1782#    # Add fields for related objects. 
     1783#    for f in opts.get_all_related_objects(): 
     1784#        if self.follow.get(f.name, False): 
     1785#            fol = self.follow[f.name] 
     1786#            self.fields.extend(f.get_manipulator_fields(opts, self, change, fol)) 
     1787
     1788#    # Add field for ordering. 
     1789#    if change and opts.get_ordered_objects(): 
     1790#        self.fields.append(formfields.CommaSeparatedIntegerField(field_name="order_")) 
     1791 
     1792#def manipulator_save(opts, klass, add, change, self, new_data): 
     1793#    # TODO: big cleanup when core fields go -> use recursive manipulators. 
     1794#    from django.utils.datastructures import DotExpandedDict 
     1795#    params = {} 
     1796#    for f in opts.fields: 
     1797#        # Fields with auto_now_add should keep their original value in the change stage. 
     1798#        auto_now_add = change and getattr(f, 'auto_now_add', False) 
     1799#        if self.follow.get(f.name, None) and not auto_now_add: 
     1800#            param = f.get_manipulator_new_data(new_data) 
     1801#        else: 
     1802#            if change: 
     1803#                param = getattr(self.original_object, f.attname) 
     1804#            else: 
     1805#                param = f.get_default() 
     1806#        params[f.attname] = param 
     1807
     1808#    if change: 
     1809#        params[opts.pk.attname] = self.obj_key 
     1810
     1811#    # First, save the basic object itself. 
     1812#    new_object = klass(**params) 
     1813#    new_object.save() 
     1814
     1815#    # Now that the object's been saved, save any uploaded files. 
     1816#    for f in opts.fields: 
     1817#        if isinstance(f, FileField): 
     1818#            f.save_file(new_data, new_object, change and self.original_object or None, change, rel=False) 
     1819
     1820#    # Calculate which primary fields have changed. 
     1821#    if change: 
     1822#        self.fields_added, self.fields_changed, self.fields_deleted = [], [], [] 
     1823#        for f in opts.fields: 
     1824#            if not f.primary_key and str(getattr(self.original_object, f.attname)) != str(getattr(new_object, f.attname)): 
     1825#                self.fields_changed.append(f.verbose_name) 
     1826
     1827#    # Save many-to-many objects. Example: Poll.set_sites() 
     1828#    for f in opts.many_to_many: 
     1829#        if self.follow.get(f.name, None): 
     1830#            if not f.rel.edit_inline: 
     1831#                if f.rel.raw_id_admin: 
     1832#                    new_vals = new_data.get(f.name, ()) 
     1833#                else: 
     1834#                    new_vals = new_data.getlist(f.name) 
     1835#                was_changed = getattr(new_object, 'set_%s' % f.name)(new_vals) 
     1836#                if change and was_changed: 
     1837#                    self.fields_changed.append(f.verbose_name) 
     1838
     1839#    expanded_data = DotExpandedDict(dict(new_data)) 
     1840#    # Save many-to-one objects. Example: Add the Choice objects for a Poll. 
     1841#    for related in opts.get_all_related_objects(): 
     1842#        # Create obj_list, which is a DotExpandedDict such as this: 
     1843#        # [('0', {'id': ['940'], 'choice': ['This is the first choice']}), 
     1844#        #  ('1', {'id': ['941'], 'choice': ['This is the second choice']}), 
     1845#        #  ('2', {'id': [''], 'choice': ['']})] 
     1846#        child_follow = self.follow.get(related.name, None) 
     1847
     1848#        if child_follow: 
     1849#            obj_list = expanded_data[related.var_name].items() 
     1850#            obj_list.sort(lambda x, y: cmp(int(x[0]), int(y[0]))) 
     1851#            params = {} 
     1852
     1853#            # For each related item... 
     1854#            for _, rel_new_data in obj_list: 
     1855
     1856#                # Keep track of which core=True fields were provided. 
     1857#                # If all core fields were given, the related object will be saved. 
     1858#                # If none of the core fields were given, the object will be deleted. 
     1859#                # If some, but not all, of the fields were given, the validator would 
     1860#                # have caught that. 
     1861#                all_cores_given, all_cores_blank = True, True 
     1862
     1863#                # Get a reference to the old object. We'll use it to compare the 
     1864#                # old to the new, to see which fields have changed. 
     1865#                old_rel_obj = None 
     1866#                if change: 
     1867#                    if rel_new_data[related.opts.pk.name][0]: 
     1868#                        try: 
     1869#                            old_rel_obj = getattr(self.original_object, 'get_%s' % related.get_method_name_part() )(**{'%s__exact' % related.opts.pk.name: rel_new_data[related.opts.pk.attname][0]}) 
     1870#                        except ObjectDoesNotExist: 
     1871#                            pass 
     1872
     1873#                for f in related.opts.fields: 
     1874#                    if f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True) in (None, ''): 
     1875#                        all_cores_given = False 
     1876#                    elif f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True) not in (None, ''): 
     1877#                        all_cores_blank = False 
     1878#                    # If this field isn't editable, give it the same value it had 
     1879#                    # previously, according to the given ID. If the ID wasn't 
     1880#                    # given, use a default value. FileFields are also a special 
     1881#                    # case, because they'll be dealt with later. 
     1882
     1883#                    if f == related.field: 
     1884#                        param = getattr(new_object, related.field.rel.field_name) 
     1885#                    elif add and isinstance(f, AutoField): 
     1886#                        param = None 
     1887#                    elif change and (isinstance(f, FileField) or not child_follow.get(f.name, None)): 
     1888#                        if old_rel_obj: 
     1889#                            param = getattr(old_rel_obj, f.column) 
     1890#                        else: 
     1891#                            param = f.get_default() 
     1892#                    else: 
     1893#                        param = f.get_manipulator_new_data(rel_new_data, rel=True) 
     1894#                    if param != None: 
     1895#                       params[f.attname] = param 
     1896
     1897#                # Create the related item. 
     1898#                new_rel_obj = related.opts.get_model_module().Klass(**params) 
     1899
     1900#                # If all the core fields were provided (non-empty), save the item. 
     1901#                if all_cores_given: 
     1902#                    new_rel_obj.save() 
     1903
     1904#                    # Save any uploaded files. 
     1905#                    for f in related.opts.fields: 
     1906#                        if child_follow.get(f.name, None): 
     1907#                            if isinstance(f, FileField) and rel_new_data.get(f.name, False): 
     1908#                                f.save_file(rel_new_data, new_rel_obj, change and old_rel_obj or None, old_rel_obj is not None, rel=True) 
     1909
     1910#                    # Calculate whether any fields have changed. 
     1911#                    if change: 
     1912#                        if not old_rel_obj: # This object didn't exist before. 
     1913#                            self.fields_added.append('%s "%s"' % (related.opts.verbose_name, new_rel_obj)) 
     1914#                        else: 
     1915#                            for f in related.opts.fields: 
     1916#                                if not f.primary_key and f != related.field and str(getattr(old_rel_obj, f.attname)) != str(getattr(new_rel_obj, f.attname)): 
     1917#                                    self.fields_changed.append('%s for %s "%s"' % (f.verbose_name, related.opts.verbose_name, new_rel_obj)) 
     1918
     1919#                    # Save many-to-many objects. 
     1920#                    for f in related.opts.many_to_many: 
     1921#                        if child_follow.get(f.name, None) and not f.rel.edit_inline: 
     1922#                            was_changed = getattr(new_rel_obj, 'set_%s' % f.name)(rel_new_data[f.attname]) 
     1923#                            if change and was_changed: 
     1924#                                self.fields_changed.append('%s for %s "%s"' % (f.verbose_name, related.opts.verbose_name, new_rel_obj)) 
     1925
     1926#                # If, in the change stage, all of the core fields were blank and 
     1927#                # the primary key (ID) was provided, delete the item. 
     1928#                if change and all_cores_blank and old_rel_obj: 
     1929#                    new_rel_obj.delete() 
     1930#                    self.fields_deleted.append('%s "%s"' % (related.opts.verbose_name, old_rel_obj)) 
     1931
     1932#    # Save the order, if applicable. 
     1933#    if change and opts.get_ordered_objects(): 
     1934#        order = new_data['order_'] and map(int, new_data['order_'].split(',')) or [] 
     1935#        for rel_opts in opts.get_ordered_objects(): 
     1936#            getattr(new_object, 'set_%s_order' % rel_opts.object_name.lower())(order) 
     1937#    return new_object 
    17731938 
    17741939