Django using media (uploading files and adding them to templates) - python

I'm trying to learn how to upload files in Django and use them in templates.
My goal is to create post form with multiuplad field but im starting with simple things. Im trying to uplad single files and add link to those files in tempalate. Thats what i have done so far:
model:
class Adds(models.Model):
author = models.ForeignKey(User, verbose_name=u"Autor postu", blank=True, null=True)
image = models.FileField(upload_to='photos/')
def get_absolute_url(self):
return settings.MEDIA_ROOT+"\%s" % self.image.name
I've added function get_absolute_url to get url with MEDIA_ROOT added. Its not working because MEDIA_ROOT path part is with "\" and the res is separated with "/". Thats first question how to make this function work properly.
I am adding links like this {{plik.get_absolute_url}}
but i read about url function so i tryed somethin like this {{plik.image.url}}but it returns url without MEDIA_ROOT part so only "upladed_to_name/file_name".
My MEDIA_ROOT in settings:
MEDIA_ROOT= os.path.join(os.path.dirname(BASE_DIR), "static_env", "my_static", "media")
In shell i have somethin like this:
In [1]: from voiceManaging.models import Pracownik
In [2]: i=Pracownik.objects.get(pk=1)
In [3]: i.zdjecie.url
Out[3]: 'photos/mama_0SADn31.jpg'
In [4]: i.zdjecie.path
Out[4]: u'E:\\Django\\Projects\\KCKAPP\\static_env\\media\\photos\\mama_0SADn31.
jpg'

Because you're using the default FileSystemStorage class, providing you have defined a MEDIA_URL in your settings the storage class can build a URL for your uploaded files using that setting & the corresponding file name using the .url attribute.
So using your example;
class Adds(models.Model):
author = models.ForeignKey(User, blank=True, null=True)
image = models.FileField(upload_to='photos')
To illustrate the attributes & what they each do for the FieldField take a look at this;
>>> add = Adds.objects.get(author="Mark")
>>> add.image
<FileField: mark.jpg>
>>> car.photo.name
'photos/mark.jpg'
>>> add.image.path
'/media/photos/mark.jpg'
>>> add.image.url
'http://media.example.com/photos/mark.jpg'
So MEDIA_URL should be a URL where your web server is configured to serve the files stored in MEDIA_ROOT.

Related

Storing files Django

I am building an website using django in which I have to store a lot of files.
I have a view, which takes file from the user and saves it.
def store(request):
if request.method == "POST":
sender = request.POST['sender']
file = request.POST['file']
I have a model in which i save these data:
class t_data(models.Model):
sender = models.TextField()
file = models.FileField(upload_to='files')
and I have this on my settings file:
MEDIA_ROOT = os.path.join(BASE_DIR,"media")
MEDIA_URL = '/media/'
Many files can have same name. Should I rename before saving them? How should I save them. There will be many users, So how can I distinguish files for each user?
my question is : **What is the best way to store files in a django application?**Please
Thank you
Try this solution. It creates a random string and adds it to the file name - How to Rename an Image or File in an Upload in Django

Django MEDIA_ROOT pointed to network drive

I'm trying to get files uploaded through the Django admin site to be placed on a network drive. Lets say the path to this drive is '\\FILESERVER\Django'.
My initial thought was to just set my media root to the same path I'd use to access the drive via File Explorer:
#settings.py
MEDIA_ROOT = r'\\FILESERVER\Django'
An Example Model:
#models.py
class Article(models.Model):
title = models.CharField(max_length=128)
pdf = models.FileField(upload_to='articles', blank=True, null=True)
def __str__(self):
return self.title
But when I upload a file, It just creates the folder on my local C: drive.
(e.g. C:\FILESERVER\Django\articles). Is there a way I can tell Django that this is supposed to be a path to a network drive?
Note: This is a Django 2.0.4 app running on a windows machine.
I believe what you're looking for is in pathlib. Have a look here:
https://docs.python.org/3/library/pathlib.html#methods-and-properties
Something like PureWindowsPath('//FILESERVER/Django').drive should do the trick for MEDIA_ROOT, IIRC.
If you use a network file server,you may need a customized django file storage class.

Mezzanine FileBrowser not allowing me to select an image

