Author: adrian
Date: 2007-01-25 12:05:10 -0600 (Thu, 25 Jan 2007)
New Revision: 4430

Modified:
   
django/branches/newforms-admin/django/contrib/admin/media/js/admin/RelatedObjectLookups.js
   django/branches/newforms-admin/django/contrib/admin/options.py
   django/branches/newforms-admin/django/contrib/admin/widgets.py
   django/branches/newforms-admin/django/contrib/comments/models.py
   django/branches/newforms-admin/django/db/models/fields/generic.py
   django/branches/newforms-admin/django/db/models/fields/related.py
   django/branches/newforms-admin/django/db/models/manipulators.py
Log:
newforms-admin: Backwards-incompatible change: Refactored raw_id_admin. It is 
no longer a valid attribute for fields. Instead, specify 'raw_id_fields', a 
list of field names, in the 'class Admin'. Also removed raw_id functionality 
for ManyToManyFields, as it was hackish.

Modified: 
django/branches/newforms-admin/django/contrib/admin/media/js/admin/RelatedObjectLookups.js
===================================================================
--- 
django/branches/newforms-admin/django/contrib/admin/media/js/admin/RelatedObjectLookups.js
  2007-01-25 13:47:55 UTC (rev 4429)
+++ 
django/branches/newforms-admin/django/contrib/admin/media/js/admin/RelatedObjectLookups.js
  2007-01-25 18:05:10 UTC (rev 4430)
@@ -1,4 +1,4 @@
-// Handles related-objects functionality: lookup link for raw_id_admin=True
+// Handles related-objects functionality: lookup link for raw_id_fields
 // and Add Another links.
 
 function showRelatedObjectLookupPopup(triggeringLink) {

Modified: django/branches/newforms-admin/django/contrib/admin/options.py
===================================================================
--- django/branches/newforms-admin/django/contrib/admin/options.py      
2007-01-25 13:47:55 UTC (rev 4429)
+++ django/branches/newforms-admin/django/contrib/admin/options.py      
2007-01-25 18:05:10 UTC (rev 4430)
@@ -108,6 +108,7 @@
     ordering = None
     js = None
     fields = None
+    raw_id_fields = ()
 
     def __init__(self, model):
         self.model = model
@@ -224,12 +225,16 @@
             return db_field.formfield(**kwargs)
 
         # For ForeignKey or ManyToManyFields, use a special widget.
-        if db_field.rel and isinstance(db_field.rel, (models.ManyToOneRel, 
models.ManyToManyRel)):
-            # Wrap the widget's render() method with a method that adds
-            # extra HTML to the end of the rendered output.
-            formfield = db_field.formfield(**kwargs)
-            formfield.widget.render = 
widgets.RelatedFieldWidgetWrapper(formfield.widget.render, db_field.rel)
-            return formfield
+        if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
+            if isinstance(db_field, models.ForeignKey) and db_field.name in 
self.raw_id_fields:
+                kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel)
+                return db_field.formfield(**kwargs)
+            else:
+                # Wrap the widget's render() method with a method that adds
+                # extra HTML to the end of the rendered output.
+                formfield = db_field.formfield(**kwargs)
+                formfield.widget.render = 
widgets.RelatedFieldWidgetWrapper(formfield.widget.render, db_field.rel)
+                return formfield
 
         # For any other type of field, just call its formfield() method.
         return db_field.formfield(**kwargs)

Modified: django/branches/newforms-admin/django/contrib/admin/widgets.py
===================================================================
--- django/branches/newforms-admin/django/contrib/admin/widgets.py      
2007-01-25 13:47:55 UTC (rev 4429)
+++ django/branches/newforms-admin/django/contrib/admin/widgets.py      
2007-01-25 18:05:10 UTC (rev 4430)
@@ -3,6 +3,8 @@
 """
 
 from django import newforms as forms
+from django.newforms.util import smart_unicode
+from django.utils.text import capfirst
 
 class FilteredSelectMultiple(forms.SelectMultiple):
     """
