Index: django/django/test/client.py
===================================================================
--- django/django/test/client.py	(revision 9787)
+++ django/django/test/client.py	(working copy)
@@ -2,6 +2,7 @@
 from urlparse import urlparse, urlunparse
 import sys
 import os
+import mimetypes
 try:
     from cStringIO import StringIO
 except ImportError:
@@ -83,7 +84,7 @@
     store.setdefault('template',[]).append(template)
     store.setdefault('context',[]).append(context)
 
-def encode_multipart(boundary, data):
+def encode_multipart(boundary, data, guess_mimetypes):
     """
     Encodes multipart POST data from a dictionary of form values.
 
@@ -88,8 +89,9 @@
     Encodes multipart POST data from a dictionary of form values.
 
     The key will be used as the form data name; the value will be transmitted
-    as content. If the value is a file, the contents of the file will be sent
-    as an application/octet-stream; otherwise, str(value) will be sent.
+    as content. If the value is a file, its mimetype will be guessed if
+    guess_mimetypes is True or will be set to application/octet-stream by
+    default; otherwise, str(value) will be sent.
     """
     lines = []
     to_str = lambda s: smart_str(s, settings.DEFAULT_CHARSET)
@@ -102,11 +104,11 @@
     # names can be duplicated!
     for (key, value) in data.items():
         if is_file(value):
-            lines.extend(encode_file(boundary, key, value))
+            lines.extend(encode_file(boundary, key, value, guess_mimetypes))
         elif not isinstance(value, basestring) and is_iterable(value):
             for item in value:
                 if is_file(item):
-                    lines.extend(encode_file(boundary, key, item))
+                    lines.extend(encode_file(boundary, key, item, guess_mimetypes))
                 else:
                     lines.extend([
                         '--' + boundary,
@@ -128,13 +130,20 @@
     ])
     return '\r\n'.join(lines)
 
-def encode_file(boundary, key, file):
+def encode_file(boundary, key, file, guess_mimetype):
     to_str = lambda s: smart_str(s, settings.DEFAULT_CHARSET)
+    filename = os.path.basename(file.name)
+    if guess_mimetype:
+        mimetype, encoding = mimetypes.guess_type(filename)
+        if mimetype is None:
+            mimetype = 'application/octet-stream'
+    else:
+        mimetype = 'application/octet-stream'
     return [
         '--' + boundary,
         'Content-Disposition: form-data; name="%s"; filename="%s"' \
-            % (to_str(key), to_str(os.path.basename(file.name))),
-        'Content-Type: application/octet-stream',
+            % (to_str(key), to_str(filename)),
+        'Content-Type: %s' % mimetype,
         '',
         file.read()
     ]
@@ -276,7 +285,7 @@
 
         return self.request(**r)
 
-    def post(self, path, data={}, content_type=MULTIPART_CONTENT, **extra):
+    def post(self, path, data={}, content_type=MULTIPART_CONTENT, guess_mimetypes=False, **extra):
         """
         Requests a response from the server using POST.
         """
@@ -281,7 +290,7 @@
         Requests a response from the server using POST.
         """
         if content_type is MULTIPART_CONTENT:
-            post_data = encode_multipart(BOUNDARY, data)
+            post_data = encode_multipart(BOUNDARY, data, guess_mimetypes)
         else:
             post_data = data
 
@@ -329,7 +338,7 @@
 
         return self.request(**r)
 
-    def put(self, path, data={}, content_type=MULTIPART_CONTENT, **extra):
+    def put(self, path, data={}, content_type=MULTIPART_CONTENT, guess_mimetypes=False, **extra):
         """
         Send a resource to the server using PUT.
         """
@@ -334,7 +343,7 @@
         Send a resource to the server using PUT.
         """
         if content_type is MULTIPART_CONTENT:
-            post_data = encode_multipart(BOUNDARY, data)
+            post_data = encode_multipart(BOUNDARY, data, guess_mimetypes)
         else:
             post_data = data
 
Index: django/docs/topics/testing.txt
===================================================================
--- django/docs/topics/testing.txt	(revision 9787)
+++ django/docs/topics/testing.txt	(working copy)
@@ -505,7 +505,7 @@
         If you provide URL both an encoded GET data and a data argument,
         the data argument will take precedence.
 
-    .. method:: Client.post(path, data={}, content_type=MULTIPART_CONTENT)
+    .. method:: Client.post(path, data={}, content_type=MULTIPART_CONTENT, guess_mimetypes=False)
 
         Makes a POST request on the provided ``path`` and returns a
         ``Response`` object, which is documented below.