I am using mezzanine to deploy a simple blog website. Each part of the website has a header that needs to be easily changed by the blog team. My solution was to make a model with a FileField for the blog team to change a pages header on the admin page. I am using S3 bucket to store static and media files.
Chief Complaint: When a user goes to upload a photo, the file gets uploaded to the S3 bucket, but I can't click the select button on the file that I am looking to use. Mezzanine file selector button.
My implementation:
I mainly used this tutorial to implement the backend for the file uploader (I only used S3).
settings.py
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
STATICFILES_LOCATION = 'static'
STATICFILES_STORAGE = 'custom_storages.StaticStorage'
STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN,
STATICFILES_LOCATION)
MEDIAFILES_LOCATION = 'media'
MEDIA_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN,
MEDIAFILES_LOCATION)
DEFAULT_FILE_STORAGE = 'custom_storages.MediaStorage'
MEDIA_ROOT = ''
custom_storages.py
from django.conf import settings
from storages.backends.s3boto import S3BotoStorage
from filebrowser_safe.storage import S3BotoStorageMixin
class StaticStorage(S3BotoStorage, S3BotoStorageMixin):
location = settings.STATICFILES_LOCATION
class MediaStorage(S3BotoStorage, S3BotoStorageMixin):
location = settings.MEDIAFILES_LOCATION
models.py
class Header(models.Model):
file = FileField("File", max_length=200, format="Image",
upload_to=upload_to("galleries.GalleryImage.file", ""))
# other fields ...
Error messages:
FB_FileBrowseField.js:16 Uncaught TypeError:
Cannot set property 'value' of null at FileSubmit (FB_FileBrowseField.js:16)
at HTMLAnchorElement.onclick (?pop=1&type=Image:230)
FB_FileBrowserField.js
function FileSubmit(FilePath, FileURL, ThumbURL, FileType) {
var input_id=window.name.replace(/____/g,'-').split("___").join(".");
// left out variables for post simplicity
input = opener.document.getElementById(input_id);
// set new value for input field
input.value = FilePath;
// cut out rest of the code
The problem seems to be that the opener method returns null. I assume this is because it can't find the input_id in the html. I can't seem to figure out why this is an error, since I am using the out of the box software. I'm wondering if anyone could point me in the right direct for better diagnosing this problem and potentially fixing it.
You're probably uploading a file with an extension that Mezzanine does not recognize as an image.
The default extensions are set in filebrowser-safe:
'Image': ['.jpg', '.jpeg', '.gif', '.png', '.tif', '.tiff', '.svg']
You can modify or create your own extensions with the FILEBROWSER_EXTENSIONS setting, e.g.:
FILEBROWSER_EXTENSIONS = {
'Image': ['.jpg', '.jpeg', '.gif', '.png', '.tif', '.tiff', '.svg', '.image'],
}
Alternately, you can modify or create your own format with FILEBROWSER_SELECT_FORMATS, which takes a dictionary of names (to pass to FileField's format parameter) and lists of extensions (must be defined in the default EXTENSIONS or FILEBROWSER_EXTENSIONS). For example :
FILEBROWSER_SELECT_FORMATS = {
'Multimedia': ['Image', 'Video', 'Audio'],
}

How do I assign images stored locally to an ImageField field and return its URL in Django?

I'm new with Django and I have a problem I hope you can help me to solve.
First of all, I'm working with Django 1.8.3 and Python 2.7.6 on a Virtual Env using Apache and Postgres as my DBMS.
I have the following model on my models.py file:
class Hotel(models.Model):
# ...
name = models.TextField(blank=True, null=True)
img = models.ImageField(upload_to='images/',blank=True, null=True)
stars = models.IntegerField(blank=True, null=True)
# ...
class Meta:
managed = False
db_table = 'hotel'
My views.py file looks like this
from django.http import HttpResponse, Http404
from webServices.models import Hotels
from django.core import serializers
from django.core.exceptions import ObjectDoesNotExist
import json
# ...
def all_hotels(request):
hotels = Hotel.objects.values('name', 'img', 'stars')
data = json.dumps(list(hotels), indent = 4)
return HttpResponse(data, content_type='application/json')
And my MEDIA_URL and MEDIA_ROOT variables on settings.py file are defined as follows:
MEDIA_URL = '/media/'
MEDIA_ROOT = '/path_to_my_projects_directory/media/'
As you can see, I'm working on a server that returns a json with the data for every hotel in the DB. It certainly works fine.
Json's img field has been 'null' until now that I need to associate every image stored locally to its hotel and return its URL in it.
The problem is I don't know how.
It's good to know as well that the DB is updated via python script since the data reside in a Google SpreadSheet (I'll show you if asked).
I've been searching all day long and I've found this post
how to manually assign imagefield in Django
and this article
http://www.revsys.com/blog/2014/dec/03/loading-django-files-from-code/, but I need them to be a little bit more specific.
Hi try this one in your views.py
from django.conf import settings
url = request.scheme
url += "://"
url += request.META['HTTP_HOST']
url += settings.MEDIA_URL
_len = len(hotels)
_range = range(0, _len)
hotels = Hotel.objects.values('name', 'img', 'stars')
for x in _range:
hotels[x]['img'] = "%s%s" % (url, hotels[x]['img'])
data = json.dumps(list(hotels), indent = 4)
return HttpResponse(data, content_type='application/json')

Attach an image into a Django Model

Making a basic Q&A site and want to associate each question with an image (admin uploaded) and if there is no respective image, puts it with a default "No Image" placeholder.
I have two models, Question and Answer (see below). Each question needs to have an image associated with it, so I thought the best way was to attach attribute ImageField with the Question model.
#models.py
class Question(models.Model):
title = models.CharField(max_length = 500)
picture = models.ImageField(height_field = '250',
width_field = '200',
upload_to = 'images')
def __unicode__(self):
return self.title
When I runserver though, tells me to download Python Imaging Library, and when I do get an error (different problem).
Taking a step back, what is the best way to add an image to a model in Django?
Forget PIL...
Use a location URL DB entry. Instead of having an ImageField(), use
picturepath = models.CharField(255)
that contains a URL to the static location of the image.
so if STATIC_URL = "http://127.0.0.1/static/"
and picturepath = "images/poots.png"
Then, pass that information along in the view, and use this in the template:
<img src="{{ STATIC_URL }}{{ question.picturepath }}">
will provide
<img src="http://127.0.0.1/static/images/poots.png">

Categories