Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Added templates for 'funny' widgets here: django/conf/admin_templates…

…/widget

Added a follow argument to manipulators. This allows you to exclude/include fields and related objects ( recursively), defaulting to current behaviour, meaning that forms can modify a subset of fields. This should fix #445. Fixed update generic view to use this (will change others soon).  Merged to trunk r772. 



git-svn-id: http://code.djangoproject.com/svn/django/branches/new-admin@773 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 555502e208656b2a6cb8aa4cf11acdf5a0374285 1 parent 1c9cf48
Robert Wittams authored October 04, 2005
4  django/conf/admin_templates/widget/date_time.html
... ...
@@ -0,0 +1,4 @@
  1
+<p class="datetime"> 
  2
+   Date: {{ bound_field.form_fields.0 }}<br />
  3
+   Time: {{ bound_field.form_fields.1 }}
  4
+</p>
1  django/conf/admin_templates/widget/default.html
... ...
@@ -0,0 +1 @@
  1
+{% output_all bound_field.form_fields %}
4  django/conf/admin_templates/widget/file.html
... ...
@@ -0,0 +1,4 @@
  1
+{% if bound_field.original_value %}
  2
+Currently: <a href="{{ bound_field.original_url }}" > {{ bound_field.original_value }} </a><br />
  3
+Change: {% output_all bound_field.form_fields %}
  4
+{% else %} {% output_all bound_field.form_fields %} {% endif %}
7  django/conf/admin_templates/widget/foreign.html
... ...
@@ -0,0 +1,7 @@
  1
+{% output_all bound_field.form_fields %}
  2
+{% if bound_field.raw_id_admin %}
  3
+            <a href="../../../{{ bound_field.field.rel.to.app_label }}/{{ bound_field.field.rel.to.module_name }}/" class="related-lookup" id="lookup_{{bound_field.element_id}}" onclick="return showRelatedObjectLookupPopup(this);"> <img src="{% admin_media_prefix %}img/admin/selector-search.gif" width="16" height="16" alt="Lookup"></a>
  4
+{% else %}
  5
+{% if bound_field.needs_add_label %}
  6
+            <a href="../../../{{ bound_field.field.rel.to.app_label }}/{{ bound_field.field.rel.to.module_name }}/add/" class="add-another" id="add_{{ bound_field.element_id}}" onclick="return showAddAnotherPopup(this);"> <img src="{% admin_media_prefix %}img/admin/icon_addlink.gif" width="10" height="10" alt="Add Another"/></a>
  7
+{% endif %} {% endif %}
1  django/conf/admin_templates/widget/many_to_many.html
... ...
@@ -0,0 +1 @@
  1
+{% include "widget/foreign" %}
320  django/core/meta/__init__.py
@@ -147,15 +147,16 @@ class BadKeywordArguments(Exception):
147 147
     pass
148 148
 
149 149
 
150  
-class InlineRelatedObject(object):
  150
+class RelatedObject(object):
151 151
     def __init__(self,parent_opts, opts, field):
152 152
         self.parent_opts = parent_opts
153 153
         self.opts = opts
154 154
         self.field = field
  155
+        self.edit_inline = field.rel.edit_inline
155 156
         self.name = opts.module_name
  157
+        self.var_name = opts.object_name.lower()
156 158
 
157 159
     def flatten_data(self,obj = None):
158  
-        var_name = self.opts.object_name.lower()
159 160
         new_data = {}
160 161
         rel_instances = self.get_list(obj)
161 162
 
@@ -165,7 +166,7 @@ def flatten_data(self,obj = None):
165 166
                 field_data = f.flatten_data(rel_instance)
166 167
                 #if hasattr(f, 'editable') and f.editable and f != self.field:
167 168
                 for name, value in field_data.items():
168  
-                    instance_data['%s.%d.%s' % (var_name, i, name)] = value
  169
+                    instance_data['%s.%d.%s' % (self.var_name, i, name)] = value
169 170
             new_data.update(instance_data)             
170 171
     
171 172
         return new_data        