@@ -41,6 +43,33 @@
         return u'<p class="datetime">%s %s<br />%s %s</p>' % \
             (_('Date:'), rendered_widgets[0], _('Time:'), rendered_widgets[1])
 
+class ForeignKeyRawIdWidget(forms.TextInput):
+    """
+    A Widget for displaying ForeignKeys in the "raw_id" interface rather than
+    in a <select> box.
+    """
+    def __init__(self, rel, attrs=None):
+        self.rel = rel
+        super(ForeignKeyRawIdWidget, self).__init__(attrs)
+
+    def render(self, name, value, attrs=None):
+        from django.conf import settings
+        related_url = '../../../%s/%s/' % (self.rel.to._meta.app_label, 
self.rel.to._meta.object_name.lower())
+        if self.rel.limit_choices_to:
+            url = '?' + '&amp;'.join(['%s=%s' % (k, v) for k, v in 
self.rel.limit_choices_to.items()])
+        else:
+            url = ''
+        attrs['class'] = 'vRawIdAdminField' # The JavaScript looks for this 
hook.
+        output = [super(ForeignKeyRawIdWidget, self).render(name, value, 
attrs)]
+        # TODO: "id_" is hard-coded here. This should instead use the correct
+        # API to determine the ID dynamically.
+        output.append('<a href="%s%s" class="related-lookup" id="lookup_id_%s" 
onclick="return showRelatedObjectLookupPopup(this);"> ' % \
+            (related_url, url, name))
+        output.append('<img src="%simg/admin/selector-search.gif" width="16" 
height="16" alt="Lookup"></a>' % settings.ADMIN_MEDIA_PREFIX)
+        return u''.join(output)
+        #if self.change: # TODO
+            #output.append('&nbsp;<strong>TODO</strong>')
+
 class RelatedFieldWidgetWrapper(object):
     """
     This class is a wrapper whose __call__() method mimics the interface of a
@@ -54,21 +83,9 @@
         rel_to = self.rel.to
         related_url = '../../../%s/%s/' % (rel_to._meta.app_label, 
rel_to._meta.object_name.lower())
         output = [self.render_func(name, value, *args, **kwargs)]
-        if self.rel.raw_id_admin:
-            if self.rel.limit_choices_to:
-                url = '?' + '&amp;'.join(['%s=%s' % (k, v) for k, v in 
self.rel.limit_choices_to.items()])
-            else:
-                url = ''
+        if rel_to._meta.admin: # If the related object has an admin interface:
             # TODO: "id_" is hard-coded here. This should instead use the 
correct
             # API to determine the ID dynamically.
-            output.append('<a href="%s%s" class="related-lookup" 
id="lookup_id_%s" onclick="return showRelatedObjectLookupPopup(this);"> ' % \
-                (related_url, url, name))
-            output.append('<img src="%simg/admin/selector-search.gif" 
width="16" height="16" alt="Lookup"></a>' % settings.ADMIN_MEDIA_PREFIX)
-            #if self.change: # TODO
-                #output.append('&nbsp;<strong>TODO</strong>')
-        elif rel_to._meta.admin: # If the related object has an admin 
interface:
-            # TODO: "id_" is hard-coded here. This should instead use the 
correct
-            # API to determine the ID dynamically.
             output.append(u'<a href="%sadd/" class="add-another" 
id="add_id_%s" onclick="return showAddAnotherPopup(this);"> ' % \
                 (related_url, name))
             output.append(u'<img src="%simg/admin/icon_addlink.gif" width="10" 
height="10" alt="Add Another"/></a>' % settings.ADMIN_MEDIA_PREFIX)

Modified: django/branches/newforms-admin/django/contrib/comments/models.py
===================================================================
--- django/branches/newforms-admin/django/contrib/comments/models.py    
2007-01-25 13:47:55 UTC (rev 4429)
+++ django/branches/newforms-admin/django/contrib/comments/models.py    
2007-01-25 18:05:10 UTC (rev 4430)
@@ -62,7 +62,7 @@
         return False
 
 class Comment(models.Model):
-    user = models.ForeignKey(User, raw_id_admin=True)
+    user = models.ForeignKey(User)
     content_type = models.ForeignKey(ContentType)
     object_id = models.IntegerField(_('object ID'))
     headline = models.CharField(_('headline'), maxlength=255, blank=True)
@@ -101,6 +101,7 @@
         list_filter = ('submit_date',)
         date_hierarchy = 'submit_date'
         search_fields = ('comment', 'user__username')
+        raw_id_fields = ('user',)
 
     def __repr__(self):
         return "%s: %s..." % (self.user.username, self.comment[:100])

Modified: django/branches/newforms-admin/django/db/models/fields/generic.py
===================================================================
--- django/branches/newforms-admin/django/db/models/fields/generic.py   
2007-01-25 13:47:55 UTC (rev 4429)
+++ django/branches/newforms-admin/django/db/models/fields/generic.py   
2007-01-25 18:05:10 UTC (rev 4430)
@@ -16,18 +16,18 @@
     Provides a generic relation to any object through content-type/object-id
     fields.
     """
-    
+
     def __init__(self, ct_field="content_type", fk_field="object_id"):
         self.ct_field = ct_field
         self.fk_field = fk_field
-        
+
     def contribute_to_class(self, cls, name):
-        # Make sure the fields exist (these raise FieldDoesNotExist, 
+        # Make sure the fields exist (these raise FieldDoesNotExist,
         # which is a fine error to raise here)
         self.name = name
         self.model = cls
         self.cache_attr = "_%s_cache" % name
-        
+
         # For some reason I don't totally understand, using weakrefs here 
doesn't work.
         dispatcher.connect(self.instance_pre_init, signal=signals.pre_init, 
sender=cls, weak=False)
 
@@ -35,18 +35,18 @@
         setattr(cls, name, self)
 
     def instance_pre_init(self, signal, sender, args, kwargs):
-        # Handle initalizing an object with the generic FK instaed of 
-        # content-type/object-id fields.        
+        # Handle initalizing an object with the generic FK instaed of
+        # content-type/object-id fields.
         if kwargs.has_key(self.name):
             value = kwargs.pop(self.name)
             kwargs[self.ct_field] = self.get_content_type(value)
             kwargs[self.fk_field] = value._get_pk_val()
-            
+
     def get_content_type(self, obj):
         # Convenience function using get_model avoids a circular import when 
using this model
         ContentType = get_model("contenttypes", "contenttype")
         return ContentType.objects.get_for_model(obj)
-        
+
     def __get__(self, instance, instance_type=None):
         if instance is None:
             raise AttributeError, "%s must be accessed via instance" % 
self.name
@@ -77,21 +77,21 @@
         setattr(instance, self.ct_field, ct)
         setattr(instance, self.fk_field, fk)
         setattr(instance, self.cache_attr, value)
-    
+
 class GenericRelation(RelatedField, Field):
     """Provides an accessor to generic related objects (i.e. comments)"""
 
     def __init__(self, to, **kwargs):
         kwargs['verbose_name'] = kwargs.get('verbose_name', None)
-        kwargs['rel'] = GenericRel(to, 
+        kwargs['rel'] = GenericRel(to,
                             related_name=kwargs.pop('related_name', None),
                             limit_choices_to=kwargs.pop('limit_choices_to', 
None),
                             symmetrical=kwargs.pop('symmetrical', True))
-                            
+
         # Override content-type/object-id field names on the related class
         self.object_id_field_name = kwargs.pop("object_id_field", "object_id")
-        self.content_type_field_name = kwargs.pop("content_type_field", 
"content_type")                
-        
+        self.content_type_field_name = kwargs.pop("content_type_field", 
"content_type")
+
         kwargs['blank'] = True
         kwargs['editable'] = False
         Field.__init__(self, **kwargs)
@@ -115,7 +115,7 @@
 
     def m2m_column_name(self):
         return self.object_id_field_name
-        
+
     def m2m_reverse_name(self):
         return self.object_id_field_name
 
@@ -130,13 +130,13 @@
 
     def contribute_to_related_class(self, cls, related):
         pass
-        
+
     def set_attributes_from_rel(self):
         pass
 
     def get_internal_type(self):
         return "ManyToManyField"
-        
+
 class ReverseGenericRelatedObjectsDescriptor(object):
     """
     This class provides the functionality that makes the related-object
@@ -190,12 +190,12 @@
     Factory function for a manager that subclasses 'superclass' (which is a
     Manager) and adds behavior for generic related objects.
     """
-    
+
     class GenericRelatedObjectManager(superclass):
         def __init__(self, model=None, core_filters=None, instance=None, 
symmetrical=None,
                      join_table=None, source_col_name=None, 
target_col_name=None, content_type=None,
                      content_type_field_name=None, object_id_field_name=None):
-            
+
             super(GenericRelatedObjectManager, self).__init__()
             self.core_filters = core_filters or {}
             self.model = model
@@ -209,10 +209,10 @@
             self.content_type_field_name = content_type_field_name
             self.object_id_field_name = object_id_field_name
             self.pk_val = self.instance._get_pk_val()
-                        
+
         def get_query_set(self):
             query = {
-                '%s__pk' % self.content_type_field_name : 
self.content_type.id, 
+                '%s__pk' % self.content_type_field_name : self.content_type.id,
                 '%s__exact' % self.object_id_field_name : self.pk_val,
             }
             return superclass.get_query_set(self).filter(**query)
@@ -252,8 +252,5 @@
         self.filter_interface = None
         self.limit_choices_to = limit_choices_to or {}
         self.edit_inline = False
-        self.raw_id_admin = False
         self.symmetrical = symmetrical
         self.multiple = True
-        assert not (self.raw_id_admin and self.filter_interface), \
-            "Generic relations may not use both raw_id_admin and 
filter_interface"

Modified: django/branches/newforms-admin/django/db/models/fields/related.py
===================================================================
--- django/branches/newforms-admin/django/db/models/fields/related.py   
2007-01-25 13:47:55 UTC (rev 4429)
+++ django/branches/newforms-admin/django/db/models/fields/related.py   
2007-01-25 18:05:10 UTC (rev 4430)
@@ -483,8 +483,7 @@
             edit_inline=kwargs.pop('edit_inline', False),
             related_name=kwargs.pop('related_name', None),
             limit_choices_to=kwargs.pop('limit_choices_to', None),
-            lookup_overrides=kwargs.pop('lookup_overrides', None),
-            raw_id_admin=kwargs.pop('raw_id_admin', False))
+            lookup_overrides=kwargs.pop('lookup_overrides', None))
         Field.__init__(self, **kwargs)
 
         self.db_index = True
@@ -497,27 +496,20 @@
 
     def prepare_field_objs_and_params(self, manipulator, name_prefix):
         params = {'validator_list': self.validator_list[:], 'member_name': 
name_prefix + self.attname}
-        if self.rel.raw_id_admin:
-            field_objs = self.get_manipulator_field_objs()
-            params['validator_list'].append(curry(manipulator_valid_rel_key, 
self, manipulator))
+        if self.radio_admin:
+            field_objs = [oldforms.RadioSelectField]
+            params['ul_class'] = get_ul_class(self.radio_admin)
         else:
-            if self.radio_admin:
-                field_objs = [oldforms.RadioSelectField]
-                params['ul_class'] = get_ul_class(self.radio_admin)
+            if self.null:
+                field_objs = [oldforms.NullSelectField]
             else:
-                if self.null:
-                    field_objs = [oldforms.NullSelectField]
-                else:
-                    field_objs = [oldforms.SelectField]
-            params['choices'] = self.get_choices_default()
+                field_objs = [oldforms.SelectField]
+        params['choices'] = self.get_choices_default()
         return field_objs, params
 
     def get_manipulator_field_objs(self):
         rel_field = self.rel.get_related_field()
-        if self.rel.raw_id_admin and not isinstance(rel_field, AutoField):
-            return rel_field.get_manipulator_field_objs()
-        else:
-            return [oldforms.IntegerField]
+        return [oldforms.IntegerField]
 
     def get_db_prep_save(self, value):
         if value == '' or value == None:
@@ -533,7 +525,7 @@
             # is *2*, not 1, because SelectFields always have an initial
             # "blank" value. Otherwise (radio_admin=True), we check that the
             # length is 1.
-            if not self.blank and (not self.rel.raw_id_admin or self.choices):
+            if not self.blank and self.choices:
                 choice_list = self.get_choices_default()
                 if self.radio_admin and len(choice_list) == 1:
                     return {self.attname: choice_list[0][0]}
@@ -573,8 +565,7 @@
             edit_inline=kwargs.pop('edit_inline', False),
             related_name=kwargs.pop('related_name', None),
             limit_choices_to=kwargs.pop('limit_choices_to', None),
-            lookup_overrides=kwargs.pop('lookup_overrides', None),
-            raw_id_admin=kwargs.pop('raw_id_admin', False))
+            lookup_overrides=kwargs.pop('lookup_overrides', None))
         kwargs['primary_key'] = True
         IntegerField.__init__(self, **kwargs)
 
