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].