Repository: encode/django-rest-framework

Issue:
FileUploadParser never gets filename from url because get_parser_context called before kwargs set
get_parser_context always returns an empty args and kwargs because it depends on args & kwargs being set, and dispatch calls initialize_request before setting the variables.

Either get_parser_context needs to be passed args and kwargs, or dispatch needs to set args and kwargs before invoking initialize_request.

Additionally, FileUploadParser is fine returning None as a filename, but the standard filehandlers do not create a file in that circumstance, causing request.FILES['file'] to not be invoked.



Discussion:

Resolving patch:
diff --git a/rest_framework/routers.py b/rest_framework/routers.py
--- a/rest_framework/routers.py
+++ b/rest_framework/routers.py
@@ -215,6 +215,7 @@ class DefaultRouter(SimpleRouter):
     """
     include_root_view = True
     include_format_suffixes = True
+    root_view_name = 'api-root'
 
     def get_api_root_view(self):
         """
@@ -244,7 +245,7 @@ def get_urls(self):
         urls = []
 
         if self.include_root_view:
-            root_url = url(r'^$', self.get_api_root_view(), name='api-root')
+            root_url = url(r'^$', self.get_api_root_view(), name=self.root_view_name)
             urls.append(root_url)
 
         default_urls = super(DefaultRouter, self).get_urls()
diff --git a/rest_framework/views.py b/rest_framework/views.py
--- a/rest_framework/views.py
+++ b/rest_framework/views.py
@@ -304,10 +304,10 @@ def dispatch(self, request, *args, **kwargs):
         `.dispatch()` is pretty much the same as Django's regular dispatch,
         but with extra hooks for startup, finalize, and exception handling.
         """
-        request = self.initialize_request(request, *args, **kwargs)
-        self.request = request
         self.args = args
         self.kwargs = kwargs
+        request = self.initialize_request(request, *args, **kwargs)
+        self.request = request
         self.headers = self.default_response_headers  # deprecate?
 
         try:


Test patch:
diff --git a/rest_framework/tests/test_routers.py b/rest_framework/tests/test_routers.py
--- a/rest_framework/tests/test_routers.py
+++ b/rest_framework/tests/test_routers.py
@@ -6,7 +6,7 @@
 from rest_framework.compat import include, patterns, url
 from rest_framework.decorators import link, action
 from rest_framework.response import Response
-from rest_framework.routers import SimpleRouter
+from rest_framework.routers import SimpleRouter, DefaultRouter
 
 factory = RequestFactory()
 
@@ -148,3 +148,17 @@ def test_urls_can_have_trailing_slash_removed(self):
         expected = ['^notes$', '^notes/(?P<pk>[^/]+)$']
         for idx in range(len(expected)):
             self.assertEqual(expected[idx], self.urls[idx].regex.pattern)
+
+class TestNameableRoot(TestCase):
+    def setUp(self):
+        class NoteViewSet(viewsets.ModelViewSet):
+            model = RouterTestModel
+        self.router = DefaultRouter()
+        self.router.root_view_name = 'nameable-root'
+        self.router.register(r'notes', NoteViewSet)
+        self.urls = self.router.urls
+
+    def test_router_has_custom_name(self):
+        expected = 'nameable-root'
+        self.assertEqual(expected, self.urls[0].name)
+