@@ -204,12 +205,47 @@ def editable_fields(self, wrapping_func = lambda x: x):
204 205
         This can be useful to add extra attributes for use in templates."""
205 206
         
206 207
         return [wrapping_func(f) for f in self.opts.fields + self.opts.many_to_many if f.editable and f != self.field ]
  208
+      
  209
+    def get_follow(self, override=None):
  210
+        if override:
  211
+            over = override.copy()
  212
+        elif self.edit_inline:
  213
+            over = {}
  214
+        else:
  215
+            return None
207 216
         
  217
+        over[self.field.name] = False
  218
+        return self.opts.get_follow(over)
  219
+    
  220
+    
208 221
     def __repr__(self):
209  
-        return "<InlineRelatedObject: %s related to %s>" % ( self.name, self.field.name)      
  222
+        return "<RelatedObject: %s related to %s>" % ( self.name, self.field.name)      
  223
+
  224
+    def get_manipulator_fields(self, opts, manipulator, change, follow):
  225
+        if change:
  226
+            meth_name = 'get_%s_count' % self.parent_opts.get_rel_object_method_name(self.opts, self.field)
  227
+            count = getattr(manipulator.original_object, meth_name)()
  228
+            count += self.field.rel.num_extra_on_change
  229
+            if self.field.rel.min_num_in_admin:
  230
+                count = max(count, self.field.rel.min_num_in_admin)
  231
+            if self.field.rel.max_num_in_admin:
  232
+                count = min(count, self.field.rel.max_num_in_admin)
  233
+        else:
  234
+            count = self.field.rel.num_in_admin
210 235
 
  236
+        fields = []
211 237
         
212 238
 
  239
+        for i in range(count):
  240
+            for f in self.opts.fields + self.opts.many_to_many:
  241
+                    if follow.get(f.name, False):
  242
+                        prefix = '%s.%d.' % (self.var_name, i)
  243
+                        fields.extend(
  244
+                             f.get_manipulator_fields(self.opts, manipulator, change, name_prefix=prefix, rel=True))
  245
+
  246
+        return fields
  247
+
  248
+
213 249
 class Options:
214 250
     def __init__(self, module_name='', verbose_name='', verbose_name_plural='', db_table='',
215 251
         fields=None, ordering=None, unique_together=None, admin=None, has_related_links=False,
@@ -382,10 +418,34 @@ def get_inline_related_objects(self):
382 418
         return [(a, b) for a, b in self.get_all_related_objects() if b.rel.edit_inline]
383 419
 
384 420
     def get_inline_related_objects_wrapped(self):
385  
-        return [InlineRelatedObject(self, opts, field) for opts, field in self.get_all_related_objects() if field.rel.edit_inline]
  421
+        return [RelatedObject(self, opts, field) for opts, field in self.get_all_related_objects() if field.rel.edit_inline]
  422
+
  423
+    def get_all_related_objects_wrapped(self):
  424
+        return [RelatedObject(self, opts, field) for opts, field in self.get_all_related_objects()]
  425
+
  426
+    def get_data_holders(self, follow=None):
  427
+        return [f for f in self.fields + self.many_to_many + self.get_all_related_objects_wrapped() if follow.get(f.name, None) ]
  428
+
  429
+    def get_follow(self, override=None):
  430
+        follow = {}
  431
+        
  432
+        for f in self.fields + self.many_to_many:
  433
+            if override and override.has_key(f.name):
  434
+                fol = override[f.name]
  435
+            else:
  436
+                fol = f.editable
  437
+            if fol:
  438
+                follow[f.name] = fol
  439
+ 
  440
+        for f in self.get_all_related_objects_wrapped():
  441
+            if override and override.has_key(f.name):
  442
+               fol = f.get_follow(override[f.name])
  443
+            else:
  444
+               fol = f.get_follow(None)
  445
+            if fol:
  446
+                follow[f.name] = fol 
386 447
 
387  
-    def get_data_holders(self):
388  
-        return self.fields + self.many_to_many + self.get_inline_related_objects_wrapped()
  448
+        return follow
389 449
 
390 450
     def get_all_related_many_to_many_objects(self):
391 451
         module_list = get_installed_model_modules()
@@ -1488,7 +1548,9 @@ def get_manipulator(opts, klass, extra_methods, add=False, change=False):
1488 1548
         setattr(man, k, v)
1489 1549
     return man
1490 1550
 
1491  
-def manipulator_init(opts, add, change, self, obj_key=None):
  1551
+def manipulator_init(opts, add, change, self, obj_key=None, follow=None):
  1552
+    self.follow = opts.get_follow(follow)   
  1553
+    
1492 1554
     if change:
1493 1555
         assert obj_key is not None, "ChangeManipulator.__init__() must be passed obj_key parameter."
1494 1556
         self.obj_key = obj_key
@@ -1512,25 +1574,32 @@ def manipulator_init(opts, add, change, self, obj_key=None):
1512 1574
             else:
1513 1575
                 raise
1514 1576
     self.fields = []
  1577
+
1515 1578
     for f in opts.fields + opts.many_to_many:
1516  
-        if f.editable and not (f.primary_key and change) and (not f.rel or not f.rel.edit_inline):
  1579
+        if self.follow.get(f.name, False):   
  1580
+        # if f.editable and not (f.primary_key and change) and (not f.rel or not f.rel.edit_inline):
1517 1581
             self.fields.extend(f.get_manipulator_fields(opts, self, change))
1518 1582
 
1519 1583
     # Add fields for related objects.
1520  
-    for obj in opts.get_inline_related_objects_wrapped():
1521  
-        if change:
1522  
-            count = getattr(self.original_object, 'get_%s_count' % opts.get_rel_object_method_name(obj.opts, obj.field))()
1523  
-            count += obj.field.rel.num_extra_on_change
1524  
-            if obj.field.rel.min_num_in_admin:
1525  
-                count = max(count, obj.field.rel.min_num_in_admin)
1526  
-            if obj.field.rel.max_num_in_admin:
1527  
-                count = min(count, obj.field.rel.max_num_in_admin)
1528  
-        else:
1529  
-            count = obj.field.rel.num_in_admin
1530  
-        for f in obj.opts.fields + obj.opts.many_to_many:
1531  
-            if f.editable and f != obj.field :
1532  
-                for i in range(count):
1533  
-                    self.fields.extend(f.get_manipulator_fields(obj.opts, self, change, name_prefix='%s.%d.' % (obj.opts.object_name.lower(), i), rel=True))
  1584
+    for f in opts.get_all_related_objects_wrapped():
  1585
+        if self.follow.get(f.name, False):
  1586
+            fol = self.follow[f.name]
  1587
+            self.fields.extend(f.get_manipulator_fields(opts, self, change, fol))
  1588
+
  1589
+   # for obj in opts.get_inline_related_objects_wrapped():
  1590
+   #     if change:
  1591
+   #         count = getattr(self.original_object, 'get_%s_count' % opts.get_rel_object_method_name(obj.opts, obj.field))()
  1592
+   #         count += obj.field.rel.num_extra_on_change
  1593
+   #         if obj.field.rel.min_num_in_admin:
  1594
+   #             count = max(count, obj.field.rel.min_num_in_admin)
  1595
+   #         if obj.field.rel.max_num_in_admin:
  1596
+   #             count = min(count, obj.field.rel.max_num_in_admin)
  1597
+   #     else:
  1598
+   #         count = obj.field.rel.num_in_admin
  1599
+   #     for f in obj.opts.fields + obj.opts.many_to_many:
  1600
+   #         if f.editable and f != obj.field :
  1601
+   #             for i in range(count):
  1602
+   #                self.fields.extend(f.get_manipulator_fields(obj.opts, self, change, name_prefix='%s.%d.' % (obj.opts.object_name.lower(), i), rel=True))
1534 1603
 
1535 1604
     # Add field for ordering.
1536 1605
     if change and opts.get_ordered_objects():
@@ -1540,12 +1609,19 @@ def manipulator_save(opts, klass, add, change, self, new_data):
1540 1609
     from django.utils.datastructures import DotExpandedDict
1541 1610
     params = {}
1542 1611
     for f in opts.fields:
  1612
+        auto_now_add = change and getattr(f, 'auto_now_add', False)
  1613
+        if self.follow.get(f.name, None) and not auto_now_add:
  1614
+            param = f.get_manipulator_new_data(new_data)
  1615
+        else:
  1616
+            param = getattr(self.original_object, f.column)
  1617
+        params[f.column] = param    
  1618
+    
1543 1619
         # Fields with auto_now_add are another special case; they should keep
1544 1620
         # their original value in the change stage.
1545  
-        if change and getattr(f, 'auto_now_add', False):
1546  
-            params[f.column] = getattr(self.original_object, f.name)
1547  
-        else:
1548  
-            params[f.column] = f.get_manipulator_new_data(new_data)
  1621
+        #if change and getattr(f, 'auto_now_add', False):
  1622
+        #    params[f.column] = getattr(self.original_object, f.name)
  1623
+        #else:
  1624
+        #    params[f.column] = f.get_manipulator_new_data(new_data)
1549 1625
 
1550 1626
     if change:
1551 1627
         params[opts.pk.column] = self.obj_key
@@ -1568,101 +1644,117 @@ def manipulator_save(opts, klass, add, change, self, new_data):
1568 1644
 
1569 1645
     # Save many-to-many objects. Example: Poll.set_sites()
1570 1646
     for f in opts.many_to_many:
1571  
-        if not f.rel.edit_inline:
1572  
-            was_changed = getattr(new_object, 'set_%s' % f.name)(new_data.getlist(f.name))
1573  
-            if change and was_changed:
1574  
-                self.fields_changed.append(f.verbose_name)
  1647
+        if self.follow.get(f.name, None):
  1648
+            if not f.rel.edit_inline:
  1649
+                was_changed = getattr(new_object, 'set_%s' % f.name)(new_data.getlist(f.name))
  1650
+                if change and was_changed:
  1651
+                    self.fields_changed.append(f.verbose_name)
1575 1652
 
  1653
+    expanded_data = DotExpandedDict(new_data.data)
1576 1654
     # Save many-to-one objects. Example: Add the Choice objects for a Poll.
1577  
-    for rel_opts, rel_field in opts.get_inline_related_objects():
  1655
+    for related in opts.get_all_related_objects_wrapped():
1578 1656
         # Create obj_list, which is a DotExpandedDict such as this:
1579 1657
         # [('0', {'id': ['940'], 'choice': ['This is the first choice']}),
1580 1658
         #  ('1', {'id': ['941'], 'choice': ['This is the second choice']}),
1581 1659
         #  ('2', {'id': [''], 'choice': ['']})]
1582  
-        obj_list = DotExpandedDict(new_data.data)[rel_opts.object_name.lower()].items()
1583  
-        obj_list.sort(lambda x, y: cmp(int(x[0]), int(y[0])))
1584  
-        params = {}
1585  
-
1586  
-        # For each related item...
1587  
-        for _, rel_new_data in obj_list:
1588  
-
1589  
-            # Keep track of which core=True fields were provided.
1590  
-            # If all core fields were given, the related object will be saved.
1591  
-            # If none of the core fields were given, the object will be deleted.
1592  
-            # If some, but not all, of the fields were given, the validator would
1593  
-            # have caught that.
1594  
-            all_cores_given, all_cores_blank = True, True
1595  
-
1596  
-            # Get a reference to the old object. We'll use it to compare the
1597  
-            # old to the new, to see which fields have changed.
1598  
-            if change:
  1660
+        child_follow = self.follow.get(related.name, None)
  1661
+                
  1662
+        if child_follow:
  1663
+            obj_list = expanded_data[related.var_name].items()
  1664
+            obj_list.sort(lambda x, y: cmp(int(x[0]), int(y[0])))
  1665
+            params = {}
  1666
+
  1667
+
  1668
+            # For each related item...
  1669
+            for _, rel_new_data in obj_list:
  1670
+
  1671
+                # Keep track of which core=True fields were provided.
  1672
+                # If all core fields were given, the related object will be saved.
  1673
+                # If none of the core fields were given, the object will be deleted.
  1674
+                # If some, but not all, of the fields were given, the validator would
  1675
+                # have caught that.
  1676
+                all_cores_given, all_cores_blank = True, True
  1677
+
  1678
+                # Get a reference to the old object. We'll use it to compare the
  1679
+                # old to the new, to see which fields have changed.
1599 1680
                 old_rel_obj = None
1600  
-                if rel_new_data[rel_opts.pk.name][0]:
1601  
-                    try:
1602  
-                        old_rel_obj = getattr(self.original_object, 'get_%s' % opts.get_rel_object_method_name(rel_opts, rel_field))(**{'%s__exact' % rel_opts.pk.name: rel_new_data[rel_opts.pk.name][0]})
1603  
-                    except ObjectDoesNotExist:
1604  
-                        pass
1605  
-
1606  
-            for f in rel_opts.fields:
1607  
-                if f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True) in (None, ''):
1608  
-                    all_cores_given = False
1609  
-                elif f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True) not in (None, ''):
1610  
-                    all_cores_blank = False
1611  
-                # If this field isn't editable, give it the same value it had
1612  
-                # previously, according to the given ID. If the ID wasn't
1613  
-                # given, use a default value. FileFields are also a special
1614  
-                # case, because they'll be dealt with later.
1615  
-                if change and (isinstance(f, FileField) or not f.editable):
1616  
-                    if rel_new_data.get(rel_opts.pk.name, False) and rel_new_data[rel_opts.pk.name][0]:
1617  
-                        params[f.column] = getattr(old_rel_obj, f.column)
1618  
-                    else:
1619  
-                        params[f.column] = f.get_default()
1620  
-                elif f == rel_field:
1621  
-                    params[f.column] = getattr(new_object, rel_field.rel.field_name)
1622  
-                elif add and isinstance(f, AutoField):
1623  
-                    params[f.column] = None
1624  
-                else:
1625  
-                    params[f.column] = f.get_manipulator_new_data(rel_new_data, rel=True)
1626  
-                # Related links are a special case, because we have to
1627  
-                # manually set the "content_type_id" and "object_id" fields.
1628  
-                if opts.has_related_links and rel_opts.module_name == 'relatedlinks':
1629  
-                    contenttypes_mod = get_module('core', 'contenttypes')
1630  
-                    params['content_type_id'] = contenttypes_mod.get_object(package__label__exact=opts.app_label, python_module_name__exact=opts.module_name).id
1631  
-                    params['object_id'] = new_object.id
1632  
-
1633  
-            # Create the related item.
1634  
-            new_rel_obj = rel_opts.get_model_module().Klass(**params)
1635  
-
1636  
-            # If all the core fields were provided (non-empty), save the item.
1637  
-            if all_cores_given:
1638  
-                new_rel_obj.save()
1639  
-
1640  
-                # Save any uploaded files.
1641  
-                for f in rel_opts.fields:
1642  
-                    if isinstance(f, FileField) and rel_new_data.get(f.name, False):
1643  
-                        f.save_file(rel_new_data, new_rel_obj, change and old_rel_obj or None, change, rel=True)
1644  
-
1645  
-                # Calculate whether any fields have changed.
1646 1681
                 if change:
1647  
-                    if not old_rel_obj: # This object didn't exist before.
1648  
-                        self.fields_added.append('%s "%r"' % (rel_opts.verbose_name, new_rel_obj))
  1682
+                    if rel_new_data[related.opts.pk.name][0]:
  1683
+                        try:
  1684
+                            old_rel_obj = getattr(self.original_object, 'get_%s' % opts.get_rel_object_method_name(related.opts, related.field))(**{'%s__exact' % related.opts.pk.name: rel_new_data[related.opts.pk.name][0]})
  1685
+                        except ObjectDoesNotExist:
  1686
+                            pass
  1687
+
  1688
+                for f in related.opts.fields:
  1689
+                    if f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True) in (None, ''):
  1690
+                        all_cores_given = False
  1691
+                    elif f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True) not in (None, ''):
  1692
+                        all_cores_blank = False
  1693
+                    # If this field isn't editable, give it the same value it had
  1694
+                    # previously, according to the given ID. If the ID wasn't
  1695
+                    # given, use a default value. FileFields are also a special
  1696
+                    # case, because they'll be dealt with later.
  1697
+                    
  1698
+                    if f == related.field:
  1699
+                        param = getattr(new_object, related.field.rel.field_name)
  1700
+                    elif add and isinstance(f, AutoField):
  1701
+                        param = None
  1702
+                    elif change and (isinstance(f, FileField) or not child_follow.get(f.name, None)):
  1703
+                        if old_rel_obj:
  1704
+                            param = getattr(old_rel_obj, f.column)
  1705
+                        else:
  1706
+                            param = f.get_default()
1649 1707
                     else:
1650  
-                        for f in rel_opts.fields:
1651  
-                            if not f.primary_key and f != rel_field and str(getattr(old_rel_obj, f.column)) != str(getattr(new_rel_obj, f.column)):
1652  
-                                self.fields_changed.append('%s for %s "%r"' % (f.verbose_name, rel_opts.verbose_name, new_rel_obj))
1653  
-
1654  
-                # Save many-to-many objects.
1655  
-                for f in rel_opts.many_to_many:
1656  
-                    if not f.rel.edit_inline:
1657  
-                        was_changed = getattr(new_rel_obj, 'set_%s' % f.name)(rel_new_data[f.name])
1658  
-                        if change and was_changed:
1659  
-                            self.fields_changed.append('%s for %s "%s"' % (f.verbose_name, rel_opts.verbose_name, new_rel_obj))
1660  
-
1661  
-            # If, in the change stage, all of the core fields were blank and
1662  
-            # the primary key (ID) was provided, delete the item.
1663  
-            if change and all_cores_blank and rel_new_data.has_key(rel_opts.pk.name) and rel_new_data[rel_opts.pk.name][0]:
1664  
-                new_rel_obj.delete()
1665  
-                self.fields_deleted.append('%s "%r"' % (rel_opts.verbose_name, old_rel_obj))
  1708
+                        param = f.get_manipulator_new_data(rel_new_data, rel=True)
  1709
+                    
  1710
+                    if param:
  1711
+                       params[f.column] = param
  1712
+                    
  1713
+
  1714
+                    # Related links are a special case, because we have to
  1715
+                    # manually set the "content_type_id" and "object_id" fields.
  1716
+                    if opts.has_related_links and related.opts.module_name == 'relatedlinks':
  1717
+                        contenttypes_mod = get_module('core', 'contenttypes')
  1718
+                        params['content_type_id'] = contenttypes_mod.get_object(package__label__exact=opts.app_label, python_module_name__exact=opts.module_name).id
  1719
+                        params['object_id'] = new_object.id
  1720
+
  1721
+                # Create the related item.
  1722
+                new_rel_obj = related.opts.get_model_module().Klass(**params)
  1723
+    
  1724
+                
  1725
+
  1726
+                # If all the core fields were provided (non-empty), save the item.
  1727
+                if all_cores_given:
  1728
+                    new_rel_obj.save()
  1729
+
  1730
+                    # Save any uploaded files.
  1731
+                    for f in related.opts.fields:
  1732
+                        if child_follow.get(f.name, None):
  1733
+                            if isinstance(f, FileField) and rel_new_data.get(f.name, False):
  1734
+                                f.save_file(rel_new_data, new_rel_obj, change and old_rel_obj or None, change, rel=True)
  1735
+
  1736
+                    # Calculate whether any fields have changed.
  1737
+                    if change:
  1738
+                        if not old_rel_obj: # This object didn't exist before.
  1739
+                            self.fields_added.append('%s "%r"' % (related.opts.verbose_name, new_rel_obj))
  1740
+                        else:
  1741
+                            for f in related.opts.fields:
  1742
+                                if not f.primary_key and f != related.field and str(getattr(old_rel_obj, f.column)) != str(getattr(new_rel_obj, f.column)):
  1743
+                                    self.fields_changed.append('%s for %s "%r"' % (f.verbose_name, rel_opts.verbose_name, new_rel_obj))
  1744
+
  1745
+                    # Save many-to-many objects.
  1746
+                    for f in related.opts.many_to_many:
  1747
+                        if child_follow.get(f.name, None) and not f.rel.edit_inline:
  1748
+                            was_changed = getattr(new_rel_obj, 'set_%s' % f.name)(rel_new_data[f.name])
  1749
+                            if change and was_changed:
  1750
+                                self.fields_changed.append('%s for %s "%s"' % (f.verbose_name, rel_opts.verbose_name, new_rel_obj))
  1751
+
  1752
+                # If, in the change stage, all of the core fields were blank and
  1753
+                # the primary key (ID) was provided, delete the item.
  1754
+                if change and all_cores_blank and old_rel_obj:
  1755
+                    new_rel_obj.delete()
  1756
+                    self.fields_deleted.append('%s "%r"' % (related.opts.verbose_name, old_rel_obj))
  1757
+
1666 1758
 
1667 1759
     # Save the order, if applicable.
1668 1760
     if change and opts.get_ordered_objects():
@@ -1677,7 +1769,7 @@ def manipulator_get_inline_related_objects_wrapped(opts, klass, add, change, sel
1677 1769
 def manipulator_flatten_data(opts, klass, add, change, self):
1678 1770
      new_data = {}
1679 1771
      obj = change and self.original_object or None
1680  
-     for f in opts.get_data_holders():
  1772
+     for f in opts.get_data_holders(self.follow):
1681 1773
             new_data.update(f.flatten_data(obj))
1682 1774
      return new_data
1683 1775
 
13  django/core/meta/fields.py
@@ -639,11 +639,14 @@ def get_manipulator_field_objs(self):
639 639
         return [formfields.IntegerField]
640 640
 
641 641
     def get_db_prep_save(self,value):
642  
-        if value == '':
643  
-            return None
644  
-        else:
645  
-            return int(value)
646  
-    
  642
+       try:
  643
+            if value == '' or None:
  644
+                return None
  645
+            else:
  646
+                return int(value)
  647
+       except Exception, e: 
  648
+            print "name: %s  val: %s" % (self.name, value)         
  649
+
647 650
     def flatten_data(self, obj = None):
648 651
         if not obj: 
649 652
             # In required many-to-one fields with only one available choice,
8  django/views/generic/create_update.py
@@ -68,7 +68,7 @@ def create_object(request, app_label, module_name, template_name=None,
68 68
 def update_object(request, app_label, module_name, object_id=None, slug=None, 
69 69
                   slug_field=None, template_name=None, template_loader=template_loader,
70 70
                   extra_lookup_kwargs={}, extra_context={}, post_save_redirect=None, 
71  
-                  login_required=False):
  71
+                  login_required=False, follow=None):
72 72
     """