@@ -590,19 +581,15 @@
     # ManyToManyField. This works for now.
     def prepare_field_objs_and_params(self, manipulator, name_prefix):
         params = {'validator_list': self.validator_list[:], 'member_name': 
name_prefix + self.attname}
-        if self.rel.raw_id_admin:
-            field_objs = self.get_manipulator_field_objs()
-            params['validator_list'].append(curry(manipulator_valid_rel_key, 
self, manipulator))
+        if self.radio_admin:
+            field_objs = [oldforms.RadioSelectField]
+            params['ul_class'] = get_ul_class(self.radio_admin)
         else:
-            if self.radio_admin:
-                field_objs = [oldforms.RadioSelectField]
-                params['ul_class'] = get_ul_class(self.radio_admin)
+            if self.null:
+                field_objs = [oldforms.NullSelectField]
             else:
-                if self.null:
-                    field_objs = [oldforms.NullSelectField]
-                else:
-                    field_objs = [oldforms.SelectField]
-            params['choices'] = self.get_choices_default()
+                field_objs = [oldforms.SelectField]
+        params['choices'] = self.get_choices_default()
         return field_objs, params
 
     def contribute_to_class(self, cls, name):
@@ -627,24 +614,15 @@
             related_name=kwargs.pop('related_name', None),
             filter_interface=kwargs.pop('filter_interface', None),
             limit_choices_to=kwargs.pop('limit_choices_to', None),
