【问题标题】:Passing context to django-registration's views将上下文传递给 django-registration 的视图
【发布时间】:2018-01-02 14:45:44
【问题描述】:

我正在使用 django-registration 和我在 Github 上找到的一组预制模板来执行两步(注册-激活)工作流程 using HMAC

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

“问题”是我无法直接访问这些视图。这就是 django-registration 的重点,您将其路径包含在 urls.py 文件中,一切正常:

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

为这些视图添加上下文的最简单方法是什么?我已经创建并成功passing context to emails in my own views(使用上下文处理器):

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 提供的每个需要发送电子邮件的视图编写单独的视图......

【问题讨论】:

  • 哦 - 我在写完答案后读了最后一段 - 真丢人。这通常是使用 3rd 方库时的缺点。您可以按预期使用站点功能 - 或者为 django-registration 编写一个补丁,允许您通过设置为电子邮件设置额外的上下文数据 - 也许他们喜欢它。
  • 哦,好吧,或者您只需提供一个补丁,该补丁还将请求传递给render_to_string 以进行所有电子邮件模板渲染调用 - 这只是一些更改的行,我想他们会欣赏这一点它不应该有任何副作用。

标签: python django django-registration


【解决方案1】:

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

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')),
    # [...]
]

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

【讨论】:

  • 感谢您的回答!问题是,我想尽可能地干燥,所以我再次尝试利用我在自定义上下文处理器中的请求中设置的全局变量。但是,当我执行context['mysite_name'] = RequestContext(self.request).get('mysite_name') 时,它返回无。 mysite_name 在模板中成功使用,所以我有点不同意为什么这不起作用。
  • 你能提供更多关于你在哪里做这个作业的信息吗?顺便说一句:我已经添加了一些关于 github 问题的信息,我猜你打开了。
  • 我正在一个视图中创建我现在正在使用的 dj RegistrationView 的子类。它看起来与您的答案中的相同,除了我上面评论中的那一行。不过,self.request 似乎在工作流程的这个阶段不包含变量......?还是另一种请求?
  • 所以我设法通过执行以下分配来做到这一点:context['req'] = get_website_name(self.request) 其中get_website_name 是我的processors.py 文件中的函数,然后我在电子邮件模板中访问{{req.mysite_name}}。这并不理想,因为它不是跨模板的完全相同相同的引用,但这确实意味着更改函数中的变量将相应地更新所有引用。哦,好吧。
  • 我根据您的反馈稍微调整了以上内容,您可以试一试吗?请求的内容应该与它无关。使用 RequestContext 应该只确保上下文处理器被触发。
【解决方案2】:

这就是我最终做的事情,感谢 dahren 的回答发给我的方向:

# 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}}。但这确实具有我的目标:如果函数中的变量发生变化,所有模板都会相应地更新。

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

【讨论】:

    猜你喜欢
    • 2013-12-05
    • 2020-06-01
    • 2016-01-06
    • 2016-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多