django renaming image file while uploading - python

Im working on a social media application in django and would like to rename all the images from the uploaded content to make it easier to reuse them (putting them in to a pdf is the end goal, right now the filenames are the same as uploaded and i don't know how put these paths into the pdf --> solution might be numbering them all).
The filename should be renamed to: postimg{num_post}
all posts are numbered. the specific number or the post should be the end of the filename of the image file.
models.py
def post_images(instance, filename):
ext = filename.split('.')[-1]
filename = "%s_%s.%s" % (instance.post.num_post, ext)
return os.path.join('uploads', filename)
class Post(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
num_post = models.IntegerField(default=0)
image = models.ImageField(upload_to='post_images')
caption = models.TextField(max_length=300)
created_at = models.DateTimeField(auto_now_add=True)
number_of_likes = models.IntegerField(default=0)
number_of_dislikes = models.IntegerField(default=0)
def __str__(self):
return self.caption
views.py
def upload(request):
if request.method == 'POST':
#user = request.user.username
image = request.FILES.get('image_upload')
#--> how to rename the image file to "post{num_post}.jpg"
caption = request.POST['caption']
num_post = Post.objects.count()+1
new_post = Post.objects.create(image=image, caption=caption, num_post=num_post)
new_post.save()
#create pdf
buffer = io.BytesIO()
#get the image
#img_file = Image.open(f'{os.getcwd()}/{post.image.url}').convert('RGB')
#img_file = f'media/post_images/postimg{num_post}'
#x_start = 0
#y_start = 0
#saving it on the server
folder_path = f"media/post{num_post}.pdf"
folder_name = os.path.basename(folder_path)
p = canvas.Canvas(folder_name)
#p.drawImage(img_file, x_start, y_start, width=120, preserveAspectRatio=True, mask='auto')
p.drawString(200, 300, new_post.caption)
p.drawString(200, 100, str(new_post.created_at))
p.drawString(200, 600, str(new_post.id))
#p.drawText(new_post.caption)
#p.drawImage(new_post.image)
p.showPage()
p.save()
buffer.seek(0)
return redirect('/'), folder_path
else:
return redirect('/')
so in the end i should be able to put the image in the pdf by using:
img_file = f'media/post_images/postimg{num_post}'
x_start = 0
y_start = 0
p.drawImage(img_file, x_start, y_start, width=120, preserveAspectRatio=True, mask='auto')
I was already able to get the images into the pdf by using the existing filename but since the pdf should be automatically generated for each post, the image name needs to be variable, i think.
Right now, it is not working. The image is not renamed, but there is also no error display. so the function seems not to reach the image? How do I make it work?
Thank you for any suggestions. :) im new to django... any explanation helps.

Lets start with the model field:
class Post(models.Model):
...
image = models.ImageField(upload_to='post_images')
...
It is not showing any errors because you are uploading files to 'post_images' folder and not calling a function with such name. And that is also why your files are not being renamed.
To call the rename function, just remove the single quote:
image = models.ImageField(upload_to=post_image)
Although, it is not going to work because of this line:
def post_images(instance, filename):
...
filename = "%s_%s.%s" % (instance.post.num_post, ext)
...
Where there are two problems. First, instance is a post object instance, you are trying to access it in the wrong way. And second when trying to format three strings with two parameters. That being said:
def post_images(instance, filename):
ext = filename.split('.')[-1]
filename = 'post{}.{}'.format(instance.num_post, ext)
return os.path.join('uploads', filename)
Lets also implement a #property on model Post so we can access its image filename with ease:
class Post(models.Model):
...
#property
def filename(self):
return os.path.basename(self.image.name).split('.')[0]
Now, related to the view, it is always a good practice to work with django forms (model form), it also helps writing less code while doing more (like validating data):
forms.py
from django import forms
from .models import Post
class UploadForm(forms.ModelForm):
class Meta:
model = Post
fields = ['image', 'caption']
views.py
from django.shortcuts import render, redirect
from .forms import UploadForm
from .models import Post
import os
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
def upload(request):
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES)
if form.is_valid():
form.cleaned_data['num_post'] = Post.objects.count() + 1
post = Post.objects.create(**form.cleaned_data)
p = canvas.Canvas(os.getcwd() + f'/uploads/converted/{post.filename}.pdf')
p.drawString(200, 300, post.caption)
p.drawString(200, 100, str(post.created_at))
p.drawString(200, 600, str(post.id))
p.showPage()
p.drawImage(post.image.name, 0,0, width=A4[0], height=A4[1],mask='auto')
p.showPage()
p.save()
return redirect('post:upload')
else:
form = UploadForm()
return render(request, 'upload.html', {'form': form})
In this view, after checking that the data is valid we then update the valid data dictionary and create the object. Furthermore, since we are using .create() it is not necessary to save the object afterwards.
After this first process we create ReportLab PDF object, with two pages, the first one containing the string related data (as in your original function). And, the second one where we draw an image fitting the whole page by using from reportlab.lib.pagesizes import A4 size properties. You can find all this information at the userguide documentation.
upload.html
{% block content %}
<form action="{% url 'post:upload' %}" enctype="multipart/form-data" method="post">
{% csrf_token %}
{{form.as_p}}
<button type="submit">Create</button>
</form>
{% endblock content %}
urls.py
app_name = 'post'
urlpatterns = [
path('upload/', views.upload, name='upload'),
]

