Last active
December 10, 2015 14:19
-
-
Save pipermerriam/4446905 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.utils.http import is_safe_url | |
from django.core.urlresolvers import reverse | |
from django.utils.safestring import mark_safe | |
class WithNextUrlMixin(object): | |
""" | |
This view will use whatever value was submitted as `next` as the success | |
url, as long as the url resolves correctly. | |
""" | |
def get_success_url(self): | |
return self.get_next_url() or super(WithNextUrlMixin, self).get_success_url() | |
def get_next_url(self): | |
next = self.request.REQUEST.get('next') | |
if next and is_safe_url(next): | |
return next | |
def get_context_data(self, **kwargs): | |
kwargs = super(WithNextUrlMixin, self).get_context_data(**kwargs) | |
next = self.get_next_url() | |
if next: | |
kwargs['next'] = next | |
kwargs['next_input'] = mark_safe('<input type="hidden" name="next" value="{0}">'.format(next)) | |
return kwargs | |
@classmethod | |
def as_view(cls, *args, **kwargs): | |
""" | |
Wraps View.as_view to add a with_next function on the view object. | |
with_next will return the reverse of the current view with the query | |
string for the next URL appended. | |
""" | |
view = super(WithNextUrlMixin, cls).as_view(*args, **kwargs) | |
def with_next(next_url, args=None, kwargs=None): | |
return '{0}?{1}'.format( | |
reverse(view, args=args, kwargs=kwargs), | |
urllib.urlencode({'next': next_url}), | |
) | |
view.with_next = with_next | |
return view |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class LoginView(WithNextUrlMixin, ...): | |
... | |
login = LoginView.as_view() | |
class NeedsLoginView(...): | |
def get(self, *args, **kwargs): | |
if not self.request.user.is_authenticated(): | |
return redirect(login.with_next(self.request.path)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment