Reputation: 1059
models.py
class Campaign(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
# this is many to one relationship, on_deleting user, profile will also be deleted
funds_for = models.CharField(max_length=200)
campaign_title = models.CharField(max_length=200, blank=True)
amount_required = models.IntegerField(null=True, blank=True)
campaign_image = models.ImageField(default="default_campaign.png",upload_to="campaign_pictures")
forms.py
class RaiseFundsFrom1(forms.ModelForm):
class Meta:
model = Campaign
fields = ['funds_for']
class RaiseFundsFrom2(forms.ModelForm):
class Meta:
model = Campaign
fields = ['campaign_image']
class RaiseFundsFrom3(forms.ModelForm):
class Meta:
model = Campaign
fields = ['campaign_title','amount_required']
views.py
@login_required
def raise_funds_medical_1(request):
if request.method == 'POST':
form = RaiseFundsFrom1(request.POST)
if form.is_valid():
request.session['funds_for'] = form.cleaned_data.get('funds_for')
return redirect('funds:raise_funds_medical_2')
else:
form = RaiseFundsFrom1(instance=request.user)
return render(request,'funds/raise_funds_medical_1.html',{'form':form})
@login_required
def raise_funds_medical_2(request):
if request.method == 'POST':
form = RaiseFundsFrom2(request.POST, request.FILES or None)
if form.is_valid():
f = request.FILES['campaign_image']
request.session['campaign_image'] = f.name
return redirect('funds:raise_funds_medical_3')
else:
form = RaiseFundsFrom2(instance=request.user)
return render(request,'funds/raise_funds_medical_2.html',{'form':form})
@login_required
def raise_funds_medical_3(request):
if request.method == 'POST':
form = RaiseFundsFrom3(request.POST)
if form.is_valid():
request.session['campaign_title '] = form.cleaned_data.get('campaign_title')
request.session['amount_required '] = form.cleaned_data.get('amount_required')
c = Campaign()
c.funds_for = request.session['funds_for']
c.campaign_image = request.session['campaign_image']
c.campaign_title = request.session['campaign_title']
c.amount_required = request.session['amount_required']
c.save()
return redirect('core:landing_page')
else:
form = RaiseFundsFrom3(instance=request.user)
return render(request,'funds/raise_funds_medical_3.html',{'form':form})
I need to get details for campaign model in 3 parts. I need to do in a specific order, with the second form requiring to be only an image upload. My plan is to capture the required fields and store temporarily in sessions. when the form is saved, i intend to delete the sessions(not important right now)
In the current scenario, when the third form is processed/saved. the contents of first form, third form and image name from second form gets saved. however, the image does not get uploaded to the required folder.
Upvotes: 0
Views: 140
Reputation: 2212
I do not know whether it is possible to save a file to session with some trick. A workaround I see is to save the file in the required destination in the second view and save the path to that file in the session. Then use this saved path to create the object in the 3rd view.
So, create a small function to handle the upload
def handle_uploaded_file(f, upload_to):
with open(upload_to, 'wb') as destination:
for chunk in f.chunks():
destination.write(chunk)
and then use it to save the file in your second view
def raise_funds_medical_2(request):
if request.method == 'POST':
form = RaiseFundsFrom2(request.POST, request.FILES or None)
if form.is_valid():
f = request.FILES['campaign_image']
f_path_rel = os.path.join("campaign_pictures", f.name)
f_path = os.path.join(settings.MEDIA_ROOT, f_path_rel)
handle_uploaded_file(f, f_path)
request.session['campaign_image'] = f_path_rel
return redirect('raise_funds_medical_3')
else:
form = RaiseFundsFrom2(instance=request.user)
return render(request,'funds/raise_funds_medical_2.html',{'form':form})
I think assigning the path to your image field should work, so that you do not need to change your 3rd view.
However, be aware of two things:
The handle_uploaded_file
expects that the correct destination folder
exists. If you cannot guarantee this you should add a check for the
folder and create it if not existant
The handle_uploaded_file
will overwrite exisitng files with the same
name. If this should be avoided check for existing files before
writing and modify the filename accordingly.
Upvotes: 1