Related

django set image delete old reference and prevent delete default

despite of many mordern website employ an OSS for serving image, I still want to build a backend to manage small thumbnails locally.
however, django image field is a bit tricky.
there are three views I may change image reference:
models.py
views.py
forms.py
I used to do it simply by:
forms.py
request.user.profile.image = self.files['image']
and I always have a default
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = ProcessedImageField(
default='profile/default.jpg',
upload_to='profile',
processors=[ResizeToFill(*THUMBNAIL_SIZE)],
format='JPEG',
options={'quality': THUMBNAIL_QUALITY},
)
After a lot of testing, I found that it always result in an issue, can be among:
default image file get deleted.
if the image has been set before, it holds an value that is not the default, when I reset it, the old referenced file is not deleted and will occupy disk storage.
to do it perfectly, I decided to write a global function for import, whenever I want to set an image, call it
from django.conf import settings
def setImage(instance, attr, file):
""" instance will be saved """
if file:
ifield = getattr(instance, attr)
# old reference, can be default
iurl = ifield.url
# default
durl = settings.MEDIA_URL + instance._meta.get_field(attr).get_default()
if iurl != durl:
# old reference is not default
# delete old reference and free up space
ifield.delete(save=True)
# set new file
setattr(ifield, attr, file)
instance.save()
pretty straight-forward. however, in testing, I found the image will never be set. Following are the possibale reasons I have eliminated:
form multipart enctype attribute
ajax processData, contentType is correctly set
save in model class is not overriden
if it's all ok, where went wrong? I logged out all the values.
setImage(self.user.profile, 'image', self.files['image'])
# self.files['image'] has valid value and is passed
# to setImage, which I think, is not garbage collected
def setImage(instance, attr, file):
""" instance will be saved """
print('======')
print(file)
if file:
ifield = getattr(instance, attr)
iurl = ifield.url
durl = settings.MEDIA_URL + instance._meta.get_field(attr).get_default()
print(iurl)
print(durl)
if iurl != durl:
ifield.delete(save=True)
print(f'--- del {iurl}')
setattr(ifield, attr, file)
print('----res')
print(getattr(ifield, attr))
print(ifield.image)
print('--- ins')
print(instance)
instance.save()
print('--- after save')
print(instance.image.url)
print(getattr(instance, attr))
the field has a default value, and I upload the screen shot in testing.
======
Screen Shot 2022-11-03 at 10.59.41 pm.png
/media/profile/default.jpg
/media/profile/default.jpg
----res
Screen Shot 2022-11-03 at 10.59.41 pm.png
Screen Shot 2022-11-03 at 10.59.41 pm.png
--- ins
tracey
--- after save
/media/profile/default.jpg
profile/default.jpg
why the image is not setting, anybody have any ideas?
Solutions
after tons of testing, only a line went wrong and just simple a wrong variable.
def setImage(instance, attr, file):
""" instance will be saved """
if file:
ifield = getattr(instance, attr)
iurl = ifield.url
durl = settings.MEDIA_URL + instance._meta.get_field(attr).get_default()
if iurl != durl:
ifield.delete(save=True)
setattr(instance, attr, file)
instance.save()
for form update validation, here's a method I've worked out and testified working:
def clean_image(form, attr:str, field:str):
"""
form.instance.attr -> ImageFile
form.cleaned_data[field] -> ImageFile
"""
upload_img = form.cleaned_data[field]
if form.instance:
# condition: update
# create does not matter
ifield = getattr(form.instance, attr)
iurl = ifield.url
if isinstance(upload_img, InMemoryUploadedFile):
# upload new file
# else, the file is not changed
durl = settings.MEDIA_URL + form.instance._meta.get_field(attr).get_default()
if iurl != durl:
ifield.delete(save=True)
return upload_img
e.g. you can call it simply like:
class Project(models.Model):
image = ProcessedImageField(
default='projects/default.jpg',
upload_to='projects',
processors=[ResizeToFill(*THUMBNAIL_SIZE)],
options={'quality': THUMBNAIL_QUALITY},
format='JPEG',
)
class ProjectCreateForm(forms.ModelForm):
class Meta:
model = Project
fields = ['name', 'image']
def clean_image(self):
return clean_image(self, 'image', 'image')
Honestly, I did not test your function to say what is wrong with it. Instead I implemented it in my own way taking your model as a base. If you really want a set_image(instance, attr, file) function, you can adapt it from this answer create_profile_ajax at views.py.
settings.py
DEFAULT_IMAGE_URL = 'profile/default.jpg'
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = ProcessedImageField(
default=settings.DEFAULT_IMAGE_URL,
upload_to='avatars',
processors=[ResizeToFill(100, 50)],
format='JPEG',
options={'quality': 60},
blank=True,
null=True
)
#staticmethod
def default_image_absolute_url():
return settings.MEDIA_URL + settings.DEFAULT_IMAGE_URL
#staticmethod
def default_image_url():
return settings.DEFAULT_IMAGE_URL
forms.py
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['image']
views.py
#login_required
def create_profile(request):
form = ProfileForm()
return render(request, 'profile/create.html', {'form': form})
def create_profile_ajax(request):
image = request.FILES.get('image')
profile, created = Profile.objects.get_or_create(user=request.user)
if image:
if profile.image.url == Profile.default_image_absolute_url():
profile.image = image
else:
profile.image.delete()
profile.image = image
else:
profile.image = Profile.default_image_url()
profile.save()
profile.refresh_from_db()
return JsonResponse({'new_image_url': profile.image.url})
profile/create.html (csrf with ajax)
{% extends 'base.html' %}
{% block content %}
{{form.as_p}}
<input type="submit" value="Create" onclick="sendProfile()">
<img src="{{request.user.profile.image.url}}"
id="thumb"
width="500"
height="600"
{% if not request.user.profile.image %} hidden {% endif %}
style="object-fit: contain;">
<script>
function getCookie(name) {
...
}
function sendProfile() {
const csrftoken = getCookie('csrftoken');
var input = document.getElementById('id_image');
var data = new FormData()
data.append('image', input.files[0])
fetch('/your/ajax/url/', {
method: 'POST',
headers: {
'X-CSRFToken': csrftoken
},
body: data
})
.then((response) => response.json())
.then((data) => {
var thumb = document.getElementById('thumb');
thumb.src = data.new_image_url;
thumb.hidden = false;
input.value = '';
});
}
</script>
{% endblock %}
quotting FormData documentation:
When using FormData to submit POST requests using XMLHttpRequest or
the Fetch_API with the multipart/form-data Content-Type (e.g. when
uploading Files and Blobs to the server), do not explicitly set the
Content-Type header on the request.

