diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 467d13a..281963f 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -119,34 +119,6 @@ class Field(object):
         messages.update(error_messages or {})
         self.error_messages = messages
 
-    def __getstate__(self):
-        """
-        Pickling support.
-        """
-        from django.utils.functional import Promise
-        obj_dict = self.__dict__.copy()
-        items = []
-        translated_keys = []
-        for k, v in self.error_messages.items():
-            if isinstance(v, Promise):
-                args = getattr(v, '_proxy____args', None)
-                if args:
-                    translated_keys.append(k)
-                    v = args[0]
-            items.append((k,v))
-        obj_dict['_translated_keys'] = translated_keys
-        obj_dict['error_messages'] = dict(items)
-        return obj_dict
-
-    def __setstate__(self, obj_dict):
-        """
-        Unpickling support.
-        """
-        translated_keys = obj_dict.pop('_translated_keys')
-        self.__dict__.update(obj_dict)
-        for k in translated_keys:
-            self.error_messages[k] = _(self.error_messages[k])
-
     def __cmp__(self, other):
         # This is needed because bisect does not take a comparison function.
         return cmp(self.creation_counter, other.creation_counter)
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index 8329792..9235a67 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -87,9 +87,9 @@ signals.class_prepared.connect(do_pending_lookups)
 class RelatedField(object):
     def contribute_to_class(self, cls, name):
         sup = super(RelatedField, self)
-
-        # Add an accessor to allow easy determination of the related query path for this field
-        self.related_query_name = curry(self._get_related_query_name, cls._meta)
+        
+        # Store the opts for related_query_name()
+        self.opts = cls._meta
 
         if hasattr(sup, 'contribute_to_class'):
             sup.contribute_to_class(cls, name)
@@ -174,12 +174,12 @@ class RelatedField(object):
             return []
         raise TypeError("Related Field has invalid lookup: %s" % lookup_type)
 
-    def _get_related_query_name(self, opts):
+    def related_query_name(self):
         # This method defines the name that can be used to identify this
         # related object in a table-spanning query. It uses the lower-cased
         # object_name by default, but this can be overridden with the
         # "related_name" option.
-        return self.rel.related_name or opts.object_name.lower()
+        return self.rel.related_name or self.opts.object_name.lower()
 
 class SingleRelatedObjectDescriptor(object):
     # This class provides the functionality that makes the related-object
diff --git a/django/utils/functional.py b/django/utils/functional.py
index e52ab76..4539497 100644
--- a/django/utils/functional.py
+++ b/django/utils/functional.py
@@ -147,6 +147,12 @@ def lazy(func, *resultclasses):
     the lazy evaluation code is triggered. Results are not memoized; the
     function is evaluated on every access.
     """
+    # When lazy() is called by the __reduce_ex__ machinery to reconstitute the
+    # __proxy__ class it can't call with *args, so the first item will just be
+    # a tuple.
+    if len(resultclasses) == 1 and isinstance(resultclasses[0], tuple):
+        resultclasses = resultclasses[0]
+    
     class __proxy__(Promise):
         """
         Encapsulate a function call and act as a proxy for methods that are
@@ -161,7 +167,10 @@ def lazy(func, *resultclasses):
             self.__kw = kw
             if self.__dispatch is None:
                 self.__prepare_class__()
-
+        
+        def __reduce_ex__(self, protocol):
+            return (lazy, (self.__func, resultclasses), self.__dict__)
+        
         def __prepare_class__(cls):
             cls.__dispatch = {}
             for resultclass in resultclasses:
diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py
index c0a0df9..54fb86d 100644
--- a/django/utils/translation/__init__.py
+++ b/django/utils/translation/__init__.py
@@ -1,8 +1,11 @@
 """
 Internationalization support.
 """
-from django.utils.functional import lazy
+from django.conf import settings
 from django.utils.encoding import force_unicode
