Search code examples
djangodjango-modelsdjango-viewsdjango-templates

Django uploading PDF and mailing it


So I want to code a website using Django where anyone can apply to become agents for the company. To apply they fill out a form where they upload their resume/CV which is then mailed to the HR. Now my code doesn't seem to take the pdf since it returns none after hitting submit. Also the mail isn't being sent. How can I fix this? Thanks in advance!

My html:

<form method="POST" action="{% url 'apply' %}" class="row" enctype="multipart/form-data">
        {% csrf_token %}
        <div class="mb-3 col-lg-6">
        <input type="text" class="form-control" placeholder="Name" name ="name">
        </div>
        <div class="mb-3 col-lg-6">
        <input type="text" class="form-control" placeholder="Email Address" name ="email">
        </div>
        <div class="mb-3 col-lg-6">
        <input type="text" class="form-control" placeholder="Subject" name ="subject">
        </div>
        <div class="mb-3 col-lg-6">
        <input type="text" class="form-control" placeholder="Phone" name ="phone">
        </div>
        <div class="mb-3 col-lg-6">
            <input id="CV" type="file" class="form-control" placeholder="CV" name ="CV" aria-label="CV">
        </div>
        <div class="mb-3 col-lg-6">
            <input type="text" class="form-control" placeholder="Address" name ="address">
        </div>
        <div class="mb-3 col-lg-12">
        <textarea name id cols="30" rows="5" class="form-control"  name ="cover_letter" placeholder="Cover Letter..."></textarea>
        </div>
        <div class="mb-3 col-lg-12">
        <input type="submit" class="btn btn-primary" value="Apply">
        </div>
</form>

My views.py:

def apply(request):
    if request.method == "POST":
        name = request.POST['name']
        email = request.POST['email']
        subject = request.POST['subject']
        phone = request.POST['phone']
        CV = request.POST.get('CV')
        address = request.POST['address']
        cover_letter = request.POST.get('cover_letter')

        application = "Name: " + name + "  " + "Phone: " + phone + "  " + "Email: " + email + "  " + "Address: " + address + "  " + "Subject: " + subject


        send_mail(
            'Application of ' + name,
            application,
            CV,
            cover_letter,
            email,
            ['email@.gmailcom'],
            )

        return render(request, 'users/apply.html', {
            'name' : name,
            'email' : email,
            'phone' : phone,
            'address' : address,
            'subject' : subject,
            'cover_letter' : cover_letter,
            'CV' : CV,
            })
    else:
        return render(request, 'blog/index.html', {})

My settings.py:

EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"

Solution

  • In Django, uploaded files are accessed via request.FILES, not request.POST. So, you should retrieve the uploaded file using request.FILES.get('CV').

    The parameters you're using with send_mail seem to be incorrect. send_mail doesn't natively support sending files as attachments with the parameters you've provided. For sending emails with attachments, you should use the EmailMessage class.

    Here's how you can adjust your views.py:

    from django.core.mail import EmailMessage
    from django.conf import settings
        def apply(request):
            if request.method == "POST":
                name = request.POST['name']
                email = request.POST['email']
                subject = request.POST['subject']
                phone = request.POST['phone']
                address = request.POST['address']
                cover_letter = request.POST.get('cover_letter')
                cv_file = request.FILES.get('CV')
        
                application = f"Name: {name}\nPhone: {phone}\nEmail: {email}\nAddress: {address}\nSubject: {subject}\nCover Letter: {cover_letter}"
        
                email_message = EmailMessage(
                    f'Application from {name}',
                    application,
                    settings.DEFAULT_FROM_EMAIL,
                    ['example@example.com'],  
                )
        
                # Attach the CV if it exists
                if cv_file:
                    email_message.attach(cv_file.name, cv_file.read(), cv_file.content_type)
        
                email_message.send()
        
                return render(request, 'users/apply.html', {
                    'name': name,
                    'email': email,
                    'phone': phone,
                    'address': address,
                    'subject': subject,
                    'cover_letter': cover_letter,
                    'CV': cv_file,
                })
        
            else:
                return render(request, 'blog/index.html', {})