Home > Software design >  uploaded file wont save
uploaded file wont save

Time:10-03

Im trying to add a feature to my app that allows users to upload their cv file. I created a model like this:

class ResumeDocument(models.Model):
    id = models.AutoField(primary_key=True)
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    cvfile = models.FileField(upload_to="documents", null=True)

and created a model form like below:

class DocumentForm(forms.ModelForm): 
    class Meta:
        model = ResumeDocument
        fields = ['cvfile']

my views.py:

def pdf_resume(request):
    if request.method == 'POST':
        form = DocumentForm(request.POST or None ,request.FILES or None , instance=request.user)
        if form.is_valid():
            form.save()
            messages.success(request, f'Done!!!!')
            return redirect('pdf_resume')
    else:
        form = DocumentForm(instance=request.user)
    context = {'form':form}
    return render(request, 'reg/pdf_resume.html', context)

and finally my HTML:

{% if messages %}
{% for m in messages %}
{{m}}
{% endfor %}
{% endif %}
<form method="POST" action="{% url 'pdf_resume' %}" enctype="multipart/form-data">
    {% csrf_token %}
    <fieldset class="form-group">
        <legend class="border-bottom mb-4">Profile Info</legend>
        {{ form }}
    </fieldset>
    <div class="form-group">
        <button class="btn btn-outline-info" type="submit ">Update</button>
    </div>
</form>

when I click Update, it redirects to the page and messages me with success and no error. but the file doesn't get saved in media. however, when I upload the file from admin page it gets uploaded and saved. what am I doing wrong? please help me

CodePudding user response:

You should not pass instance=request.user, because then the form will try to edit the user object, not add a ResumeDocument.

You can link the ResumeDocument to the request.user by setting the .user attribute of the .instance wrapped in the form:

from django.contrib.auth.decorators import login_required

@login_required
def pdf_resume(request):
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)  # ← no instance=request.user
        if form.is_valid():
            form.instance.user = request.user
            form.save()
            messages.success(request, f'Done!!!!')
            return redirect('pdf_resume')
    else:
        form = DocumentForm()  # ← no instance=request.user
    context = {'form':form}
    return render(request, 'reg/pdf_resume.html', context)

If you want to edit an existing ResumeDocument, then you can try to fetch that ResumeDocument with:

from django.contrib.auth.decorators import login_required

@login_required
def pdf_resume(request):
    instance = ResumeDocument.objects.filter(user=request.user).first()
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES, instance=instance)
        if form.is_valid():
            form.instance.user = request.user
            form.save()
            messages.success(request, f'Done!!!!')
            return redirect('pdf_resume')
    else:
        form = DocumentForm(instance=instance)
    context = {'form':form}
    return render(request, 'reg/pdf_resume.html', context)

Note: You can limit views to a view to authenticated users with the @login_required decorator [Django-doc].

  • Related