Commit ce47d4ab authored by Brian Rosner's avatar Brian Rosner
Browse files

Fixed #8648 -- Admin no longer ignores to_field. Thanks for the help Karen Tracey and SmileyChris.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@8823 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent dcb0e8f9
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -222,7 +222,11 @@ def items_for_result(cl, result):
            url = cl.url_for_result(result)
            # Convert the pk to something that can be used in Javascript.
            # Problem cases are long ints (23L) and non-ASCII strings.
            result_id = repr(force_unicode(getattr(result, pk)))[1:]
            if cl.to_field:
                attr = str(cl.to_field)
            else:
                attr = pk
            result_id = repr(force_unicode(getattr(result, attr)))[1:]
            yield mark_safe(u'<%s%s><a href="%s"%s>%s</a></%s>' % \
                (table_tag, row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %s); return false;"' % result_id or ''), conditional_escape(result_repr), table_tag))
        else:
+4 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ ORDER_VAR = 'o'
ORDER_TYPE_VAR = 'ot'
PAGE_VAR = 'p'
SEARCH_VAR = 'q'
TO_FIELD_VAR = 't'
IS_POPUP_VAR = 'pop'
ERROR_FLAG = 'e'

@@ -52,9 +53,12 @@ class ChangeList(object):
            self.page_num = 0
        self.show_all = ALL_VAR in request.GET
        self.is_popup = IS_POPUP_VAR in request.GET
        self.to_field = request.GET.get(TO_FIELD_VAR)
        self.params = dict(request.GET.items())
        if PAGE_VAR in self.params:
            del self.params[PAGE_VAR]
        if TO_FIELD_VAR in self.params:
            del self.params[TO_FIELD_VAR]
        if ERROR_FLAG in self.params:
            del self.params[ERROR_FLAG]

+18 −15
Original line number Diff line number Diff line
@@ -105,11 +105,13 @@ class ForeignKeyRawIdWidget(forms.TextInput):
        super(ForeignKeyRawIdWidget, self).__init__(attrs)

    def render(self, name, value, attrs=None):
        from django.contrib.admin.views.main import TO_FIELD_VAR
        related_url = '../../../%s/%s/' % (self.rel.to._meta.app_label, self.rel.to._meta.object_name.lower())
        params = {}
        if self.rel.limit_choices_to:
            url = '?' + '&amp;'.join(['%s=%s' % (k, ','.join(v)) for k, v in self.rel.limit_choices_to.items()])
        else:
            url = ''
            params.update(dict([(k, ','.join(v)) for k, v in self.rel.limit_choices_to.items()]))
        params.update({TO_FIELD_VAR: self.rel.get_related_field().name})
        url = '?' + '&amp;'.join(['%s=%s' % (k, v) for k, v in params.items()])
        if not attrs.has_key('class'):
          attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript looks for this hook.
        output = [super(ForeignKeyRawIdWidget, self).render(name, value, attrs)]
@@ -123,8 +125,9 @@ class ForeignKeyRawIdWidget(forms.TextInput):
        return mark_safe(u''.join(output))

    def label_for_value(self, value):
        return '&nbsp;<strong>%s</strong>' % \
            truncate_words(self.rel.to.objects.get(pk=value), 14)
        key = self.rel.get_related_field().name
        obj = self.rel.to.objects.get(**{key: value})
        return '&nbsp;<strong>%s</strong>' % truncate_words(obj, 14)

class ManyToManyRawIdWidget(ForeignKeyRawIdWidget):
    """
+6 −1
Original line number Diff line number Diff line
@@ -691,7 +691,12 @@ class ForeignKey(RelatedField, Field):
        setattr(cls, related.get_accessor_name(), ForeignRelatedObjectsDescriptor(related))

    def formfield(self, **kwargs):
        defaults = {'form_class': forms.ModelChoiceField, 'queryset': self.rel.to._default_manager.complex_filter(self.rel.limit_choices_to)}
        defaults = {
            'form_class': forms.ModelChoiceField,
            'queryset': self.rel.to._default_manager.complex_filter(
                                                    self.rel.limit_choices_to),
            'to_field_name': self.rel.field_name,
        }
        defaults.update(kwargs)
        return super(ForeignKey, self).formfield(**defaults)

+14 −5
Original line number Diff line number Diff line
@@ -550,14 +550,21 @@ class ModelChoiceIterator(object):
        if self.field.cache_choices:
            if self.field.choice_cache is None:
                self.field.choice_cache = [
                    (obj.pk, self.field.label_from_instance(obj))
                    for obj in self.queryset.all()
                    self.choice(obj) for obj in self.queryset.all()
                ]
            for choice in self.field.choice_cache:
                yield choice
        else:
            for obj in self.queryset.all():
                yield (obj.pk, self.field.label_from_instance(obj))
                yield self.choice(obj)

    def choice(self, obj):
        if self.field.to_field_name:
            key = getattr(obj, self.field.to_field_name)
        else:
            key = obj.pk
        return (key, self.field.label_from_instance(obj))


class ModelChoiceField(ChoiceField):
    """A ChoiceField whose choices are a model QuerySet."""
@@ -570,7 +577,7 @@ class ModelChoiceField(ChoiceField):

    def __init__(self, queryset, empty_label=u"---------", cache_choices=False,
                 required=True, widget=None, label=None, initial=None,
                 help_text=None, *args, **kwargs):
                 help_text=None, to_field_name=None, *args, **kwargs):
        self.empty_label = empty_label
        self.cache_choices = cache_choices

@@ -580,6 +587,7 @@ class ModelChoiceField(ChoiceField):
                       *args, **kwargs)
        self.queryset = queryset
        self.choice_cache = None
        self.to_field_name = to_field_name

    def _get_queryset(self):
        return self._queryset
@@ -622,7 +630,8 @@ class ModelChoiceField(ChoiceField):
        if value in EMPTY_VALUES:
            return None
        try:
            value = self.queryset.get(pk=value)
            key = self.to_field_name or 'pk'
            value = self.queryset.get(**{key: value})
        except self.queryset.model.DoesNotExist:
            raise ValidationError(self.error_messages['invalid_choice'])
        return value
Loading