Display PDF in django

I need to display a pdf file in a browser, but I cannot find the solution to take the PDF for the folder media, the PDF file was save in my database, but I cannot show.
my urls.py:
urlpatterns = [
path('uploadfile/', views.uploadFile, name="uploadFile"),
path('verPDF/<idtermsCondition>', views.verPDF, name='verPDF'),
]
my models.py:
class termsCondition(models.Model):
title = models.CharField(max_length=20, verbose_name="title")
uploadPDF = models.FileField(
upload_to="PDF/", null=True, blank=True)
dateTimeUploaded = models.DateTimeField(auto_now_add=True)
deleted_at = models.DateTimeField(
auto_now=False, verbose_name="Fecha eliminacion", blank=True, null=True)
class Meta:
verbose_name = "termsCondition"
verbose_name_plural = "termsConditions"
my views.py:
def uploadFile(request):
user = request.user
if user.is_authenticated:
if user.is_admin:
if request.method == "POST":
# Fetching the form data
fileTitle = request.POST["fileTitle"]
loadPDF = request.FILES["uploadPDF"]
# Saving the information in the database
termscondition = termsCondition.objects.create(
title=fileTitle,
uploadPDF=loadPDF
)
termscondition.save()
else:
listfiles = termsCondition.objects.all()[:1].get()
return render(request, 'subirTerminos.html', context={
"files": listfiles
})
else:
messages.add_message(request=request, level=messages.SUCCESS,
message="No tiene suficientes permisos para ingresar a esta página")
return redirect('customer')
else:
return redirect('login2')
def verPDF(request, idtermsCondition):
user = request.user
if user.is_authenticated():
if user.is_admin:
getPDF = termsCondition.objects.get(pk=idtermsCondition)
seePDF = {'PDF': getPDF.uploadPDF}
print(seePDF)
return render(request, 'subirTerminos.html', {'termsCondition': getPDF, 'uploadPDF': getPDF.uploadPDF})
else:
messages.error(request, 'Do not have permission')
else:
return redirect('login2')
my html:
<div>
<iframe id="verPDF" src="media/PDF/{{ uploadPDF.url }}"
style="width:800px; height:800px;"></iframe>
</div>
I want to see my pdf and I cannot do, I want to know how to do, I tried many solutions, I accept js, embed iframe whatever to can solve.
It should be user.is_authenticated not user.is_authenticated() in verPDF view and also I'd recommend you to change <idtermsCondition> to <int:idtermsCondition> as by default (if nothing is given) it is considered as string.
urls.py
urlpatterns = [
path('uploadfile/', views.uploadFile, name="uploadFile"),
path('verPDF/<int:idtermsCondition>/', views.verPDF, name='verPDF'),
]
And the {{uploadPDF.url}} already has the url (full path to the media directory) and try to use <embed> tag so:
<div>
<embed id="verPDF" src="{{uploadPDF.url}}" width="500" height="375" type="application/pdf">
</div>
Note: Always add / at the end of every route
Finally I can solve it, I had problems in my views.py and in the html, when I called uploadPDF my views called another name which was loadpdf and when I rendered it it was another name.
now, views.py:
``def uploadFile(request):
user = request.user
if user.is_authenticated:
if user.is_admin:
if request.method == "POST":
# Fetching the form data
fileTitle = request.POST["fileTitle"]
loadPDF = request.FILES["uploadPDF"]
if termsCondition.objects.all().exists():
listfiles = termsCondition.objects.all()[:1].get()
listfiles.uploadPDF = loadPDF
listfiles.save()
else:
# Saving the information in the database
termscondition = termsCondition.objects.create(
title=fileTitle,
uploadPDF=loadPDF
)
return redirect('uploadFile')
else:
if termsCondition.objects.all().exists():
listfiles = termsCondition.objects.all()[:1].get()
return render(request, 'subirTerminos.html', context={
"files": listfiles.uploadPDF
})
else:
listfiles = {}
return render(request, 'subirTerminos.html', context={"files": listfiles})
else:
messages.add_message(request=request, level=messages.SUCCESS,
message="No tiene suficientes permisos para ingresar a esta página")
return redirect('customer')
else:
return redirect('login2') ``
and html:
<h1 class="title">Visualizador de PDF</h1>
<embed id="verPDF" src="{{files.url}}" width="500" height="375" type="application/pdf">

