【问题标题】:How do I 'monkey patch' or override User.is_authenticated()? Creates issues with using django-lazysignup我如何“猴子补丁”或覆盖 User.is_authenticated()?使用 django-lazysignup 产生问题
【发布时间】:2015-09-24 05:01:35
【问题描述】:

我安装了 django-lazysignup 并且现在正面临 User.is_authenticated() 返回 True 的挑战,因为不是实际上经过身份验证的用户,而是惰性注册用户。我可以使用自己的函数更新代码中对 User.is_authenticated() 的任何检查。然而,像 django-allauth 这样的其他包,检查这个方法来确定用户是否已经登录,并从尝试到达登录页面重定向。

class RedirectAuthenticatedUserMixin(object):
    def dispatch(self, request, *args, **kwargs):
        self.request = request
        if request.user.is_authenticated():
            redirect_to = self.get_authenticated_redirect_url()
            response = HttpResponseRedirect(redirect_to)
            return _ajax_response(request, response)
...

是否有不需要在我包含的每个包中替换 is_authenticated() 的建议?似乎他们中的大多数人都希望它以一种特定的方式运行,而 django-lazysignup 完全颠覆了它。我可以用新的 is_authenticated() 方法修补 User 模型吗?如果可能,我将在哪里执行此操作以将其附加到页面请求?

【问题讨论】:

    标签: python django django-allauth monkeypatching


    【解决方案1】:

    您正在使用的django-lazysignup 允许您提供自定义的 LazyUser 类 (here)。您需要做的就是编写lazysignup.models.LazyUser 的子类,定义is_authenticated 方法并将其设置为settings.LAZYSIGNUP_USER_MODEL

    但这并不是你的麻烦的结束。很多 django 应用程序 假设经过身份验证的用户具有一些属性。主要是is_staffis_superuserpermissionsgroups。首先,django.contrib.admin 需要他们检查它是否可以让用户进入以及向他展示什么。看看django.contrib.auth.models.AnonymousUser 如何模拟它们并复制它。备注:看看AnonymousUser 如何不是继承任何用户类或db.Model。提供的用户类只需要嘎嘎。

    【讨论】:

    • 感谢 Łukasz,这是猴子修补的更好解决方案。我会试一试并发布任何更新。
    • 我得到了 LazyUser 的子类化,但 settings.LAZYSIGNUP_USER_MODEL 似乎严格用于引用自定义用户模型,而不是自定义 LazyUser 模型。由于此处的所有警告,我避免使用自定义用户模型:docs.djangoproject.com/en/1.8/topics/auth/customizing/…
    【解决方案2】:

    最终只需要替换对 User.is_authenticated() 的所有调用。

    为了防止 django-allauth 从登录页面重定向惰性用户,最终看起来像这样:

    from allauth.account.views import AjaxCapableProcessFormViewMixin
    
    def _ajax_response(request, response, form=None):
        if request.is_ajax():
            if (isinstance(response, HttpResponseRedirect)
                or isinstance(response, HttpResponsePermanentRedirect)):
                redirect_to = response['Location']
            else:
                redirect_to = None
            response = get_adapter().ajax_response(request,
                                               response,
                                               form=form,
                                               redirect_to=redirect_to)
        return response
    
    
    class RedirectUserWithAccountMixin(object):
        def dispatch(self, request, *args, **kwargs):
            self.request = request
            if user_has_account(request.user):
                redirect_to = self.get_authenticated_redirect_url()
                response = HttpResponseRedirect(redirect_to)
                return _ajax_response(request, response)
            else:
                response = super(RedirectUserWithAccountMixin,
                                 self).dispatch(request,
                                                *args,
                                                **kwargs)
            return response
    
        def get_authenticated_redirect_url(self):
            redirect_field_name = self.redirect_field_name
            return get_login_redirect_url(self.request,
                                          url=self.get_success_url(),
                                          redirect_field_name=redirect_field_name)
    
    class LoginView(RedirectUserWithAccountMixin,
                AjaxCapableProcessFormViewMixin,
                FormView):
    ...
    

    user_has_account() 是我自己检查用户是否实际登录的方法。

    【讨论】:

      猜你喜欢
      • 2010-11-26
      • 2017-10-05
      • 1970-01-01
      • 2011-10-06
      • 2012-07-26
      • 2011-01-14
      • 2015-08-21
      • 2012-08-10
      • 2019-10-27
      相关资源
      最近更新 更多