Django - обратный for с аргументами в виде ключевых слов не найден

Я создаю веб-приложение, в котором пользователи могут оставлять отзывы о моей компании. После оставления отзыва мне отправляется электронное письмо с данными отзыва и ссылкой, по которой я могу легко нажать, чтобы одобрить отзыв и показать его на странице для всех пользователей. Для этого я использовал uuid для создания токена для каждого созданного отзыва. Я знаю, что токен передается в мой шаблон review_email.html, потому что я могу отправить токен в виде html-текста в письме, но по какой-то причине я продолжаю получать эту ошибку с тегом url: Reverse for 'approve_review' with keyword arguments '{'token': ''}' not found. 1 pattern(s) tried: ['reviews/approve/(?P[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\Z']

EDIT: Ошибка возникает из-за тега url в файле review_email.html

views.py:

from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse
from django.urls import reverse
from .models import Review
from .forms import ReviewForm
from django.core.mail import send_mail
from django.conf import settings
from django.template.loader import render_to_string
import os
import uuid
# Create your views here.

def submit_review(request):
    if request.method == 'POST':
        form = ReviewForm(request.POST)
        if form.is_valid():
            review = form.save(commit=False)
            review.token = uuid.uuid4()
            review.save()
            print(review.token)
            send_review_email(review)
            return render(request, 'reviews/thank_you.html')
        
    else:
        form = ReviewForm()
    return render(request, 'reviews/submit_review.html', {'form': form})

def send_review_email(review):
    send_mail('New Review Submitted', 'A new review has been submitted.', os.getenv('EMAIL_HOST_USER'),
            ['testemail123@hotmail.com'],
            html_message=render_to_string('reviews/review_email.html', context = {
                'name': review.name,
                'street': review.street,
                'city': review.city,
                'state': review.state,
                'zip_code': review.zip_code,
                'phone_number': review.phone_number,
                'review_text': review.review_text,
                'token': review.token
            }))

def approve_review(request, token):
    review = get_object_or_404(Review, token=token)
    review.approved = True
    review.save()
    return redirect('reviews:review_list')

review_email.html:

<!DOCTYPE html>
<html>
<head>
    <title>New Review Submitted</title>
</head>
<body>
    <h1>New Review Submitted</h1>
    <p><strong>Name</strong> {{ name }}</p>
    <p><strong>Street:</strong> {{ street }}</p>
    <p><strong>City:</strong> {{ city }}</p>
    <p><strong>State:</strong> {{ state }}</p>
    <p><strong>ZIP Code:</strong> {{ zip_code }}</p>
    <p><strong>Phone Number:</strong> {{ phone_number }}</p>
    <p><strong>Review Text:</strong> {{ review_text }}</p>
    <p><strong>Token:</strong> {{ token }}</p>
    <p><a href="{% url 'reviews:approve_review' token=review.token %}"></a></p>
    
</body>
</html>

models.py:

from django.db import models
from django.utils import timezone
import uuid

# Create your models here.

class Review(models.Model):
    name = models.CharField(max_length=100)
    street = models.CharField(max_length=200, null=True)
    city = models.CharField(max_length=100, null=True)
    state = models.CharField(max_length=2, default='NY')
    zip_code = models.CharField(max_length=10, null=True, verbose_name='Zip Code')
    phone_number = models.CharField(max_length=15, null=True, verbose_name='Phone Number')
    review_text = models.TextField(verbose_name='Review')
    created_at = models.DateTimeField(default=timezone.now())
    approved = models.BooleanField(default=False)
    token = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)

    def __str__(self):
        return self.name

urls.py:

from django.urls import path
from . import views
from .views import approve_review

app_name = 'reviews'

urlpatterns = [
    path('submit/', views.submit_review, name='submit_review'),
    path('thanks/', views.thank_you, name='review_thanks'),
    path('', views.review_list, name='review_list'),
    path('approve/<uuid:token>', views.approve_review, name='approve_review'),
]

Я схожу с ума, пытаясь понять, почему это не работает, пожалуйста, помогите :)

Я пробовал менять директории review_email, изменять способ передачи контекста из view в html render message и т.д.

удалите review.token = uuid.uuid4() в представлении и установите primary_key=True для токена.

Вернуться на верх