@@ -553,7 +553,11 @@
         (The name ``attachment`` here is not relevant; use whatever name your
         file-processing code expects.)
 
-        Note that you should manually close the file after it has been provided
+		Note that by default all files will be sent as application/octet-stream.
+		If you want to let python guess the files' MIME types, simply set
+		the ``guess_mimetypes`` parameter as True.
+
+        Also note that you should manually close the file after it has been provided
         to ``post()``.
 
         .. versionadded:: development
@@ -583,7 +587,7 @@
         Makes an OPTIONS request on the provided ``path`` and returns a
         ``Response`` object. Useful for testing RESTful interfaces.
 
-    .. method:: Client.put(path, data={}, content_type=MULTIPART_CONTENT)
+    .. method:: Client.put(path, data={}, content_type=MULTIPART_CONTENT, guess_mimetypes=False)
 
         .. versionadded:: development
 
Index: django/tests/regressiontests/test_client_regress/files/test1.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: E:\Software\workspace\django\tests\regressiontests\test_client_regress\files\test1.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: django/tests/regressiontests/test_client_regress/files/test2.txt
===================================================================
--- django/tests/regressiontests/test_client_regress/files/test2.txt	(revision 0)
+++ django/tests/regressiontests/test_client_regress/files/test2.txt	(revision 0)
@@ -0,0 +1 @@
+This is a text, doh.
\ No newline at end of file
Index: django/tests/regressiontests/test_client_regress/models.py
===================================================================
--- django/tests/regressiontests/test_client_regress/models.py	(revision 9787)
+++ django/tests/regressiontests/test_client_regress/models.py	(working copy)
@@ -472,3 +472,31 @@
         self.assertEqual(response.context['post-bar'], 'bang')
         self.assertEqual(response.context['request-foo'], 'whiz')
         self.assertEqual(response.context['request-bar'], 'bang')
+
+class MimetypesTests(TestCase):
+    urls = 'regressiontests.test_client_regress.urls'
+
+    def test_mimetypes(self):
+        f1 = open(os.path.join(os.path.dirname(__file__), 'files/test1.png'), 'rb')
+        f2 = open(os.path.join(os.path.dirname(__file__), 'files/test2.txt'), 'rb')
+        post_data = {
+            'file_field1': f1,
+            'file_field2': f2,
+        }        
+        # Guessed mimetypes
+        response = self.client.post('/mimetypes/', post_data, guess_mimetypes=True)
+        self.assertContains(response, 'test1.png:image/png', 1, 200)
+        self.assertContains(response, 'test2.txt:text/plain', 1, 200)
+        
+        # Default mimetypes
+        response = self.client.post('/mimetypes/', post_data, guess_mimetypes=False)
+        self.assertContains(response, 'test1.png:application/octet-stream', 1, 200)
+        self.assertContains(response, 'test2.txt:application/octet-stream', 1, 200)
+        
+        # Without 'guess_mimetypes' (default mimetypes)
+        response = self.client.post('/mimetypes/', post_data)
+        self.assertContains(response, 'test1.png:application/octet-stream', 1, 200)
+        self.assertContains(response, 'test2.txt:application/octet-stream', 1, 200)
+        
+        f1.close()
+        f2.close()
\ No newline at end of file
Index: django/tests/regressiontests/test_client_regress/urls.py
===================================================================
--- django/tests/regressiontests/test_client_regress/urls.py	(revision 9787)
+++ django/tests/regressiontests/test_client_regress/urls.py	(working copy)
@@ -11,4 +11,5 @@
     (r'^set_session/$', views.set_session_view),
     (r'^check_session/$', views.check_session_view),
     (r'^request_methods/$', views.request_methods_view),
+    (r'^mimetypes/$', views.mimetypes_view),
 )
Index: django/tests/regressiontests/test_client_regress/views.py
===================================================================
--- django/tests/regressiontests/test_client_regress/views.py	(revision 9787)
+++ django/tests/regressiontests/test_client_regress/views.py	(working copy)
@@ -58,4 +58,9 @@
 
 def request_methods_view(request):
     "A view that responds with the request method"
-    return HttpResponse('request method: %s' % request.method)
\ No newline at end of file
+    return HttpResponse('request method: %s' % request.method)
+
+def mimetypes_view(request):
+    "A view that checks uploaded files' mimtypes"
+    content = ','.join(['%s:%s' % (v.name, v.content_type) for k, v in request.FILES.items()])
+    return HttpResponse(str(content))
\ No newline at end of file
