Pages

Sunday, June 25, 2017

Django Remind Image File upload handling and retrieving

Django Remind Image File upload handling and retrieving


The handling of image/file in Django is a bit complicated than PHP, since PHP basically uses HTML syntax to display a file.

Assuming we are building a blog, and want to to user to add photo to their posts

Here are the steps required - I write this to serve as a reminder and quick reference for myself, so I am going to do this quick.

1. Specify the MEDIA_ROOT and MEDIA_URL in the settings.py that you want to use, if not specified, the uploaded files will be stored at the projects BASE_DIR

2. Start serving files in MEDIA_ROOT by adding settings in myproject/settings.py, use shortcut method provided in the documentation in development

3. Create a model in models.py to help store the image, added an attribute to store the location that the image file will be uploaded, such as imageFile = models.ImageField(upload_to = someLocation)

3.1 (optional) Since we are adding photos for a blog post, we can make accessing the photos of a blog post easier by adding a ForeignKey field in the photo model, and point it to an blog post entry.

4. build a form in a template with enctype = multipart/data and method = post attributes

5. write a view function that process the POSTed data, point the form in step 1 to this view function by adding an ACTION attribute. 

6. In the view function, the files submitted via the POSTed form is available in the variable request.FILES dictionary, use the name of the type=file input in your form to access the file in the dictionary, say request.FILES[profile-pic]

7. handle said file, and save() it, if you have added a ForeignKey field in the photo model class, remember to save the blog post entry object before saving the photo(s), if the blog post isnt saved first, an error would occur since the photo object creation requires a ForeignKey field which is bonded to an BlogPost object

8. To retrieve the photo in a blog post template, pass the photo of a blog post like this 
photos = BlogObject.photo_set.all(), 

then

return render(request, template.html, {photo: photos })

9. In the blog post template, display the photo like this:

{% if photo %}
    {% for image in photo %}
          <img src = {{ image.ImageFile.url }}                 
    {% endfor %}

{% endif %}

Note that the ImageFile variable here is the attribute we set earlier in the models.Photo class, which is an ImageField() object. 

ImageField objects has a .url attribute that store the relative location of the image file. Therefore, we can use this to be the src attribute of our img tags.

for FileField, the usage is quite similar, but instead we would have to provide it through an <a> tag to render a file download link.

Thats it, its quite complicated to set up properly for the first time, but it would get better later :D

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.