Check if a file exist in Django - python

I have created a newclaim.html and editclaims.html. newclaims.html allows me to upload a file while editclaims.html allows me to retrieve the file.
Currently, I am able to retrieve the uploaded file but I want to do an if-else. I want to do an if-else that will delete the old file if a new file is uploaded
This is my views.py
**# Submit a new Claim**
def newclaim(request):
context = initialize_context(request)
user = context['user']
if request.method == 'POST':
receipt = request.FILES['receipt_field']
ins = SaveClaimForm(receipt=receipt)
ins.save()
print("The Data has been written")
return render(request, 'Login/newclaim.html/', {'user':user})
# Edit a claim
def editclaims(request,id):
context = initialize_context(request)
user = context['user']
# get original object
claims = SaveClaimForm.objects.get(id=id)
if request.method == 'POST':
# update original object
claims.receipt = request.FILES.get('receipt')
# save it with original `ID`
claims.save()
return render(request, "Login/editclaims.html", {'claims':claims, 'user':user})

You can check if the old file exist in your file path and delete it. May refer to the code below and modify as per your need :
def editclaims(request,id):
context = initialize_context(request)
user = context['user']
# get original object
claims = SaveClaimForm.objects.get(id=id)
if request.method == 'POST':
# get the old file name:
old_file = claims.receipt
# update original object
claims.receipt = request.FILES.get('receipt')
# save it with original `ID`
claims.save()
#Delete the old file from os if it exist
#Do not forget to import os
#FILE_PATH = path to your file directory
if os.path.isfile(FILE_PATH+old_file):
os.remove(FILE_PATH+old_file)
return render(request, "Login/editclaims.html", {'claims':claims, 'user':user})

Related

How do I redirect to url2 after performing a task on url1 in django?

I have a edit-scholarship.html in which you can search for a scholarship by passing name and type and then select that scholarship and edit it in update-scholarship.html by passing scholarship id from the url.
Now after updating the scholarship, the url becomes
http://127.0.0.1:8000/admin/updatescholarship/50
50 is the scholarship id passed into the url
Now when I try to go to dashboard in my project, the url becomes
http://127.0.0.1:8000/admin/updatescholarship/dashboard
I dont't want the dashboard to get appended after the updatescholarship . The url should be
http://127.0.0.1:8000/admin/dashboard
Here's my edit-scholarship view
def admin_editscholarship(request):
if request.method == 'POST':
name = request.POST['sch_name']
type = request.POST['sch_type']
schdets = ScholarshipDetails.objects.filter(name = name,type = type)
if schdets is not None:
#if something exists in scholarship details, then print it
print('Scholarship found')
else:
schdets = None
return render(request,'admin-editscholarship.html',{'schdets':schdets})
Here's my update-scholarship view
def admin_updatescholarship(request,pk=None):
#can update the new data in the selectd scholarship
if pk:
sch = ScholarshipDetails.objects.get(pk = pk)
if request.method == 'POST':
form = EditScholarshipForm(request.POST,instance=sch)
if form.is_valid():
form.save()
print('\nform saved')
args = {'form' : form}
messages.success(request,'Successfully updated')
return render(request,'admin-editscholarship.html',args)
Here's my urls.py
path('admin/dashboard',views.admin_dash),
path('admin/addscholarship',views.admin_addscholarship),
path('admin/editscholarship',views.admin_editscholarship),
url(r'^admin/updatescholarship/(?P<pk>\d+)$',views.admin_updatescholarship,name =
'updatescholarship'),
path('admin/students',views.admin_students),
path('admin/requests',views.admin_requests)
you can redirect to other url using django redirect
from django.shortcuts import redirect
def fn_test(request):
task here
return redirect('path_to_redirect/')

Passing Form Data to View

I have the following view:
views.py
def PackingListView(request):
if request.method == "POST":
form = PackingListForm(request.POST)
if form.is_valid():
if 'preview' in request.POST:
request.session['data'] = form.cleaned_data
return redirect('myview')
....
I would like to take the data in form and pass it to this next view, and set the data variable equal to it. This was previously working, but once I added a foreign key into this form, the session no longer works as it is not serializable. What approach is the safest for me to take here?
views.py
class myview(View):
def get(self, request, *args, **kwargs):
data = request.session.pop('data', {})#this won't work now
pdf = render_to_pdf('packlist_preview.html', data)
return HttpResponse(pdf, content_type='application/pdf')
Also in case it is needed - here is the URL for myview
url(r'^myview/', views.myview.as_view(), name='myview'),
You should be able to serialize the data if you replace the model instance with its id.
data = form.cleaned_data
# remove object from data dict
related_object = data.pop('related_object')
# add in a reference
data['related_object_id'] = related_object.pk
# now you should be able to serialize object
request.session['data'] = data
Then in the next view, you can fetch the object from the database using its id
data = request.session.pop('data', {})
related_object_id = data.pop('related_object_id', None)
if related_object_id:
try:
data['related_object'] = RelatedObject.objects.get(pk=related_object_id)
except RelatedObject.DoesNotExist:
pass

Passing uploaded file to template -- Django

