将上下文传递给 django-registration 的视图

Passing context to django-registration's views

我正在使用 django-registration with a set of premade templates I found on Github for doing a two-step (registration-activation) workflow using HMAC

我想将全局变量(在上下文处理器中定义)(如我的网站名称)传递给 django-registration 发送的电子邮件。例如,发送给新注册者的激活电子邮件,或密码更改。

"problem" 是我无法直接访问这些视图。这有点像 django 注册的要点,您将其路径包含在 urls.py 文件中,一切正常:

urlpatterns = [
    url(r'^', include('core.urls')),
    url(r'^admin/', admin.site.urls),
    url(r'^accounts/', include('registration.backends.hmac.urls')),
]

向这些视图添加上下文的最省力方法是什么?我已经创建并成功 (使用上下文处理器):

def send_some_email_view(request):

    msg_plain = render_to_string('email_change_email.txt', context, request=request)
   msg_html = render_to_string('email_change_email.html', context, request=request)

但是我没有创建的视图呢?

编辑:所以我取得了一些进展,找到了 django-registration 的注册视图,以及其中的这个方法:

def send_activation_email(self, user):
    """
    Send the activation email. The activation key is simply the
    username, signed using TimestampSigner.

    """
    activation_key = self.get_activation_key(user)
    context = self.get_email_context(activation_key)
    context.update({
        'user': user
    })
    subject = render_to_string(self.email_subject_template,
                               context)
    # Force subject to a single line to avoid header-injection
    # issues.
    subject = ''.join(subject.splitlines())
    message = render_to_string(self.email_body_template,
                               context)
    user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)

我不想在源代码中覆盖它,因为那样会阻止我更新。所以现在问题变成了:我唯一的出路是编写一个子类化该视图并覆盖该方法的视图吗?这意味着我正在为需要发送电子邮件的 django-registartion 提供的每个视图编写单独的视图...

首先根据供应商视图创建您自己的视图并覆盖您想要的方法:

from registration.backends.hmac.views import RegistrationView


class CustomRegistrationView(RegistrationView):
    def get_email_context(self, user):
        context = super().get_email_context(user)
        return RequestContext(self.request, context)

不如看看 registration.backends.hmac.urls.py (source)。他们只是在那里定义了一堆网址。

您可以轻松地只覆盖其中一个,方法是在添加您自己的之前您从应用程序中添加一个。

from yourapp import views


urlpatterns = [
    # [...]
    url(r'^accounts/register/$', views.CustomRegistrationView.as_view(), name='registration_register'),
    url(r'^accounts/', include('registration.backends.hmac.urls')),
    # [...]
]

在仅更改必要的内容的同时,您还可以深入了解第 3 方应用程序中发生的事情,这始终是一个优势。这适用于大多数第 3 方应用程序,而不仅仅是您当前使用的应用程序。

这就是我最终所做的,感谢 dahrens 的回答将我送到:

# myapp/processors.py
def get_website_name(request):
    website_name = 'ExcitingWebsiteThatsComingSoon'
    return {'mysite_name': website_name}

# some views.py file
from myapp.processors import get_website_name

class RegistrationViewWithContext(RegistrationView):
    def get_email_context(self, user):
        context = super().get_email_context(user)
        context['req'] = get_website_name(self.request)
        return context

基本上,我只是使用我的自定义处理器来注入网站名称。它不像我希望的那样干净:虽然在我的模板中我可以简单地使用 {{ mysite_name}},但在电子邮件模板中我必须使用 {{req.mysite_name}}。但这确实具有我想要的 DRY-ness:如果函数中的变量发生变化,所有模板都会相应更新。

我暂时将我的答案标记为正确,如果有新答案出现,我会相应更新。