+from django.utils.functional import lazy, curry
+from django.utils.translation import trans_real, trans_null
+
 
 __all__ = ['gettext', 'gettext_noop', 'gettext_lazy', 'ngettext',
         'ngettext_lazy', 'string_concat', 'activate', 'deactivate',
@@ -19,32 +22,23 @@ __all__ = ['gettext', 'gettext_noop', 'gettext_lazy', 'ngettext',
 # replace the functions with their real counterparts (once we do access the
 # settings).
 
-def delayed_loader(*args, **kwargs):
+def delayed_loader(real_name, *args, **kwargs):
     """
-    Replace each real_* function with the corresponding function from either
-    trans_real or trans_null (e.g. real_gettext is replaced with
-    trans_real.gettext or trans_null.gettext). This function is run once, the
-    first time any i18n method is called. It replaces all the i18n methods at
-    once at that time.
+    Call the real, underlying function.  We have a level of indirection here so
+    that modules can use the translation bits without actually requiring
+    Django's settings bits to be configured before import.
     """
-    import traceback
-    from django.conf import settings
     if settings.USE_I18N:
-        import trans_real as trans
+        trans = trans_real
     else:
-        import trans_null as trans
-    caller = traceback.extract_stack(limit=2)[0][2]
-    g = globals()
-    for name in __all__:
-        if hasattr(trans, name):
-            g['real_%s' % name] = getattr(trans, name)
+        trans = trans_null
 
     # Make the originally requested function call on the way out the door.
-    return g['real_%s' % caller](*args, **kwargs)
+    return getattr(trans, real_name)(*args, **kwargs)
 
 g = globals()
 for name in __all__:
-    g['real_%s' % name] = delayed_loader
+    g['real_%s' % name] = curry(delayed_loader, name)
 del g, delayed_loader
 
 def gettext_noop(message):
@@ -102,10 +96,10 @@ def templatize(src):
 def deactivate_all():
     return real_deactivate_all()
 
-def string_concat(*strings):
+def _string_concat(*strings):
     """
     Lazy variant of string concatenation, needed for translations that are
     constructed from multiple parts.
     """
     return u''.join([force_unicode(s) for s in strings])
-string_concat = lazy(string_concat, unicode)
+string_concat = lazy(_string_concat, unicode)
diff --git a/tests/regressiontests/i18n/tests.py b/tests/regressiontests/i18n/tests.py
index 31150a6..941f66f 100644
--- a/tests/regressiontests/i18n/tests.py
+++ b/tests/regressiontests/i18n/tests.py
@@ -46,7 +46,6 @@ class TranslationTests(TestCase):
         unicode(string_concat(...)) should not raise a TypeError - #4796
         """
         import django.utils.translation
-        self.assertEqual(django.utils.translation, reload(django.utils.translation))
         self.assertEqual(u'django', unicode(django.utils.translation.string_concat("dja", "ngo")))
 
     def test_safe_status(self):
diff --git a/tests/regressiontests/queryset_pickle/__init__.py b/tests/regressiontests/queryset_pickle/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/queryset_pickle/models.py b/tests/regressiontests/queryset_pickle/models.py
new file mode 100644
index 0000000..1c7dc4f
--- /dev/null
+++ b/tests/regressiontests/queryset_pickle/models.py
@@ -0,0 +1,8 @@
+from django.db import models
+
+
+class Group(models.Model):
+    name = models.CharField(max_length=100)
+
+class Event(models.Model):
+    group = models.ForeignKey(Group)
diff --git a/tests/regressiontests/queryset_pickle/tests.py b/tests/regressiontests/queryset_pickle/tests.py
new file mode 100644
index 0000000..cc0d0a6
--- /dev/null
+++ b/tests/regressiontests/queryset_pickle/tests.py
@@ -0,0 +1,14 @@
+import pickle
+
+from django.test import TestCase
+
+from models import Group, Event
+
+
+class PickleabilityTestCase(TestCase):
+    def assert_pickles(self, qs):
+        self.assertEqual(list(pickle.loads(pickle.dumps(qs))), list(qs))
+    
+    def test_related_field(self):
+        g = Group.objects.create(name="Ponies Who Own Maybachs")
+        self.assert_pickles(Event.objects.filter(group=g.id))