I was following the instructions from the top comment of this post: Need a minimal Django file upload example and this is my views.py. I'm not interested in creating a list of files, so I removed that.
def reikna(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
new_doc = Document(docfile = request.FILES['docfile'])
# Marks the file as /options/ file
new_doc.save()
# Redirect to the document list after POST
#return HttpResponseRedirect(reverse('notendur.views.options'))
else:
form = DocumentForm() # An empty, unbound form
return render('file_view2.html', {'new_doc': new_doc})
However, when I do this, I get
UnboundLocalError: local variable 'new_doc' referenced before assignment
Does this have something to do with the scope of new_doc? How should I do this?
EDIT __ My model
class Document(models.Model):
docfile = models.FileField(upload_to=_upload_path)
def get_upload_path(self,filename):
return "uploads/"+str(self.user.id) + '/' + str(date.today()) + '/' + filename

Not saving data to Database from Form

When i have this view, It only change username a password from first Form, but it would save any data from second form. Why?
if request.method == 'POST': # If the form has been submitted...
username_a_heslo = UserCreationForm(request.POST, prefix = "začátek")
přidat_údaje = UcitelZmenaForm(request.POST, prefix = "konec")
if username_a_heslo.is_valid() and přidat_údaje.is_valid(): # All validation rules pass
změnajména = request.user
změnajména.username = username_a_heslo.cleaned_data["username"]
změnajména.save()
zmenahesla=request.user.set_password(username_a_heslo.cleaned_data["password1"])
# primary = username_a_heslo.save()
cast_form = Ucitel.objects.all().filter(user=request.user)
form = UcitelZmenaForm(přidat_údaje.cleaned_data, instance=cast_form[0])
form.save
#b = přidat_údaje.save()
return HttpResponseRedirect('/hlavni_stranka/')
else:
username_a_heslo = UserCreationForm(prefix = "začátek")
přidat_údaje = UcitelZmenaForm(prefix = "konec")
return render(request, 'registration/prihlasen.html', {'prvni_prihlaseni':prvni_prihlaseni,'první_form': username_a_heslo,'druhý_form':přidat_údaje})
You did not call the function on the second one, you only have form.save when you need form.save().

How can I open a image from an ImageField before validating and saving a form?

I want to get the value of a CharField based on the value of an ImageField. My form and view are defined as:
#Form
class GpsImForm(forms.Form):
image = forms.ImageField(required=True)
gps_data = forms.CharField(required=True)
#View
def gpsim_gen_view(request):
if request.method == 'POST':
form = GpsImForm(request.POST, request.FILES)
if 'image' in request.FILES:
im = request.FILES['image']
i = Image.open(im)
... # functions to extract exif data from i
request.POST.update({ 'gps_data': ...}) # set gps_data based on exif data from i
if form.is_valid():
obj = form.save()
return ... #returns the gpsim
else:
form = GpsImForm()
return direct_to_template(request, 'gpsim_generate.html', {'form': form,})
The gps_data is updated, but, as soon as I use Image.open(), I get the following error message:
Upload a valid image. The file you uploaded was either not an image or a corrupted image.
If I comment the lines concerning i and modify the gps_data to whatever, the form (with the image) is saved without any error...
# i = Image.open(im)
# ...
# functions to extract exif data from i
request.POST.update({ 'gps_data': 'some text'}) # set gps_data to 'test'
first of all, make sure that your form has the enctype tag
<form enctype="multipart/form-data" ... >
Try to write the img (all the chunks) on disk:
import Image
from random import choice
from django.conf import settings
random_file_name = getattr(settings, 'FILE_UPLOAD_TEMP_DIR', '/tmp')
random_file_name += '/' + ''.join([choice('abcdefg') for i in range(12)]) + '.jpg'
destination = open(random_file_name, 'wb+')
for chunk in request.FILES['image'].chunks():
destination.write(chunk)
destination.close()
Then, you can open it from disk:
image = Image.open(random_file_name)
if image.mode != "RGB":
image = image.convert("RGB")
...
This URL may help you:
https://docs.djangoproject.com/en/dev/topics/http/file-uploads/
I finally found a cleaner solution:
I removed the "required=True" from my models and defined a clean() method which does the job in my form models:
#Form
class GpsImForm(forms.Form):
image = forms.ImageField(required=True)
gps_data = forms.CharField()
def clean(self):
super(forms.Form, self)).clean()
if not self.cleaned_data['gps_data']: # the user can provide the gps_data manually
if self.cleaned_data['image']: # if he provided no gps_data but an image
i = Image.open(self.cleaned_data['image'])
... # functions to extract exif data from i
else:
msg = _("You have to provide an image or a gps_data.")
self._errors['gps_data'] = self.error_class([msg])
return self.cleaned_data
#View
def gpsim_gen_view(request):
if request.method == 'POST':
form = GpsImForm(request.POST, request.FILES)
if form.is_valid():
obj = form.save()
return ... #returns the gpsim
else:
form = GpsImForm()
return direct_to_template(request, 'gpsim_generate.html', {'form': form,})

Categories

Resources