Help Needed with View Returning "Invalid Request Method" Error

Hi everyone,

I’m encountering an issue with one of my Django views, and I’m hoping someone can help me troubleshoot it.

When I try to access the URL: https://tout-talent.com/forfait/, the browser or site displays a different page with the message:

{"success": false, "message": "Invalid request method"}

However, on my server and in the debug.log file, I see the following log entry:

"GET /forfait/ HTTP/1.1" 200

indicating a 200 OK HTTP status code. But the template that should normally display is not being rendered.

Here’s the code for the view:


@login_required
def subscribe(request):
    if not hasattr(request.user, 'company'):
        print("Utilisateur non connecté ou sans compagnie associée.")
        return redirect('login')  # Or show an appropriate message

    company = request.user.company
    print(f"Company: {company}")

    active_subscription = None
    try:
        active_subscription = CompanySubscription.objects.get(company=company, is_active=True)
        print(f"Active subscription found: {active_subscription}")
    except CompanySubscription.DoesNotExist:
        print("No active subscription found.")

    if request.method == 'POST':
        form = SubscriptionForm(request.POST)
        if form.is_valid():
            plan = form.cleaned_data['plan']
            print(f"Selected plan: {plan}")

            if plan.name == 'lite':
                print("Redirecting to Lite plan duration view.")
                return redirect('days_duration_for_lite_plan', plan_ref=plan.ref)
            else:
                days = plan.duration_days
                amount = plan.price_per_month if days >= 30 else plan.price_per_day * days
                print(f"Days: {days}, Amount: {amount}")

                if plan.name == 'free':
                    subscription, created = CompanySubscription.objects.get_or_create(
                        company=company,
                        defaults={
                            'plan': plan,
                            'start_date': timezone.now(),
                            'end_date': timezone.now() + timedelta(days=days),
                            'is_active': True,
                        }
                    )

                    if created:
                        print("New free subscription created.")
                    else:
                        subscription.plan = plan
                        subscription.end_date = subscription.calculate_end_date()
                        subscription.is_active = True
                        subscription.save()
                        print("Free subscription updated.")

                    return redirect('mon_forfait')  # Redirect to the user's subscription page

                # If not free, redirect to the payment page
                amount = int(amount)  # Convert amount to integer
                print(f"Redirecting to payment page with amount: {amount}")

                return redirect('payment', company_ref=company.ref, plan_ref=plan.ref, days=days, amount=amount)
        else:
            print("Form is invalid. Errors: ", form.errors)
    else:
        print("GET request received.")
        form = SubscriptionForm()

    # Retrieve subscription plans
    free_plan = SubscriptionPlan.objects.get(name='free')
    lite_plan = SubscriptionPlan.objects.get(name='lite')
    pro_plan = SubscriptionPlan.objects.get(name='pro')

    context = {
        'form': form,
        'active_subscription': active_subscription,
        'free_plan': free_plan,
        'lite_plan': lite_plan,
        'pro_plan': pro_plan,
    }

    return render(request, 'subscribe.html', context)

This is almost certainly a case where the URL is not accessing the view that you think it’s going to access.

To try and debug this, we would need to see your root urls.py file along with the urls.py file for this app, if they are different files.

Hello,

Thank you for taking the time to respond to my question. Your help is greatly appreciated !

Here is the URL mapping in my urls.py file for the view :

path('forfait/', views.subscribe, name='subscribe'),

My root urls.py file includes the application URLs as follows:

 path('', include('tout_talent.urls')),

Please show the complete urls.py files.

Project urls.py file