-            raw_id_admin=kwargs.pop('raw_id_admin', False),
             symmetrical=kwargs.pop('symmetrical', True))
-        if kwargs["rel"].raw_id_admin:
-            kwargs.setdefault("validator_list", []).append(self.isValidIDList)
         Field.__init__(self, **kwargs)
 
-        if self.rel.raw_id_admin:
-            msg = gettext_lazy('Separate multiple IDs with commas.')
-        else:
-            msg = gettext_lazy('Hold down "Control", or "Command" on a Mac, to 
select more than one.')
+        msg = gettext_lazy('Hold down "Control", or "Command" on a Mac, to 
select more than one.')
         self.help_text = string_concat(self.help_text, ' ', msg)
 
     def get_manipulator_field_objs(self):
-        if self.rel.raw_id_admin:
-            return [oldforms.RawIdAdminField]
-        else:
-            choices = self.get_choices_default()
-            return [curry(oldforms.SelectMultipleField, 
size=min(max(len(choices), 5), 15), choices=choices)]
+        choices = self.get_choices_default()
+        return [curry(oldforms.SelectMultipleField, size=min(max(len(choices), 
5), 15), choices=choices)]
 
     def get_choices_default(self):
         return Field.get_choices(self, include_blank=False)
@@ -690,14 +668,11 @@
         new_data = {}
         if obj:
             instance_ids = [instance._get_pk_val() for instance in 
getattr(obj, self.name).all()]
-            if self.rel.raw_id_admin:
-                new_data[self.name] = ",".join([str(id) for id in 
instance_ids])
-            else:
-                new_data[self.name] = instance_ids
+            new_data[self.name] = instance_ids
         else:
             # In required many-to-many fields with only one available choice,
             # select that one available choice.
-            if not self.blank and not self.rel.edit_inline and not 
self.rel.raw_id_admin:
+            if not self.blank and not self.rel.edit_inline:
                 choices_list = self.get_choices_default()
                 if len(choices_list) == 1:
                     new_data[self.name] = [choices_list[0][0]]
@@ -741,7 +716,7 @@
 class ManyToOneRel(object):
     def __init__(self, to, field_name, num_in_admin=3, min_num_in_admin=None,
         max_num_in_admin=None, num_extra_on_change=1, edit_inline=False,
-        related_name=None, limit_choices_to=None, lookup_overrides=None, 
raw_id_admin=False):
+        related_name=None, limit_choices_to=None, lookup_overrides=None):
         try:
             to._meta
         except AttributeError: # to._meta doesn't exist, so it must be 
RECURSIVE_RELATIONSHIP_CONSTANT
@@ -754,7 +729,6 @@
             limit_choices_to = {}
         self.limit_choices_to = limit_choices_to
         self.lookup_overrides = lookup_overrides or {}
-        self.raw_id_admin = raw_id_admin
         self.multiple = True
 
     def get_related_field(self):
@@ -763,8 +737,7 @@
 
 class OneToOneRel(ManyToOneRel):
     def __init__(self, to, field_name, num_in_admin=0, edit_inline=False,
-        related_name=None, limit_choices_to=None, lookup_overrides=None,
-        raw_id_admin=False):
+        related_name=None, limit_choices_to=None, lookup_overrides=None):
         self.to, self.field_name = to, field_name
         self.num_in_admin, self.edit_inline = num_in_admin, edit_inline
         self.related_name = related_name