73 73
     Generic object-update function.
74 74
 
@@ -98,13 +98,13 @@ def update_object(request, app_label, module_name, object_id=None, slug=None,
98 98
     except ObjectDoesNotExist:
99 99
         raise Http404("%s.%s does not exist for %s" % (app_label, module_name, lookup_kwargs))
100 100
     
101  
-    manipulator = mod.ChangeManipulator(object.id)
  101
+    manipulator = mod.ChangeManipulator(object.id, follow=follow)
102 102
     
103 103
     if request.POST:
104 104
         new_data = request.POST.copy()
105 105
         errors = manipulator.get_validation_errors(new_data)
  106
+        manipulator.do_html2python(new_data)
106 107
         if not errors:
107  
-            manipulator.do_html2python(new_data)
108 108
             manipulator.save(new_data)
109 109
             
110 110
             if not request.user.is_anonymous():
@@ -120,7 +120,7 @@ def update_object(request, app_label, module_name, object_id=None, slug=None,
120 120
     else:
121 121
         errors = {}
122 122
         # This makes sure the form acurate represents the fields of the place.
123  
-        new_data = object.__dict__
  123
+        new_data = manipulator.flatten_data()
124 124
     
125 125
     form = formfields.FormWrapper(manipulator, new_data, errors)
126 126
     if not template_name:
2  docs/outputting_pdf.txt
@@ -7,7 +7,7 @@ This is made possible by the excellent, open-source ReportLab_ Python PDF
7 7
 library.
8 8
 
9 9
 The advantage of generating PDF files dynamically is that you can create
10  
-customzed PDFs for different purposes -- say, for different users or different
  10
+customized PDFs for different purposes -- say, for different users or different
11 11
 pieces of content.
12 12
 
13 13
 For example, Django was used at kusports.com to generate customized,
2  docs/templates_python.txt
@@ -267,7 +267,7 @@ every template automatic access to the current time, use something like this::
267 267
 
268 268
     from django.core.template import Context
269 269
     import datetime
270  
-    class TimeContext(template.Context):
  270
+    class TimeContext(Context):
271 271
         def __init__(self, *args, **kwargs):
272 272
             Context.__init__(self, *args, **kwargs)
273 273
             self['current_time'] = datetime.datetime.now()

0 notes on commit 555502e

Please sign in to comment.
Something went wrong with that request. Please try again.