"""
URL configuration for projet_tout_talent project.

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/4.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('tout_talent.urls')),
    path('tinymce/', include('tinymce.urls')),
    path('ckeditor/', include('ckeditor_uploader.urls')),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

urlpatterns += staticfiles_urlpatterns()

and my app urls.py file :

`from django.contrib import admin
from django.urls import path
from . import views
from django.contrib.auth import views as auth_views
from django.conf import settings
from django.conf.urls.static import static
from django.contrib.staticfiles.storage import staticfiles_storage
from ckeditor_uploader import views as ckeditor_views
from django.conf.urls import handler400, handler403, handler404, handler500
from django.contrib import sitemaps
from django.contrib.sitemaps.views import sitemap
from .sitemaps import JobSitemap, ArticleSitemap

sitemaps = {
‘jobs’: JobSitemap,
‘articles’: ArticleSitemap,
}

handler400 = ‘tout_talent.views.error_400’

handler403 = ‘tout_talent.views.error_403’

handler404 = ‘tout_talent.views.error_404’

handler500 = ‘tout_talent.views.error_500’

urlpatterns = [
path(‘’, views.home, name=‘home’),

    path('register/', views.register, name='register'),
    path('profile/', views.profile, name='profile'),
    path('profile/update/', views.update_profile, name='update_profile'),
    
    path('login/', views.user_login, name='login'),
    path('logout/', views.user_logout, name='user_logout'),

    path('recherche/', views.recherche, name='recherche'),
    path('forfait/', views.subscribe, name='subscribe'),
    path('mon/forfait/', views.mon_forfait, name='mon_forfait'),
    path('upgrade_subscription/', views.upgrade_subscription, name='upgrade_subscription'),
    #path('payment/<int:ref>/<int:days>/<amount>/', views.payment, name='payment'),
    path('payment/<int:company_ref>/<int:plan_ref>/<int:days>/<amount>/', views.payment, name='payment'),
    path('payment_callback/', views.payment_callback, name='payment_callback'),
    path('calculate_amount/', views.calculate_amount, name='calculate_amount'),
    path('payment-success/<int:company_ref>/<int:plan_ref>/', views.payment_success, name='payment_success'),
    path('subscription-detail/', views.subscription_detail, name='subscription_detail'),
    path('days-duration-for-lite-plan/<str:plan_ref>/', views.days_duration_for_lite_plan, name='days_duration_for_lite_plan'),
    
    path('ajouter/formation/', views.formation, name='formation'),
    path('ajouter/experience/', views.experience, name='experience'),
    path('ajouter/certificat/', views.certificat, name='certificat'),
    path('ajouter/portfolio/', views.portfolio, name='portfolio'),

    path('update/portfolio/<int:pk>/', views.update_portfolio, name='update_portfolio'),
    path('update/certificat/<int:pk>/', views.update_certificat, name='update_certificat'),
    path('update/experience/<int:pk>/', views.update_experience, name='update_experience'),
    path('update/formation/<int:pk>/', views.update_formation, name='update_formation'),

    path('formation/delete/<int:pk>/', views.delete_formation, name='delete_formation'),
    path('experience/delete/<int:pk>/', views.delete_experience, name='delete_experience'),
    path('certificat/delete/<int:pk>/', views.delete_certificat, name='delete_certificat'),
    path('portfolio/delete/<int:pk>/', views.delete_portfolio, name='delete_portfolio'),

    path('job/create/', views.create_job, name='create_job'),
    path('my_jobs/', views.job_list, name='job_list'),
    path('gerer/candidatures/', views.manage_job_application, name='manage_job_application'),
    path('job/update/<slug:slug>/<int:ref>/', views.update_job, name='update_job'),

    path('job/delete/<slug:slug>/<int:ref>/', views.delete_job, name='delete_job'),
    path('job/<slug:slug>/<int:ref>/', views.job_detail, name='job_detail'),

    path('company_details/<slug:slug>/<int:ref>/', views.company_details, name='company_details'),

    
    path('offres/', views.jobs, name='jobs'),
    path('jobs/<str:country_name>/', views.jobs_by_country, name='jobs_by_country'),
    path('emploi/<slug:slug>/<int:ref>/postuler/', views.postuler, name='postuler'),
    path('candidate/<int:ref>/', views.voir_profile, name='voir_profile'),

    path('job/<int:job_ref>/applications/', views.detail_job_application, name='detail_job_application'),
    path('update-status/<int:ref>/<int:job_ref>/', views.update_application_status, name='update_application_status'),

    path('mes-candidatures/', views.candidate_applications, name='candidate_applications'),


    path('password_reset/', views.CustomPasswordResetView.as_view(), name='password_reset'),
    #path('password_reset/', auth_views.PasswordResetView.as_view(template_name='registration/password_reset_form.html',email_template_name='registration/password_reset_email.html',
    #                subject_template_name='registration/password_reset_subject.txt',
    #                success_url='/password_reset/done/'
    #        ), name='password_reset'),

    path('password_reset/done/', auth_views.PasswordResetDoneView.as_view(template_name='password_reset_done.html'), name='password_reset_done'),
    path('reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(template_name='password_reset_confirm.html'), name='password_reset_confirm'),
    path('reset/done/', auth_views.PasswordResetCompleteView.as_view(template_name='password_reset_complete.html'), name='password_reset_complete'),

    
    path('quizz_list/', views.quiz_list, name='quiz_list'),
    path('quiz/<int:ref>/', views.quiz_detail, name='quiz_detail'),
    path('quiz/create/', views.quiz_create, name='quiz_create'),
    path('quiz/update/<int:ref>/', views.quiz_update, name='quiz_update'),
    path('quiz/delete/<int:ref>/', views.quiz_delete, name='quiz_delete'),

    path('quiz/<int:ref>/question/create/', views.question_create, name='question_create'),
    path('question/update/<int:ref>/', views.question_update, name='question_update'),
    path('question/delete/<int:ref>/', views.question_delete, name='question_delete'),

    path('question/<int:ref>/option/create/', views.option_create, name='option_create'),
    path('option/update/<int:ref>/', views.option_update, name='option_update'),
    path('option/delete/<int:ref>/', views.option_delete, name='option_delete'),

    path('tech_skill/<int:tech_skill_id>/quizzes/', views.quizzes_by_tech_skill, name='quizzes_by_tech_skill'),
    path('candidate/profile/', views.candidate_profile, name='candidate_profile'),
    path('candidate/tech_skill/<int:tech_skill_id>/quiz/', views.candidate_quiz, name='candidate_quiz'),

    path('quiz/start/<int:ref>/', views.quiz_start, name='quiz_start'),
    path('quiz-question/<int:ref>/<int:question_ref>/', views.quiz_question, name='quiz_question'),
    path('quiz-submit/<int:ref>/<int:question_ref>/', views.quiz_submit_question, name='quiz_submit_question'),
    path('quiz-results/<int:ref>/', views.quiz_results, name='quiz_results'),
    #path('quiz/submit/<int:ref>/', views.quiz_submit, name='quiz_submit'),

    path('mes/quiz/', views.mes_quiz, name='mes_quiz'),
    path('passer-quizz/', views.passer_quizz, name='passer_quizz'),
    

    path('ckeditor/upload/', ckeditor_views.upload, name='ckeditor_upload'),
    path('ckeditor/browse/', ckeditor_views.browse, name='ckeditor_browse'),

    path('articles/', views.articles, name='articles'),
    path('lire_article/<str:slug>/<int:ref>/', views.lire_article, name='lire_article'),


    path('tech-skills-autocomplete/', views.tech_skills_autocomplete, name='tech_skills_autocomplete'),
    path('soft-skills-autocomplete/', views.soft_skills_autocomplete, name='soft_skills_autocomplete'),
    path('secteurs-autocomplete/', views.secteurs_autocomplete, name='secteurs_autocomplete'),
    path('job_tags-autocomplete/', views.job_tags_autocomplete, name='job_tags_autocomplete'),
    path('category-autocomplete/', views.category_autocomplete, name='category_autocomplete'),

    path('chat/<int:conversation_ref>/', views.chat_view, name='chat_view'),
   
    path('start_conversation/<int:candidate_ref>/<int:job_ref>/', views.start_conversation, name='start_conversation'),

    path('candidates/<int:candidate_ref>/conversations/', views.candidate_conversations, name='candidate_conversations'),
    path('companies/<int:company_ref>/conversations/', views.company_conversations, name='company_conversations'),

    path('send-test-email/', views.send_test_email, name='send_test_email'),
    path('sitemap.xml', sitemap, {'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap'),

    path('exporter/emails/', views.download, name='download'),
    path('download-mail/<int:job_ref>/', views.download_mail, name='download_mail'),
    path('export-excel/<int:job_ref>/', views.export_excel, name='export_excel'),

    ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)`

Can you verify that you don’t have two functions named subscribe in your app’s views.py file?

No, I’ve checked and there is only one view named subscribe in my views.py file. However, there is another view named payment_callback that is configured to handle POST requests and return a 405 error for other request types. I’m not sure if this could be affecting the subscribe view. Here’s the payment_callback view for reference:


@csrf_exempt
def payment_callback(request):
    # Détection de la méthode de requête
    method = request.method
    print("Méthode de requête :", method)

    # Traitement en fonction de la méthode de requête
    if method == 'POST':
        data = json.loads(request.body)
    elif method == 'GET':
        data = request.GET
    else:
        return HttpResponse("Méthode invalide", status=405)

    print("Données de callback reçues :", data)

    # Extraction des données du callback
    transaction_id = data.get('transaction_id')
    company_ref = data.get('company_ref')
    plan_ref = data.get('plan_ref')
    days = data.get('days')

    # Vérifier si les valeurs ne sont pas None avant de les convertir en entiers
    if transaction_id is not None:
        transaction_id = int(transaction_id)
    if company_ref is not None:
        company_ref = int(company_ref)
    if plan_ref is not None:
        plan_ref = int(plan_ref)
    if days is not None:
        days = int(days)

    print(f"ID de transaction : {transaction_id}, Référence entreprise : {company_ref}, Référence plan : {plan_ref}, Durée du plan : {days}")

    try:
        # Vérifier la transaction auprès de KKiaPay
        # Ici, la vérification de la transaction avec Kkiapay devrait être effectuée
        # transaction = kkiapay.verify_transaction(transaction_id)
        # print("Statut de la transaction :", transaction.status)

        # Supposons que la transaction est toujours un succès pour l'exemple
        transaction_status = 'SUCCESS'

        if transaction_status == 'SUCCESS':
            # Récupérer l'entreprise et le plan associés
            company = get_object_or_404(Company, ref=company_ref)
            plan = get_object_or_404(SubscriptionPlan, ref=plan_ref)

            # Définition des valeurs par défaut pour la souscription
            end_date = timezone.now() + timedelta(days=int(days) if plan.name.lower() == 'lite' else plan.duration_days)
            subscription_defaults = {
                'plan': plan,
                'start_date': timezone.now(),
                'end_date': end_date,
                'is_active': True,
            }

            # Créer ou mettre à jour la souscription de l'entreprise
            subscription, created = CompanySubscription.objects.update_or_create(
                company=company,
                defaults=subscription_defaults
            )

            print("Souscription créée/mise à jour avec succès.")  # Vérifier la création/mise à jour de l'abonnement

            # Envoyer une réponse de succès à Kkiapay
            return render(request, 'subscription_detail.html', {
                    'subscription': subscription,
                    'success_message': 'Votre abonnement a été mis à jour avec succès.'
                })


    except Exception as e:
        print("Erreur lors du traitement de la transaction :", e)
        return HttpResponse("Erreur lors du traitement de la transaction", status=500)

    return HttpResponse("Méthode invalide", status=405)

And how might this payment_callback function be called by the subscribe function?

No in my code views.py payment_callback is not called by the subscribe function but subscribe function call payment view and if payment succeed the payment_callback is called.

This the subscribe function and subscribe html template .

function
`
@login_required
def subscribe(request):
if not hasattr(request.user, ‘company’):
print(“Utilisateur non connecté ou sans compagnie associée.”)
return redirect(‘login’) # Or show an appropriate message

company = request.user.company
print(f"Company: {company}")

active_subscription = None
try:
    active_subscription = CompanySubscription.objects.get(company=company, is_active=True)
    print(f"Active subscription found: {active_subscription}")
except CompanySubscription.DoesNotExist:
    print("No active subscription found.")

if request.method == 'POST':
    form = SubscriptionForm(request.POST)
    if form.is_valid():
        plan = form.cleaned_data['plan']
        print(f"Selected plan: {plan}")

        if plan.name == 'lite':
            print("Redirecting to Lite plan duration view.")
            return redirect('days_duration_for_lite_plan', plan_ref=plan.ref)
        else:
            days = plan.duration_days
            amount = plan.price_per_month if days >= 30 else plan.price_per_day * days
            print(f"Days: {days}, Amount: {amount}")

            if plan.name == 'free':
                subscription, created = CompanySubscription.objects.get_or_create(
                    company=company,
                    defaults={
                        'plan': plan,
                        'start_date': timezone.now(),
                        'end_date': timezone.now() + timedelta(days=days),
                        'is_active': True,
                    }
                )

                if created:
                    print("New free subscription created.")
                else:
                    subscription.plan = plan
                    subscription.end_date = subscription.calculate_end_date()
                    subscription.is_active = True
                    subscription.save()
                    print("Free subscription updated.")

                return redirect('mon_forfait')  # Redirect to the user's subscription page

            # If not free, redirect to the payment page
            amount = int(amount)  # Convert amount to integer
            print(f"Redirecting to payment page with amount: {amount}")

            return redirect('payment', company_ref=company.ref, plan_ref=plan.ref, days=days, amount=amount)
    else:
        print("Form is invalid. Errors: ", form.errors)
else:
    print("GET request received.")
    form = SubscriptionForm()

# Retrieve subscription plans
free_plan = SubscriptionPlan.objects.get(name='free')
lite_plan = SubscriptionPlan.objects.get(name='lite')
pro_plan = SubscriptionPlan.objects.get(name='pro')

context = {
    'form': form,
    'active_subscription': active_subscription,
    'free_plan': free_plan,
    'lite_plan': lite_plan,
    'pro_plan': pro_plan,
}

return render(request, 'subscribe.html', context)

`

this is template subscribe.html

{% extends "base1.html" %}
{% load static %}

{% block content %}
    
<section class="py-24 ">
    <div class="mx-auto max-w-7xl px-4 mt-8 mb-8 sm:px-6 lg:px-8">
        <div class="mb-12">
            <h2 class="font-manrope md:text-5xl text-3xl text-center font-bold text-gray-900 mb-4">Choisissez votre plan d'abonnement </h2>
            
            
        </div>
            <!--Grid-->
            <div class="space-y-8 lg:grid lg:grid-cols-3 sm:gap-6 xl:gap-8 lg:space-y-0 lg:items-center">
                <!--Pricing Card-->
                <div class="flex flex-col mx-auto max-w-sm text-gray-900 rounded-2xl bg-gray-50 p-6 xl:py-9 xl:px-12 transition-all duration-500 hover:bg-gray-100">
                    <h3 class="font-manrope text-2xl font-bold mb-3">Free</h3>
                    <div class="flex items-center mb-6">
                        <span class="font-manrope mr-2 text-3xl font-semibold">0 FCFA</span>
                        <span class="text-xl text-black ">/ mois</span>
                    </div>
                    <!--List-->
                    <ul class="mb-12 space-y-6 text-left text-lg text-black">
                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Publiez 3 offres d'emploi par mois</span>
                        </li>
                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Publication et partage de vos offres sur nos différentes plateformes  </span>
                        </li>

                        
                        
                    </ul>
                    {% if active_subscription and active_subscription.plan.ref == free_plan.ref %}  
                        <button type="button" class="py-2.5 px-5 bg-black shadow-sm rounded-full transition-all duration-500 text-base text-white font-semibold text-center w-fit mx-auto hover:bg-black">Votre plan actuel</button>
                    
                    {% else %}
                        <form method="post" action="{% url 'subscribe' %}" id="subscription-form">
                            {% csrf_token %}
                            <input type="hidden" name="plan" value="{{ free_plan.ref }}">    
                            <button type="submit" id="subscribe-button" class="py-2.5 px-5 bg-[#125892] shadow-sm rounded-full transition-all duration-500 text-base text-white font-semibold text-center w-fit mx-auto hover:bg-black">Choisir</button>
                        </form>
                    {% endif %}    
                    <!--List End-->
                </div>
                
                <!--Pricing Card-->
                <div class="flex flex-col mx-auto max-w-sm text-gray-900 rounded-2xl bg-gray-50 p-6 xl:py-9 xl:px-12 transition-all duration-500 hover:bg-gray-100">
                    <h3 class="font-manrope text-2xl font-bold mb-3">Lite</h3>
                    <div class="flex items-center mb-6">
                        <span class="font-manrope mr-2 text-3xl font-semibold">2.000 FCFA</span>
                        <span class="text-xl text-black ">/ Jour</span>
                    </div>
                    <!--List-->
                    <ul class="mb-12 space-y-6 text-left text-lg text-black">
                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Publiez 1 seule offre d'emploi</span>
                        </li>
                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Publication et partage de vos offres sur nos différentes plateformes  </span>
                        </li>

                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Mise en avant de vos offres </span>
                        </li>
                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Gérez vos offres d'emploi</span>
                        </li>
                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Gérez les candidatures</span>
                        </li>

                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Programmez les entretiens</span>
                        </li>
                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Télécharger les emails des candidats</span>
                        </li>
                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Assistance pour la rédaction de vos offres d'emploi(Si besoin)</span>
                        </li>
                    </ul>
                    {% if active_subscription and active_subscription.plan.ref == lite_plan.ref %}  
                        <button type="button" class="py-2.5 px-5 bg-black shadow-sm rounded-full transition-all duration-500 text-base text-white font-semibold text-center w-fit mx-auto hover:bg-black">Votre plan actuel</button>
                    
                    {% else %}
                        <form method="post" action="{% url 'subscribe' %}" id="subscription-form">
                            {% csrf_token %}
                            <input type="hidden" name="plan" value="{{ lite_plan.ref }}">
                            <button type="submit" id="subscribe-button" class="py-2.5 px-5 bg-[#125892] shadow-sm rounded-full transition-all duration-500 text-base text-white font-semibold text-center w-fit mx-auto hover:bg-black">Choisir</button>
                        </form>
                    {% endif %}    
                    <!--List End-->
                </div> 

                <!--Pricing Card-->
                <div class="flex flex-col mx-auto max-w-sm text-gray-900 rounded-2xl bg-indigo-50 transition-all duration-500 hover:bg-indigo-100 ">
                    <div class="uppercase bg-gradient-to-r from-[#125892] to-[#125892] rounded-t-2xl p-3 text-center text-white">
                        Populaire
                    </div>   
                    <div class="p-6 xl:py-9 xl:px-12">
                    <h3 class="font-manrope text-2xl font-bold mb-3">Pro</h3>
                    <div class="flex items-center mb-6">
                        <span class="font-manrope mr-2 text-3xl font-semibold text-black">30.000 FCFA</span>
                        <span class="text-xl text-black ">/ mois</span>
                    </div>
                    <!--List-->
                    <ul class="mb-12 space-y-6 text-left text-black text-lg ">
                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Publiez des offre d'emploi illimitée</span>
                        </li>
                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Publication et partage de vos offres sur nos différentes plateformes  </span>
                        </li>

                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Mise en avant de vos offres </span>
                        </li>
                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Gérez vos offres d'emploi</span>
                        </li>
                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Gérez les candidatures</span>
                        </li>

                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Programmez les entretiens</span>
                        </li>
                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Télécharger les emails des candidats</span>
                        </li>
                        <li class="flex items-center space-x-4">
                            <!-- Icon -->
                            <svg class="flex-shrink-0 w-6 h-6 text-white" viewBox="0 0 30 30" fill="#125892" xmlns="http://www.w3.org/2000/svg">
                                <path d="M10 14.7875L13.0959 17.8834C13.3399 18.1274 13.7353 18.1275 13.9794 17.8838L20.625 11.25M15 27.5C8.09644 27.5 2.5 21.9036 2.5 15C2.5 8.09644 8.09644 2.5 15 2.5C21.9036 2.5 27.5 8.09644 27.5 15C27.5 21.9036 21.9036 27.5 15 27.5Z" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            <span>Assistance pour la rédaction de vos offres d'emploi(Si besoin)</span>
                        </li>

                    </ul>
                    {% if active_subscription and active_subscription.plan.ref == pro_plan.ref %}  
                        <button type="button" class="py-2.5 px-5 bg-black shadow-sm rounded-full transition-all duration-500 text-base text-white font-semibold text-center w-fit mx-auto hover:bg-black">Votre plan actuel</button>
                    
                    {% else %}
                        <form method="post" action="{% url 'subscribe' %}" id="subscription-form">
                            {% csrf_token %}
                            <input type="hidden" name="plan" value="{{ pro_plan.ref }}">
                            <button type="submit" id="subscribe-button" class="py-2.5 px-5 bg-[#125892] shadow-sm rounded-full transition-all duration-500 text-base text-white font-semibold text-center w-fit block mx-auto hover:bg-black">Choisir</button>
                        </form>
                    {% endif %}     
                    <!--List End-->
                </div>
                </div> 
                 
            </div>
            <!--Grid End-->
        
    </div>
    <br>
    <br>
    <br>
</section>
           

    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
        $(document).ready(function() {
            // Pré-remplir le montant au chargement de la page
            updateAmount();

            $('#id_plan, #id_days').change(function() {
                updateAmount();
            });

            function updateAmount() {
                var planRef = $('#id_plan').val();
                var days = $('#id_days').val();

                // Vérifier si le plan sélectionné est le plan Lite
                var selectedPlan = $('#id_plan option:selected').text();
                if (selectedPlan !== 'Forfait Lite') {
                    // Afficher un message d'erreur ou ne rien faire
                    return;
                }

                if (planRef) {
                    $.ajax({
                        url: "{% url 'calculate_amount' %}",
                        data: {
                            'plan_ref': planRef,
                            'days': days
                        },
                        dataType: 'json',
                        success: function(data) {
                            if (data.amount) {
                                $('#amount_display').text('Montant à payer: ' + data.amount + ' FCFA');
                            } else {
                                $('#amount_display').text('Erreur de calcul du montant.');
                            }
                        }
                    });
                }
            }


            // Afficher ou masquer le champ des jours en fonction du plan
            $('#id_plan').change(function() {
                var selectedPlan = $('#id_plan option:selected').text();
                if (selectedPlan === 'Forfait Lite') {
                    $('#days_field').show();
                } else {
                    $('#days_field').hide();
                }
            }).trigger('change');  // Déclenche l'événement pour afficher correctement au chargement


            const planField = document.getElementById('id_plan');
            const daysField = document.getElementById('id_days');
            const amountDisplay = document.getElementById('amount_display');

            function updateAmount() {
                const planValue = parseFloat(planField.value);
                const daysValue = parseInt(daysField.value, 10);

                if (!isNaN(planValue) && !isNaN(daysValue)) {
                    const totalAmount = (planValue * daysValue).toFixed(2);
                    amountDisplay.innerHTML = `Montant total : ${totalAmount} FCFA`;
                } else {
                    amountDisplay.innerHTML = '';
                }
            }

            planField.addEventListener('change', updateAmount);
            daysField.addEventListener('input', updateAmount);

            updateAmount();

        });
    </script>
{% endblock %}                             

What output are you getting from all your print statements in your console log?