-
-
Save amccloud/2201802 to your computer and use it in GitHub Desktop.
Revisions
-
bmispelon revised this gist
Feb 18, 2012 . 1 changed file with 183 additions and 206 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -2,9 +2,8 @@ import urlparse from django.conf import settings from django.core.urlresolvers import reverse_lazy from django.http import HttpResponseRedirect, QueryDict from django.utils.decorators import method_decorator from django.utils.http import base36_to_int from django.utils.translation import ugettext as _ @@ -55,7 +54,7 @@ def get_default_redirect_to(self): def get_success_url(self): default = self.get_default_redirect_to() redirect_to = self.request.REQUEST.get(self.get_redirect_field_name()) return redirect_to or default @@ -127,7 +126,7 @@ class LogoutView(ProtectectedRedirectToMixin, CurrentAppMixin, generic.TemplateV """ Logs out the user and displays 'You are logged out' message. """ template_name = 'registration/logged_out.html' current_app = None extra_context = None @@ -155,7 +154,7 @@ def get(self, request, *args, **kwargs): # Render the template return super(LogoutView, self).get(request, *args, **kwargs) # XXX: define post(), put(), ... ? class LogoutThenLoginView(LogoutView): @@ -169,87 +168,6 @@ def next_page(self): return self.login_url or settings.LOGIN_URL class PasswordResetView(CurrentAppMixin, generic.FormView): """ Ask for the user's email address and send a message containing a token @@ -259,7 +177,7 @@ class PasswordResetView(CurrentAppMixin, generic.FormView): form_class = PasswordResetForm success_url = reverse_lazy('django.contrib.auth.views.password_reset_done') is_admin_site = False email_template_name = "registration/password_reset_email.html" subject_template_name = "registration/password_reset_subject.txt" token_generator = default_token_generator @@ -290,37 +208,6 @@ def get_context_data(self, **kwargs): def dispatch(self, request, *args, **kwargs): return super(PasswordResetView, self).dispatch(request, *args, **kwargs) class PasswordResetDoneView(CurrentAppMixin, generic.TemplateView): """ @@ -332,24 +219,8 @@ class PasswordResetDoneView(CurrentAppMixin, generic.TemplateView): extra_context = None def get_context_data(self): # XXX: does this work? return self.extra_context class PasswordResetConfirmView(CurrentAppMixin, generic.UpdateView): @@ -403,33 +274,6 @@ def get_context_data(self, **kwargs): def dispatch(self, request, *args, **kwargs): return super(PasswordResetConfirmView, self).dispatch(request, *args, **kwargs) class PasswordResetComplete(CurrentAppMixin, generic.TemplateView): """ @@ -447,24 +291,6 @@ def get_context_data(self, **kwargs): return context class PasswordChangeView(CurrentAppMixin, generic.UpdateView): """ Prompt the logged-in user for their old password and a new one and change @@ -492,28 +318,6 @@ def get_form_kwargs(self): def dispatch(self, request, *args, **kwargs): return super(PasswordChangeView, self).dispatch(request, *args, **kwargs) class PasswordChangeDoneView(CurrentAppMixin, generic.TemplateView): """ @@ -533,12 +337,185 @@ def get_context_data(self, **kwargs): def dispatch(self, request, *args, **kwargs): return super(PasswordChangeDoneView, self).dispatch(request, *args, **kwargs) # Backwards-compatible stubs that call the class-based views: # login # logout # logout_then_login # redirect_to_login (not actually a view) # password_reset # password_reset_done # password_reset_confirm # password_reset_complete # password_change # password_change_done def login(request, template_name=None, redirect_field_name=None, authentication_form=None, current_app=None, extra_context=None): kwargs = {} if template_name is not None: kwargs["template_name"] = template_name if redirect_field_name is not None: kwargs["redirect_field_name"] = redirect_field_name if authentication_form is not None: kwargs["form_class"] = authentication_form if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context view = LoginView.as_view(**kwargs) return view(request) def logout(request, next_page=None, template_name=None, redirect_field_name=None, current_app=None, extra_context=None): kwargs = {} if next_page is not None: kwargs["default_redirect_to"] = next_page if template_name is not None: kwargs["template_name"] = template_name if redirect_field_name is not None: kwargs["redirect_field_name"] = redirect_field_name if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context view = LogoutView.as_view(**kwargs) return view(request) def logout_then_login(request, login_url=None, current_app=None, extra_context=None): kwargs = {} if login_url is not None: kwargs["login_url"] = login_url if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context view = LogoutThenLoginView.as_view(**kwargs) return view(request) def redirect_to_login(next, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME): """ Redirects the user to the login page, passing the given 'next' page """ if not login_url: login_url = settings.LOGIN_URL login_url_parts = list(urlparse.urlparse(login_url)) if redirect_field_name: querystring = QueryDict(login_url_parts[4], mutable=True) querystring[redirect_field_name] = next login_url_parts[4] = querystring.urlencode(safe='/') return HttpResponseRedirect(urlparse.urlunparse(login_url_parts)) def password_reset(request, is_admin_site=None, template_name=None, email_template_name=None, subject_template_name=None, password_reset_form=None, token_generator=None, post_reset_redirect=None, from_email=None, current_app=None, extra_context=None): kwargs = {} if is_admin_site is not None: kwargs["is_admin_site"] = is_admin_site if template_name is not None: kwargs["template_name"] = template_name if email_template_name is not None: kwargs["email_template_name"] = email_template_name if password_reset_form is not None: kwargs["form_class"] = password_reset_form if token_generator is not None: kwargs["token_generator"] = token_generator if post_reset_redirect is not None: kwargs["success_url"] = post_reset_redirect if from_email is not None: kwargs["from_email"] = from_email if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context password_reset = PasswordResetView.as_view(**kwargs) return password_reset(request) def password_reset_done(request, template_name=None, current_app=None, extra_context=None): kwargs = {} if template_name is not None: kwargs["template_name"] = template_name if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context password_reset_done = PasswordResetDoneView.as_view(**kwargs) return password_reset_done(request) def password_reset_confirm(request, uidb36=None, token=None, template_name=None, token_generator=None, set_password_form=None, post_reset_redirect=None, current_app=None, extra_context=None): assert uidb36 is not None and token is not None # checked by URLconf kwargs = {} if template_name is not None: kwargs["template_name"] = template_name if token_generator is not None: kwargs["token_generator"] = token_generator if set_password_form is not None: kwargs["form_class"] = set_password_form if post_reset_redirect is not None: kwargs["success_url"] = post_reset_redirect if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context password_reset_confirm = PasswordResetConfirmView.as_view(**kwargs) return password_reset_confirm(request, uidb36=uidb36, token=token) def password_reset_complete(request, template_name=None, current_app=None, extra_context=None): kwargs = {} if template_name is not None: kwargs["template_name"] = template_name if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context password_reset_complete = PasswordResetComplete.as_view(**kwargs) return password_reset_complete(request) def password_change(request, template_name=None, post_change_redirect=None, password_change_form=None, current_app=None, extra_context=None): kwargs = {} if template_name is not None: kwargs["template_name"] = template_name if post_change_redirect is not None: kwargs["success_url"] = post_change_redirect if password_change_form is not None: kwargs["form_class"] = password_change_form if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context password_change = PasswordChangeView.as_view(**kwargs) return password_change(request) def password_change_done(request, template_name=None, post_change_redirect=None, password_change_form=None, current_app=None, extra_context=None): kwargs = {} if template_name is not None: -
bmispelon revised this gist
Feb 18, 2012 . 1 changed file with 6 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -46,7 +46,7 @@ class RedirectToMixin(object): """ redirect_field_name = REDIRECT_FIELD_NAME default_redirect_to = None def get_redirect_field_name(self): return self.redirect_field_name @@ -86,7 +86,7 @@ class LoginView(ProtectectedRedirectToMixin, CurrentAppMixin, generic.FormView): current_app = None extra_context = None default_redirect_to = settings.LOGIN_REDIRECT_URL @method_decorator(sensitive_post_parameters()) @@ -131,7 +131,7 @@ class LogoutView(ProtectectedRedirectToMixin, CurrentAppMixin, generic.TemplateV current_app = None extra_context = None def get_context_data(self, **kwargs): context = super(LogoutView, self).get_context_data(**kwargs) current_site = get_current_site(self.request) @@ -151,7 +151,7 @@ def get(self, request, *args, **kwargs): # Redirect to the current page if no default has been provided redirect_to = redirect_to or self.request.path return HttpResponseRedirect(redirect_to) # Render the template return super(LogoutView, self).get(request, *args, **kwargs) @@ -163,7 +163,7 @@ class LogoutThenLoginView(LogoutView): Logs out the user if he is logged in. Then redirects to the log-in page. """ login_url = None @property def next_page(self): return self.login_url or settings.LOGIN_URL @@ -280,7 +280,7 @@ def form_valid(self, form): opts['domain_override'] = self.request.META['HTTP_HOST'] form.save(**opts) return super(PasswordResetView, self).form_valid(form) def get_context_data(self, **kwargs): context = super(PasswordResetView, self).get_context_data(**kwargs) context.update(self.extra_context or {}) -
bmispelon revised this gist
Feb 18, 2012 . 1 changed file with 31 additions and 20 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -2,15 +2,16 @@ import urlparse from django.conf import settings from django.core.urlresolvers import reverse, reverse_lazy from django.http import HttpResponseRedirect, QueryDict from django.template.response import TemplateResponse from django.utils.decorators import method_decorator from django.utils.http import base36_to_int from django.utils.translation import ugettext as _ from django.views import generic from django.views.decorators.debug import sensitive_post_parameters from django.views.decorators.cache import never_cache from django.views.decorators.csrf import csrf_protect # Avoid shadowing the login() and logout() views below. from django.contrib.auth import REDIRECT_FIELD_NAME, login as auth_login, logout as auth_logout @@ -32,7 +33,7 @@ def render_to_response(self, context, **response_kwargs): request=self.request, template=self.get_template_names(), context=context, current_app=self.current_app, **response_kwargs ) @@ -64,11 +65,15 @@ class ProtectectedRedirectToMixin(RedirectToMixin): """ def get_success_url(self): redirect_to = super(ProtectectedRedirectToMixin, self).get_success_url() if not redirect_to: return redirect_to netloc = urlparse.urlparse(redirect_to)[1] if not netloc or netloc == self.request.get_host(): return redirect_to return self.get_default_redirect_to() @@ -105,19 +110,17 @@ def form_valid(self, form): return super(LoginView, self).form_valid(form) def get_context_data(self, **kwargs): context = super(LoginView, self).get_context_data(**kwargs) current_site = get_current_site(self.request) context.update({ self.get_redirect_field_name(): self.get_success_url(), "site": current_site, "site_name": current_site.name, }) context.update(self.extra_context or {}) return context class LogoutView(ProtectectedRedirectToMixin, CurrentAppMixin, generic.TemplateView): @@ -131,6 +134,7 @@ class LogoutView(ProtectectedRedirectToMixin, CurrentAppMixin, generic.TemplateV def get_context_data(self, **kwargs): context = super(LogoutView, self).get_context_data(**kwargs) current_site = get_current_site(self.request) context.update({ 'site': current_site, 'site_name': current_site.name, @@ -139,12 +143,19 @@ def get_context_data(self, **kwargs): context.update(self.extra_context or {}) return context def get(self, request, *args, **kwargs): auth_logout(request) redirect_to = self.get_success_url() if redirect_to is not None: # Redirect to the current page if no default has been provided redirect_to = redirect_to or self.request.path return HttpResponseRedirect(redirect_to) # Render the template return super(LogoutView, self).get(request, *args, **kwargs) # TODO: define post(), put(), ... ? class LogoutThenLoginView(LogoutView): @@ -197,7 +208,7 @@ def logout(request, next_page=None, template_name=None, if extra_context is not None: kwargs["extra_context"] = extra_context view = LogoutView.as_view(**kwargs) return view(request) def logout_then_login(request, login_url=None, current_app=None, extra_context=None): @@ -265,7 +276,7 @@ def form_valid(self, form): 'subject_template_name': self.subject_template_name, 'request': self.request, } if self.is_admin_site: opts['domain_override'] = self.request.META['HTTP_HOST'] form.save(**opts) return super(PasswordResetView, self).form_valid(form) @@ -390,7 +401,7 @@ def get_context_data(self, **kwargs): @method_decorator(sensitive_post_parameters()) @method_decorator(never_cache) def dispatch(self, request, *args, **kwargs): return super(PasswordResetConfirmView, self).dispatch(request, *args, **kwargs) def password_reset_confirm(request, uidb36=None, token=None, template_name=None, token_generator=None, @@ -537,5 +548,5 @@ def password_change_done(request, template_name=None, post_change_redirect=None, if extra_context is not None: kwargs["extra_context"] = extra_context password_change_done = PasswordChangeDoneView.as_view(**kwargs) return password_change_done(request) -
bmispelon revised this gist
Feb 18, 2012 . 1 changed file with 25 additions and 28 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -43,36 +43,40 @@ class RedirectToMixin(object): name is configurable). In the absence of this parameter, a (configurable) default URL is used. """ redirect_field_name = REDIRECT_FIELD_NAME default_redirect_to = None def get_redirect_field_name(self): return self.redirect_field_name def get_default_redirect_to(self): return self.default_redirect_to def get_success_url(self): default = self.get_default_redirect_to() redirect_to = self.request.REQUEST.get(self.get_redirect_field_name(), '') return redirect_to or default class ProtectectedRedirectToMixin(RedirectToMixin): """ Ensure the URL to be redirected to is on the same host. """ def get_success_url(self): redirect_to = super(ProtectectedRedirectToMixin, self).get_success_url() netloc = urlparse.urlparse(redirect_to)[1] if not netloc or netloc == self.request.get_host(): return redirect_to return self.get_default_redirect_to() class LoginView(ProtectectedRedirectToMixin, CurrentAppMixin, generic.FormView): """ Displays the login form and handles the login action. """ form_class = AuthenticationForm template_name = 'registration/login.html' current_app = None @@ -116,14 +120,12 @@ def get_context_data(self, **kwargs): return ctx class LogoutView(ProtectectedRedirectToMixin, CurrentAppMixin, generic.TemplateView): """ Logs out the user and displays 'You are logged out' message. """ template_name='registration/logged_out.html' current_app = None extra_context = None @@ -136,18 +138,13 @@ def get_context_data(self, **kwargs): }) context.update(self.extra_context or {}) return context def get_default_redirect_to(self): return self.default_redirect_to or self.request.path def dispatch(self, request, *args, **kwargs): # TODO: GET, POST, ... ? auth_logout(request) return HttpResponseRedirect(self.get_success_url()) class LogoutThenLoginView(LogoutView): @@ -190,7 +187,7 @@ def logout(request, next_page=None, template_name=None, kwargs = {} if next_page is not None: kwargs["default_redirect_to"] = next_page if template_name is not None: kwargs["template_name"] = template_name if redirect_field_name is not None: -
bmispelon revised this gist
Feb 18, 2012 . 1 changed file with 6 additions and 12 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -111,8 +111,7 @@ def get_context_data(self, **kwargs): "site_name": current_site.name, }) ctx.update(self.extra_context or {}) return ctx @@ -135,8 +134,7 @@ def get_context_data(self, **kwargs): 'site_name': current_site.name, 'title': _('Logged out') }) context.update(self.extra_context or {}) return context def dispatch(self, request, *args, **kwargs): # TODO: GET, POST, ... ? @@ -277,8 +275,7 @@ def form_valid(self, form): def get_context_data(self, **kwargs): context = super(PasswordResetView, self).get_context_data(**kwargs) context.update(self.extra_context or {}) return context @method_decorator(csrf_protect) @@ -389,8 +386,7 @@ def get_context_data(self, **kwargs): context.update({ 'validlink': self.object is not None }) context.update(self.extra_context or {}) return context # Doesn't need csrf_protect since no-one can guess the URL @@ -439,8 +435,7 @@ class PasswordResetComplete(CurrentAppMixin, generic.TemplateView): def get_context_data(self, **kwargs): context = super(PasswordResetComplete, self).get_context_data(**kwargs) context['login_url'] = settings.LOGIN_URL context.update(self.extra_context or {}) return context @@ -523,8 +518,7 @@ class PasswordChangeDoneView(CurrentAppMixin, generic.TemplateView): def get_context_data(self, **kwargs): context = super(PasswordChangeDoneView, self).get_context_data(**kwargs) context.update(self.extra_context or {}) return context @method_decorator(login_required) -
bmispelon revised this gist
Feb 17, 2012 . 1 changed file with 82 additions and 30 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,32 @@ # https://code.djangoproject.com/ticket/17209 import urlparse from django.conf import settings from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect, QueryDict from django.template.response import TemplateResponse from django.utils.http import base36_to_int from django.utils.translation import ugettext as _ from django.views.decorators.debug import sensitive_post_parameters from django.views.decorators.cache import never_cache from django.views.decorators.csrf import csrf_protect from django.views import generic # Avoid shadowing the login() and logout() views below. from django.contrib.auth import REDIRECT_FIELD_NAME, login as auth_login, logout as auth_logout from django.contrib.auth.decorators import login_required from django.contrib.auth.forms import AuthenticationForm, PasswordResetForm, SetPasswordForm, PasswordChangeForm from django.contrib.auth.models import User from django.contrib.auth.tokens import default_token_generator from django.contrib.sites.models import get_current_site class CurrentAppMixin(object): """ Add a current_app property on the view and pass it to the response class. """ current_app = None def render_to_response(self, context, **response_kwargs): return self.response_class( request=self.request, @@ -11,6 +38,11 @@ def render_to_response(self, context, **response_kwargs): class RedirectToMixin(object): """ Provide a success_url that takes into account a request parameter (whose name is configurable). In the absence of this parameter, a (configurable) default URL is used. """ def get_redirect_field_name(self): return self.redirect_field_name @@ -19,11 +51,11 @@ def get_default_redirect_to(self): def get_redirect_to(self, default=None): redirect_to = self.request.REQUEST.get(self.get_redirect_field_name(), '') if not redirect_to and default is not None: return default netloc = urlparse.urlparse(redirect_to)[1] if netloc and netloc != self.request.get_host(): # Don't allow redirection to a different host. return '' if default is None else default @@ -35,7 +67,7 @@ def get_success_url(self): return self.get_redirect_to(default) class LoginView(RedirectToMixin, CurrentAppMixin, generic.FormView): """ Displays the login form and handles the login action. """ @@ -85,7 +117,7 @@ def get_context_data(self, **kwargs): return ctx class LogoutView(RedirectToMixin, CurrentAppMixin, generic.TemplateView): """ Logs out the user and displays 'You are logged out' message. """ @@ -132,25 +164,25 @@ def next_page(self): def login(request, template_name=None, redirect_field_name=None, authentication_form=None, current_app=None, extra_context=None): """ Backwards Compatibility Shim for login -> LoginView """ kwargs = {} if template_name is not None: kwargs["template_name"] = template_name if redirect_field_name is not None: kwargs["redirect_field_name"] = redirect_field_name if authentication_form is not None: kwargs["form_class"] = authentication_form if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context view = LoginView.as_view(**kwargs) return view(request) def logout(request, next_page=None, template_name=None, redirect_field_name=None, current_app=None, extra_context=None): @@ -170,8 +202,8 @@ def logout(request, next_page=None, template_name=None, if extra_context is not None: kwargs["extra_context"] = extra_context view = Logout.as_view(**kwargs) return view(request) def logout_then_login(request, login_url=None, current_app=None, extra_context=None): """ @@ -213,18 +245,22 @@ def redirect_to_login(next, login_url=None, class PasswordResetView(CurrentAppMixin, generic.FormView): """ Ask for the user's email address and send a message containing a token allowing to reset the user's password. """ template_name = "registration/password_reset_form.html" form_class = PasswordResetForm success_url = reverse_lazy('django.contrib.auth.views.password_reset_done') is_admin_site=False email_template_name = "registration/password_reset_email.html" subject_template_name = "registration/password_reset_subject.txt" token_generator = default_token_generator from_email = None current_app = None extra_context = None def form_valid(self, form): opts = { 'use_https': self.request.is_secure(), @@ -282,11 +318,14 @@ def password_reset(request, is_admin_site=None, template_name=None, return password_reset(request) class PasswordResetDoneView(CurrentAppMixin, generic.TemplateView): """ Show a confirmation message that a password reset email has been sent. """ template_name = "registration/password_reset_done.html" current_app = None extra_context = None def get_context_data(self): return self.extra_context # TODO: does this work? @@ -296,14 +335,14 @@ def password_reset_done(request, template_name=None, current_app=None, Backwards Compatibility Shim for password_reset_done -> PassworResetDoneView """ kwargs = {} if template_name is not None: kwargs["template_name"] = template_name if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context password_reset_done = PasswordResetDoneView.as_view(**kwargs) return password_reset_done(request) @@ -313,9 +352,12 @@ class PasswordResetConfirmView(CurrentAppMixin, generic.UpdateView): # In this CBV, form.user is a User instance if the token matches the uidb36, # even in the GET request, as opposed to the old view where form.user was # only set in POST). """ Check that the given token is valid then prompt the user for a new pasword. """ template_name = "registration/password_reset_confirm.html" form_class = SetPasswordForm success_url = reverse_lazy('django.contrib.auth.views.password_reset_complete') token_generator = default_token_generator current_app = None @@ -341,7 +383,7 @@ def form_valid(self, form): if self.object is None: return self.form_invalid(form) return super(PasswordResetConfirmView, self).form_valid(form) def get_context_data(self, **kwargs): context = super(PasswordResetConfirmView, self).get_context_data(**kwargs) context.update({ @@ -365,9 +407,9 @@ def password_reset_confirm(request, uidb36=None, token=None, Backwards Compatibility Shim for password_reset_confirm -> PassworResetConfirmView """ assert uidb36 is not None and token is not None # checked by URLconf kwargs = {} if template_name is not None: kwargs["template_name"] = template_name if token_generator is not None: @@ -380,17 +422,20 @@ def password_reset_confirm(request, uidb36=None, token=None, kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context password_reset_confirm = PasswordResetConfirmView.as_view(**kwargs) return password_reset_confirm(request, uidb36=uidb36, token=token) class PasswordResetComplete(CurrentAppMixin, generic.TemplateView): """ Show a confirmation message that the user's password has been reset. """ template_name = "registration/password_reset_complete.html" current_app = None extra_context = None def get_context_data(self, **kwargs): context = super(PasswordResetComplete, self).get_context_data(**kwargs) context['login_url'] = settings.LOGIN_URL @@ -418,13 +463,17 @@ def password_reset_complete(request, template_name=None, current_app=None, class PasswordChangeView(CurrentAppMixin, generic.UpdateView): """ Prompt the logged-in user for their old password and a new one and change the password if the old password is valid. """ template_name = "registration/password_change_form.html" success_url = reverse_lazy('django.contrib.auth.views.password_change_done') form_class = PasswordChangeForm current_app = None extra_context = None def get_object(self, queryset=None): return self.request.user @@ -464,11 +513,14 @@ def password_change(request, template_name=None, post_change_redirect=None, class PasswordChangeDoneView(CurrentAppMixin, generic.TemplateView): """ Show a confirmation message that the user's password has been changed. """ template_name = "registration/password_change_done.html" current_app = None extra_context = None def get_context_data(self, **kwargs): context = super(PasswordChangeDoneView, self).get_context_data(**kwargs) if self.extra_context: -
bmispelon revised this gist
Feb 17, 2012 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,4 @@ # See https://code.djangoproject.com/ticket/17209 class CurrentAppMixin(object): def render_to_response(self, context, **response_kwargs): return self.response_class( -
bmispelon created this gist
Feb 17, 2012 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,497 @@ class CurrentAppMixin(object): def render_to_response(self, context, **response_kwargs): return self.response_class( request=self.request, template=self.get_template_names(), context=context, current_app=self.current_app. **response_kwargs ) class RedirectToMixin(object): def get_redirect_field_name(self): return self.redirect_field_name def get_default_redirect_to(self): return self.default_redirect_to def get_redirect_to(self, default=None): redirect_to = self.request.REQUEST.get(self.get_redirect_field_name(), '') netloc = urlparse.urlparse(redirect_to)[1] if not redirect_to and default is not None: return default if netloc and netloc != self.request.get_host(): # Don't allow redirection to a different host. return '' if default is None else default return redirect_to def get_success_url(self): default = self.get_default_redirect_to() return self.get_redirect_to(default) class LoginView(RedirectToMixin, CurrentAppMixin, FormView): """ Displays the login form and handles the login action. """ form_class = AuthenticationForm redirect_field_name = REDIRECT_FIELD_NAME template_name = 'registration/login.html' current_app = None extra_context = None default_redirect_to = settings.LOGIN_REDIRECT_URL @method_decorator(sensitive_post_parameters()) @method_decorator(csrf_protect) @method_decorator(never_cache) def dispatch(self, request, *args, **kwargs): request.session.set_test_cookie() return super(LoginView, self).dispatch(request, *args, **kwargs) def get_form_kwargs(self): kwargs = super(LoginView, self).get_form_kwargs() kwargs.update({"request": self.request}) return kwargs def form_valid(self, form): auth_login(self.request, form.get_user()) if self.request.session.test_cookie_worked(): self.request.session.delete_test_cookie() return super(LoginView, self).form_valid(form) def get_context_data(self, **kwargs): ctx = super(LoginView, self).get_context_data(**kwargs) current_site = get_current_site(self.request) ctx.update({ self.get_redirect_field_name(): self.get_success_url(), "site": current_site, "site_name": current_site.name, }) if self.extra_context is not None: ctx.update(self.extra_context) return ctx class LogoutView(RedirectToMixin, CurrentAppMixin, TemplateView): """ Logs out the user and displays 'You are logged out' message. """ redirect_field_name = REDIRECT_FIELD_NAME template_name='registration/logged_out.html' next_page = None current_app = None extra_context = None def get_context_data(self, **kwargs): context = super(LogoutView, self).get_context_data(**kwargs) context.update({ 'site': current_site, 'site_name': current_site.name, 'title': _('Logged out') }) if self.extra_context is not None: context.update(self.extra_context) return context def dispatch(self, request, *args, **kwargs): # TODO: GET, POST, ... ? auth_logout(request) redirect_to = self.get_success_url() if redirect_to: return HttpResponseRedirect(redirect_to) if self.next_page is None: context = self.get_context_data() return self.render_to_response(context) else: return HttpResponseRedirect(self.next_page or self.request.path) class LogoutThenLoginView(LogoutView): """ Logs out the user if he is logged in. Then redirects to the log-in page. """ login_url = None @property def next_page(self): return self.login_url or settings.LOGIN_URL def login(request, template_name=None, redirect_field_name=None, authentication_form=None, current_app=None, extra_context=None, *args, **kwargs): """ Backwards Compatibility Shim for login -> LoginView """ view_kwargs = {} if template_name is not None: view_kwargs["template_name"] = template_name if redirect_field_name is not None: view_kwargs["redirect_field_name"] = redirect_field_name if authentication_form is not None: view_kwargs["form_class"] = authentication_form if current_app is not None: view_kwargs["current_app"] = current_app if extra_context is not None: view_kwargs["extra_context"] = extra_context login_view = LoginView.as_view(**view_kwargs) return login_view(request, *args, **kwargs) def logout(request, next_page=None, template_name=None, redirect_field_name=None, current_app=None, extra_context=None): """ Backwards Compatibility Shim for logout -> LogoutView """ kwargs = {} if next_page is not None: kwargs["next_page"] = next_page if template_name is not None: kwargs["template_name"] = template_name if redirect_field_name is not None: kwargs["redirect_field_name"] = redirect_field_name if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context logout_view = Logout.as_view(**kwargs) return logout_view(request) def logout_then_login(request, login_url=None, current_app=None, extra_context=None): """ Backwards Compatibility Shim for logout -> LogoutView """ kwargs = {} if next_page is not None: kwargs["login_url"] = login_url if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context view = LogoutThenLoginView.as_view(**kwargs) return view(request) def redirect_to_login(next, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME): """ Redirects the user to the login page, passing the given 'next' page """ if not login_url: login_url = settings.LOGIN_URL login_url_parts = list(urlparse.urlparse(login_url)) if redirect_field_name: querystring = QueryDict(login_url_parts[4], mutable=True) querystring[redirect_field_name] = next login_url_parts[4] = querystring.urlencode(safe='/') return HttpResponseRedirect(urlparse.urlunparse(login_url_parts)) # 4 views for password reset: # - password_reset sends the mail # - password_reset_done shows a success message for the above # - password_reset_confirm checks the link the user clicked and # prompts for a new password # - password_reset_complete shows a success message for the above class PasswordResetView(CurrentAppMixin, generic.FormView): template_name = "registration/password_reset_form.html" form_class = PasswordResetForm success_url = reverse_lazy('django.contrib.auth.views.password_reset_done') is_admin_site=False email_template_name = "registration/password_reset_email.html" subject_template_name = "registration/password_reset_subject.txt" token_generator = default_token_generator from_email = None current_app = None extra_context = None def form_valid(self, form): opts = { 'use_https': self.request.is_secure(), 'token_generator': self.token_generator, 'from_email': self.from_email, 'email_template_name': self.email_template_name, 'subject_template_name': self.subject_template_name, 'request': self.request, } if is_admin_site: opts['domain_override'] = self.request.META['HTTP_HOST'] form.save(**opts) return super(PasswordResetView, self).form_valid(form) def get_context_data(self, **kwargs): context = super(PasswordResetView, self).get_context_data(**kwargs) if self.extra_context is not None: context.update(self.extra_context) return context @method_decorator(csrf_protect) def dispatch(self, request, *args, **kwargs): return super(PasswordResetView, self).dispatch(request, *args, **kwargs) def password_reset(request, is_admin_site=None, template_name=None, email_template_name=None, subject_template_name=None, password_reset_form=None, token_generator=None, post_reset_redirect=None, from_email=None, current_app=None, extra_context=None): """ Backwards Compatibility Shim for password_reset -> PassworResetView """ kwargs = {} if is_admin_site is not None: kwargs["is_admin_site"] = is_admin_site if template_name is not None: kwargs["template_name"] = template_name if email_template_name is not None: kwargs["email_template_name"] = email_template_name if password_reset_form is not None: kwargs["form_class"] = password_reset_form if token_generator is not None: kwargs["token_generator"] = token_generator if post_reset_redirect is not None: kwargs["success_url"] = post_reset_redirect if from_email is not None: kwargs["from_email"] = from_email if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context password_reset = PasswordResetView.as_view(**kwargs) return password_reset(request) class PasswordResetDoneView(CurrentAppMixin, generic.TemplateView): template_name = "registration/password_reset_done.html" current_app = None extra_context = None def get_context_data(self): return self.extra_context # TODO: does this work? def password_reset_done(request, template_name=None, current_app=None, extra_context=None): """ Backwards Compatibility Shim for password_reset_done -> PassworResetDoneView """ kwargs = {} if template_name is not None: kwargs["template_name"] = template_name if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context password_reset_done = PasswordResetDoneView.as_view(**kwargs) return password_reset_done(request) class PasswordResetConfirmView(CurrentAppMixin, generic.UpdateView): # XXX: This one might have some backwards-compatibility issues in some corner cases. # In this CBV, form.user is a User instance if the token matches the uidb36, # even in the GET request, as opposed to the old view where form.user was # only set in POST). template_name = "registration/password_reset_confirm.html" form_class = SetPasswordForm success_url = reverse('django.contrib.auth.views.password_reset_complete') token_generator = default_token_generator current_app = None extra_context = None def get_object(self, queryset=None): try: pk = base36_to_int(self.kwargs['uidb36']) user = User.objects.get(pk=pk) except (ValueError, User.DoesNotExist): return None if not self.token_generator.check_token(user, self.kwargs['token']): return None return user def get_form_kwargs(self): kwargs = super(PasswordResetConfirmView, self).get_form_kwargs() kwargs['user'] = kwargs.pop('instance') return kwargs def form_valid(self, form): if self.object is None: return self.form_invalid(form) return super(PasswordResetConfirmView, self).form_valid(form) def get_context_data(self, **kwargs): context = super(PasswordResetConfirmView, self).get_context_data(**kwargs) context.update({ 'validlink': self.object is not None }) if self.extra_context: context.update(self.extra_context) return context # Doesn't need csrf_protect since no-one can guess the URL @method_decorator(sensitive_post_parameters()) @method_decorator(never_cache) def dispatch(self, request, *args, **kwargs): return super(PasswordResetView, self).dispatch(request, *args, **kwargs) def password_reset_confirm(request, uidb36=None, token=None, template_name=None, token_generator=None, set_password_form=None, post_reset_redirect=None, current_app=None, extra_context=None): """ Backwards Compatibility Shim for password_reset_confirm -> PassworResetConfirmView """ assert uidb36 is not None and token is not None # checked by URLconf kwargs = {} if template_name is not None: kwargs["template_name"] = template_name if token_generator is not None: kwargs["token_generator"] = token_generator if set_password_form is not None: kwargs["form_class"] = set_password_form if post_reset_redirect is not None: kwargs["success_url"] = post_reset_redirect if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context password_reset_confirm = PasswordResetConfirmView.as_view(**kwargs) return password_reset_confirm(request, uidb36=uidb36, token=token) class PasswordResetComplete(CurrentAppMixin, generic.TemplateView): template_name = "registration/password_reset_complete.html" current_app = None extra_context = None def get_context_data(self, **kwargs): context = super(PasswordResetComplete, self).get_context_data(**kwargs) context['login_url'] = settings.LOGIN_URL if self.extra_context: context.update(self.extra_context) return context def password_reset_complete(request, template_name=None, current_app=None, extra_context=None): """ Backwards Compatibility Shim for password_reset_complete -> PasswordResetComplete """ kwargs = {} if template_name is not None: kwargs["template_name"] = template_name if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context password_reset_complete = PasswordResetComplete.as_view(**kwargs) return password_reset_complete(request) class PasswordChangeView(CurrentAppMixin, generic.UpdateView): template_name = "registration/password_change_form.html" success_url = reverse('django.contrib.auth.views.password_change_done') form_class = PasswordChangeForm current_app = None extra_context = None def get_object(self, queryset=None): return self.request.user def get_form_kwargs(self): kwargs = super(PasswordChangeView, self).get_form_kwargs() kwargs['user'] = kwargs.pop('instance') return kwargs @method_decorator(sensitive_post_parameters()) @method_decorator(csrf_protect) @method_decorator(login_required) def dispatch(self, request, *args, **kwargs): return super(PasswordChangeView, self).dispatch(request, *args, **kwargs) def password_change(request, template_name=None, post_change_redirect=None, password_change_form=None, current_app=None, extra_context=None): """ Backwards Compatibility Shim for password_change -> PasswordChangeView """ kwargs = {} if template_name is not None: kwargs["template_name"] = template_name if post_change_redirect is not None: kwargs["success_url"] = post_change_redirect if password_change_form is not None: kwargs["form_class"] = password_change_form if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context password_change = PasswordChangeView.as_view(**kwargs) return password_change(request) class PasswordChangeDoneView(CurrentAppMixin, generic.TemplateView): template_name = "registration/password_change_done.html" current_app = None extra_context = None def get_context_data(self, **kwargs): context = super(PasswordChangeDoneView, self).get_context_data(**kwargs) if self.extra_context: context.update(self.extra_context) return context @method_decorator(login_required) def dispatch(self, request, *args, **kwargs): return super(PasswordChangeDoneView, self).dispatch(request, *args, **kwargs) def password_change_done(request, template_name=None, post_change_redirect=None, password_change_form=None, current_app=None, extra_context=None): """ Backwards Compatibility Shim for password_change_done -> PasswordChangeDoneView """ kwargs = {} if template_name is not None: kwargs["template_name"] = template_name if current_app is not None: kwargs["current_app"] = current_app if extra_context is not None: kwargs["extra_context"] = extra_context password_change_done = PasswordChangeDone.as_view(**kwargs) return password_change_done(request)