@@ -772,12 +745,11 @@
             limit_choices_to = {}
         self.limit_choices_to = limit_choices_to
         self.lookup_overrides = lookup_overrides or {}
-        self.raw_id_admin = raw_id_admin
         self.multiple = False
 
 class ManyToManyRel(object):
     def __init__(self, to, num_in_admin=0, related_name=None,
-        filter_interface=None, limit_choices_to=None, raw_id_admin=False, 
symmetrical=True):
+        filter_interface=None, limit_choices_to=None, symmetrical=True):
         self.to = to
         self.num_in_admin = num_in_admin
         self.related_name = related_name
@@ -786,8 +758,5 @@
             limit_choices_to = {}
         self.limit_choices_to = limit_choices_to
         self.edit_inline = False
-        self.raw_id_admin = raw_id_admin
         self.symmetrical = symmetrical
         self.multiple = True
-
-        assert not (self.raw_id_admin and self.filter_interface), 
"ManyToManyRels may not use both raw_id_admin and filter_interface"

Modified: django/branches/newforms-admin/django/db/models/manipulators.py
===================================================================
--- django/branches/newforms-admin/django/db/models/manipulators.py     
2007-01-25 13:47:55 UTC (rev 4429)
+++ django/branches/newforms-admin/django/db/models/manipulators.py     
2007-01-25 18:05:10 UTC (rev 4430)
@@ -116,10 +116,7 @@
         for f in self.opts.many_to_many:
             if self.follow.get(f.name, None):
                 if not f.rel.edit_inline:
-                    if f.rel.raw_id_admin:
-                        new_vals = new_data.get(f.name, ())
-                    else:
-                        new_vals = new_data.getlist(f.name)
+                    new_vals = new_data.getlist(f.name)
                     # First, clear the existing values.
                     rel_manager = getattr(new_object, f.name)
                     rel_manager.clear()
@@ -216,8 +213,6 @@
                         for f in related.opts.many_to_many:
                             if child_follow.get(f.name, None) and not 
f.rel.edit_inline:
                                 new_value = rel_new_data[f.attname]
-                                if f.rel.raw_id_admin:
-                                    new_value = new_value[0]
                                 setattr(new_rel_obj, f.name, 
f.rel.to.objects.filter(pk__in=new_value))
                                 if self.change:
                                     self.fields_changed.append('%s for %s 
"%s"' % (f.verbose_name, related.opts.verbose_name, new_rel_obj))


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to