【问题标题】:Activation link to allow committing to database in Django允许在 Django 中提交到数据库的激活链接
【发布时间】:2014-01-31 18:51:22
【问题描述】:

所以我有一个应用程序,它采用表单,并向某人发送电子邮件地址,但我想要一种方法将 Django 生成的激活 URL 粘贴到该电子邮件中,而不是将表单数据提交给数据库,直到单击该激活链接。有没有办法做到这一点?

【问题讨论】:

    标签: database django views activation


    【解决方案1】:

    根据我第一个答案的 cmets,这是一个更适合您需求的重新设计。

    创建一个模型,例如ServiceHours,旁边是您要收集的数据(完成时间、主管电子邮件、...),具有以下字段:

    activation_key=models.CharField(_('activation key'), max_length=40, null=True, blank=True)
    validated=models.BooleanField(default=False)
    

    我建议在模型中添加post_save signal,这样每当创建新的 ServiceHours 实例(通过保存表单)时,就会向主管发送电子邮件。

    # Add this to your models file
    # Required imports 
    
    from django.db.models.signals import post_save
    from django.utils.hashcompat import sha_constructor
    import random
    
    def _create_and_send_activation_key(sender, instance, created, **kwargs):
        if created:    # Only do this for newly created instances.
            salt = sha_constructor(str(random.random())).hexdigest()[:5]        
            # Set activation key based on supervisor email 
            instance.activation_key = sha_constructor(salt+instance.supervisor_email).hexdigest()
            instance.save()
            # Create email
            subject = "Please validate"
            # In the message, you can use the data the volunteer has entered by accessing 
            # the instance properties
            message = "Include instance hours, volunteer's name etc\n"
            # Insert the activation key & link
            messsage += "Click here: %s" % (reverse("validate_hours", kwargs={'id': instance.id, 'activation_key':instance.activation_key})
    
            # Send the mail
            from django.core.mail import send_mail # Move this import to top of your file ofcourse, I've just put it here to show what module you need
            send_mail(subject, message, sender, recipients)
    
    post_save.connect(_create_and_send_activation_key, sender=ServiceHours)
    

    定义一个视图以根据激活密钥验证服务时间

      # in views.py
      def validate_hours(request, id, activation_key):
          # find the corresponding ServiceHours instance
          service_hours = ServiceHours.objects.get(id=id, activation_key=activation_key)
          service_hours.validated = True
          service_hours.save()
    

    在您的 urls.py 中,为您的 validate_hours 视图定义一个 url:

    urlpatterns += patterns('',
        url(r'^validate-hours/(?P<id>[0-9]+)/(?P<activation_key>\w+)', validate_hours, name='validate_hours'),
    

    这一切都在我的脑海中,所以请原谅任何错误。我希望您了解该过程的要点,并可以根据您的确切需求进行扩展。

    【讨论】:

    • 仅供参考:我已经使用了 django-registration 的部分代码来创建activation_key,信用到期:)
    • 一切似乎都应该工作,谢谢 :) 唯一的问题是 django.utils.hashcompat 在 Django 1.6 中已被弃用。任何其他库或解决方案可能在您的答案没有太大变化的情况下工作?
    • 显然hashlib 现在是标准。您可能会更改由activation_key = hashlib.sha224(salt+instance.supervisor_email).hexdigest() 之类的东西生成activation_key 的行。请注意,这是未经测试的,您可能希望增加模型的 validation_key 字段的 max_length。
    • 当我尝试点击激活链接时,页面给了我一个 TypeError 声明 validate_hours() got an unexpected keyword argument 'activation_key'。关于为什么的任何想法?我是否应该也将 validation_keyvalidated 字段添加到我的 ModelForm 中?
    • 哦,对了,你的视图应该得到 activation_keyid 作为它的参数 -> def validate_hours(request, id, activation_key)。您可以将代码中的 request.GET.get('id') 进一步替换为 id 变量(activation_key 也是如此)。
    【解决方案2】:

    您可能想要设置/取消设置用户的is_active 标志。

    概念上:

    • 当用户注册成功时,一定要设置flag为False;
    • 自动生成与用户 ID 相关联的唯一字符串,并通过电子邮件发送激活 URL;
    • 在激活视图中,将密钥分解为用户ID,并将is_active标志设置为True;
    • 在您的登录视图中,检查尝试登录的用户的 is_active 是否为 True。

    那么您将确保登录的用户拥有一个确认的电子邮件地址。

    Django 文档中的页面on user authentication 提供了所有必要的信息。对于示例登录视图,"How to log a user in" 章节有一个。

    如果您更喜欢使用可重复使用的应用,django-registration 可能完全符合您的需求。

    (回复后补充:)为什么不将数据提交到数据库?让未激活的用户驻留在数据库中的“浪费”并不超过您实施不将数据提交到数据库的解决方案所需的努力。此外,了解未激活用户的数量(并采取相应行动)可能会更有趣。

    【讨论】:

    • 我试图找到一种方法来获取上述场景并将其转移到我的需求中,但问题是,这不是为了注册新用户。我明白了,只是我想使用某种推荐系统来计算某人所做的社区服务小时数,用户输入主管的姓名和电子邮件地址以及人数他们在表格中完成的小时数,并向主管发送电子邮件,要求单击激活链接以确认用户已完成这些小时数,从而将它们提交到数据库。
    • 我仍然会将志愿者的数据提交到数据库中,并在模型中添加一个标志以供主管验证(默认=False,验证时设置为 True)。它使跟踪和追溯历史变得更加容易。但是您是在寻找发送邮件、创建(唯一)验证链接的方法,还是您正在苦苦挣扎的数据库设置?
    • 谢谢。你能更详细地解释一下吗?这不是数据库设置,而是以前的两个选项,尤其是创建一个唯一的验证链接。另外,我尝试过使用 django-generic-confirmation,但它已经过时并且不适用于 Django 1.6。
    猜你喜欢
    • 2019-08-06
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    • 2017-10-30
    • 2016-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多