Ticket #15179: 15179.diff

File 15179.diff, 2.3 KB (added by SmileyChris, 4 years ago)

My take on a completely backwards compatible method

  • django/test/client.py

    diff --git a/django/test/client.py b/django/test/client.py
    index 5cbc0ca..b3bc5c7 100644
    a b class Client(RequestFactory): 
    494494            response = self._handle_redirects(response, **extra)
    495495        return response
    496496
    497     def login(self, **credentials):
     497    def login(self, *args, **credentials):
    498498        """
    499         Sets the Factory to appear as if it has successfully logged into a site.
     499        Sets the Factory to appear as if it has successfully logged into a
     500        site.
    500501
    501502        Returns True if login is possible; False if the provided credentials
    502503        are incorrect, or the user is inactive, or if the sessions framework is
    503504        not available.
     505
     506        If the login requires the request used to log in to be passed through
     507        the middleware layers, pass an empty dictionary as a positional
     508        argument::
     509
     510            client.login({}, username='joe', password='password')
     511
     512        This dictionary can contain request metadata required for the
     513        authentication request to succeed, for example::
     514
     515            request_data = {'HTTP_HOST': 'localhost'}
     516            client.login(request_data, username='joe', password='password')
    504517        """
     518        if args and (len(args) != 1 or not isinstance(args[0], dict)):
     519            raise AttributeError('The login method only accepts a single '
     520                'positional argument which should be a dictionary.')
    505521        user = authenticate(**credentials)
    506522        if user and user.is_active \
    507523                and 'django.contrib.sessions' in settings.INSTALLED_APPS:
    508524            engine = import_module(settings.SESSION_ENGINE)
    509525
    510526            # Create a fake request to store login details.
    511             request = HttpRequest()
     527            if args:
     528                # If any request data is provided (even an empty dictionary),
     529                # get a proper request which has passed through the middleware
     530                # layers. The `/login/` URL is simply a dummy location for the
     531                # request.
     532                request = RequestFactory(**args[0]).post("/login/")
     533            else:
     534                request = HttpRequest()
    512535            if self.session:
    513536                request.session = self.session
    514537            else:
Back to Top