Why does my Submit button renders a page that is blank when it is supposed to contain the data that was just updated?

I'm trying to update the values of my database using a HTML Form.
When I Click Edit it brings me to the edit the values above.
However as I am clicking the submit button, it returns me a database but with no other values.
Is there anyone that can help me understand what I did wrong and point me to the right documentation (if any)
editclaims.html:
<div class="arrange2">
<h1>Edit Claim Form - #{{claims.id}} </h1>
</div>
<form method="POST" action="/update/{{claims.id}}">
{% csrf_token %}
views.py:
def editclaims(request,id):
context = initialize_context(request)
user = context['user']
claims = SaveClaimForm.objects.get(id=id)
if request.method == 'POST':
name = request.POST['name']
email = request.POST['email']
claim = request.POST['claim']
claimtype = request.POST.get('claimtype')
description = request.POST['description']
receipt = request.FILES['receipt']
cheque = request.POST.get('Cheque')
form = SaveClaimForm(name=name, email=email, claim=claim, claimtype=claimtype, description=description, receipt=receipt, cheque=cheque)
form.save()
return render(request, "Login/editclaims.html", {'claims':claims, 'user':user})
urls.py:
urlpatterns = [
path('existingclaims/', views.viewclaims, name='existingclaims'),
path('editclaims/<int:id>', views.editclaims, name='editclaims'),
path('update/<int:id>', views.updateclaims, name='updateclaims'),
]
It may not resolve all your problems but it will be more readable as answer.
When you get data from HTML then you create new object SaveClaimForm and it will have new ID and you will have the same object in two rows.
You have to get original Claim from database and update values in this object and save it - and then it will save it with original ID and you will have only one `object in database
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.name = request.POST['name']
claims.email = request.POST['email']
claims.claim = request.POST['claim']
claims.claimtype = request.POST.get('claimtype')
claims.description = request.POST['description']
claims.receipt = request.FILES['receipt']
claims.cheque = request.POST.get('Cheque')
# save it with original `ID`
claims.save()
return render(request, "Login/editclaims.html", {'claims':claims, 'user':user})
BTW:
Django has special class ModelForm to create forms in HTML. It may also have methods to check if data in HTML are correct - ie. if fields are not empty, if email is correctly constructed (name#domain.com), if phone has only numbers, etc. So using ModelForm can be more useful then writing all manually in code.

How to upload an image to a folder and pass its path to a view function in django?

I want to upload an image file using an input file tag from a django template. Then i want to do 2 things:
1) First i want to store the uploaded image in a directory in my project. I want to upload the file in img directory under static directory in my app so to access it easily.
2) Second i want to send the filename of this newly stored image to a view function called detect_im()
TEMPLATE:
<form style="display:inline-block;">
<input type="file" class="form-control-file">
<input type="submit" value="Upload"=>
</form>
VIEW FUNCTION in views.py
def detect_im(request):
haar_file = 'C:\\Users\\Aayush\\ev_manage\\face_detector\\haarcascade_frontalface_default.xml'
datasets = 'datasets\\'
myid = random.randint(1111, 9999)
path = "C:\\Users\\Aayush\\ev_manage\\face_detector\\" + datasets + str(myid)
if not os.path.isdir(path):
os.mkdir(path)
(width, height) = (130, 100)
face_cascade = cv2.CascadeClassifier(haar_file)
filename = "" //I WANT THE STORED FILE NAME VALUE HERE TO COMPLETE THE PATH FOR FURTHER DETECTION PROCESS BY OPENCV.
image_path = "C:\\Users\\Aayush\\ev_manage\\face_detector\\static\\img\\" + filename
count = 1
while count < 30:
im = cv2.imread(image_path)
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 4)
for (x, y, w, h) in faces:
cv2.rectangle(im, (x, y), (x + w, y + h), (255, 0, 0), 2)
face = gray[y:y + h, x:x + w]
face_resize = cv2.resize(face, (width, height))
cv2.imwrite('% s/% s.png' % (path, count), face_resize)
count += 1
key = cv2.waitKey(10)
if key == 27:
break
return render(request, 'add_dataset.html', {'uid': myid})
The final flow should be like that, user adds the image and click on upload then image gets uploaded to directory and detect_im() function is called with the filename and that filename is used in the path variable for the opencv to detect the face out of it.
Thanks for reading. Please post an answer with at least some code additions because i am a rookie in python.
upload an image file using an input file tag from a django template and
store the uploaded image in a directory in my project
Try to use Pillow:
First, install the package
pip3 install Pillow
Next, create a field and function
in your models.py:
# models.py
import os
from django.db import models
from django.utils.timezone import now as timezone_now
from django.utils.translation import ugettext_lazy as _
def upload_to(instance, filename):
now = timezone_now()
base, ext = os.path.splitext(filename)
ext = ext.lower()
return f"(your_dir)/{now:%Y/%m/%Y%m%d%H%M%S}{ext}"
# Do add the date as it prevents the same file name from occuring twice
# the ext is reserved for the file type and don't remove it
class MyExampleClass(models.Model):
...
picture = models.ImageField(_("Picture"), upload_to=upload_to, blank=True, null=True)
Then, create a form to upload the image:
# forms.py
from django import forms
class MyExampleForm(forms.ModelForm):
class Meta:
model = MyExampleClass
fields = ["picture"]
Remember to render it in a view and your url:
# views.py
from django.shortcuts import render, redirect
from .forms import MyExampleForm
def add_image(request):
form = MyExampleForm()
if request.method == "POST":
form = MyExampleForm(data=request.POST, files=request.FILES)
if form.is_valid():
form.save()
return redirect("")
else:
return render(request, "myexamplehtml.html", {"form": form})
# quotes/urls.py
from django.urls import path
from .views import MyExampleView
urlpatterns = [
path('foobar/', add_image, name='myexampleview'),
]
Finally, add it in your HTML file:
{% block content %}
<form method="post" action="your_url" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">submit</button>
</form>
{% endblock %}
About the second part, I think that you can access your user's variable like this:
MyExampleModel._meta.get_field('picture')
and then put this code into wherever you want it to function
Hope that this works!
You can get the Path of the uploaded file by following this...
#myImage is your Model
#image is your Model field
myImage.save()
got_url = Image.image.url
print(got_url)
Answer link : I am wondering how can we get path of uploaded Image (imageUrl) in views.py file in Django

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