Продолжая искать решения этой проблемы, я пролистываю эту публикацию на простом лучше, чем сложном.
Обратитесь к оригинальной статье за объяснениями большинства из них, они намного лучше, чем я. Хотя есть некоторые различия.
Я использую Django 2, а не 1.x, поскольку формат url указывает, что это решение.
Также у меня есть 2 приложения, 1 (VSL), для которых предназначено веб-приложение, включая отправку уведомлений по электронной почте; другой (пользователи) для управления пользователями.
Я расширил стандартную пользовательскую модель Django с помощью OptIn , для уведомлений и тому подобного, в models.py в пространстве приложения пользователя
class OptIn(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='opt_in')
recieve_coms = models.BooleanField(default=True)
Следуя приведенному выше примеру, я создал tokens.py в пространстве приложения VSL
class ComsOptTokenGenerator(PasswordResetTokenGenerator):
def _make_hash_value(self, user, timestamp):
return (
six.text_type(user.pk) + six.text_type(timestamp) +
six.text_type(user.opt_in.recieve_coms)
)
coms_opt_token = ComsOptTokenGenerator()
Это импортируется в views.py в пространстве приложения VSL (или там, где его необходимо использовать).
from .tokens import coms_opt_token
Поскольку я использую Django 2, URL отличается от примера
path('unsubscribe/<uidb64>/<token>/', views.unsubscribe, name='unsubscribe')
Я не могу использовать views.unsubscribe.as_view (), как показано в примере, потому что это вызывает AttributeError: тип объекта «Отписаться» не имеет атрибута «as_view» .
Представление об отмене подписки находится в файле views.py в пользователи область приложения
Сначала вам нужно будет импортировать следующее
from django.utils.encoding import force_text
from django.utils.http import urlsafe_base64_decode
from VSL.tokens import coms_opt_token
Сам вид:
def unsubscribe(request, uidb64, token):
try:
uid = urlsafe_base64_decode(uidb64).decode()
user = User.objects.get(pk=uid)
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
if user is not None and coms_opt_token.check_token(user, token):
comsoptin = OptIn.objects.get(user=request.user)
comsoptin.recieve_coms = False
comsoptin.save()
return render(request, 'users/unsubscribe.html')
else:
return render(request, 'registration/invalid.html')
Я не могу использовать отписаться (Просмотр), как показано в примере, потому что это вызывает NameError: имя 'Просмотр' не определено .
И обратите внимание, что uid = urlsafe_base64_decode (uidb64) .decode () отличается от примера из-за использования Django 2.
Это то, что приведенное выше учебное пособие занимает у меня.
Вернуться к views.py в VSL У меня есть функция для отправки электронного письма при создании нового события
Первый важный импорт
from django.utils.http import urlsafe_base64_encode
from django.utils.encoding import force_bytes
from .tokens import coms_opt_token
Функция
def notify_new_event(request, new_event):
event = new_event
users = User.objects.filter(opt_in__recieve_coms=True)
site_name = get_current_site(request).name
for user in users:
if user.is_active and user != request.user and user.last_login != None:
with open(settings.BASE_DIR + "/VSL/templates/notifications/new_event_email.txt") as t:
ne_message = t.read()
token = coms_opt_token.make_token(user)
uid = urlsafe_base64_encode(force_bytes(user.pk)).decode()
message = EmailMultiAlternatives(
subject = str(site_name) + str(event.title) + " event has been created.",
from_email = settings.EMAIL_HOST_USER,
to = [user.email],
)
context = {'request':request, 'user':user, 'event':event, 'site_name':site_name, 'token':token, 'uid':uid}
html_template = get_template("notifications/new_event_email.html").render(context)
message.attach_alternative(html_template, "text/html")
message.send()
Важными битами здесь являются token = coms_opt_token и uid = urlsafe_base64_encode (force_bytes (user.pk)). Decode () .
coms_opt_token генерирует наш безопасный одноразовый токен, и uid хэширует пользователя для безопасности.
А ссылка для отмены подписки в шаблоне электронной почты
href="{{ protocol }}://{{ domain }}{% url 'users:unsubscribe' uidb64=uid token=token %}"