Mezzanine FileBrowser not allowing me to select an image - python

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'],
}

Related

Problem uploading images to S3 Bucket from Django App [duplicate]

This question already has answers here:
Save uploaded image to S3 with Django
(2 answers)
Closed 1 year ago.
My problem is that images stored in media folder are not transferring to S3 Bucket. I tested with other file from request and the file did transfer, so I assume settings.py must be OK.
From views.py ->
This works:
if request.method == 'POST':
imageFile = request.FILES['images']
upload = Upload(file=imageFile)
upload.save()
image_url = upload.file.url
print(image_url)
This does not work:
for i in os.listdir(folder):
f = os.path.join(conf_settings.MEDIA_ROOT,company, i)
upload = Upload(file=f)
upload.save()
No error but it just does not work.
This also does not work:
for i in os.listdir(folder):
with open(os.path.join(folder, i)) as f:
upload = Upload(file=f)
upload.save()
>The error I am getting is:
>
>Exception Value:
>'_io.TextIOWrapper' object has no attribute '_committed'
>
>at upload.save()
This is my storage_backend.py
from django.conf import settings
from storages.backends.s3boto3 import S3Boto3Storage
class MediaStorage(S3Boto3Storage):
location = 'media'
default_acl = 'public-read'
file_overwrite = True
This is my model.py
class Upload(models.Model):
uploaded_at = models.DateTimeField(auto_now_add=True)
file = models.FileField()
I am uploading a .ZIP file with images. Unzipping it and saving them to media folder, then I want to upload from media folder to S3 Bucket. This operation fails.
The file in request.FILES is the Zip file, which I am using to test that all settings.py for AWS should be correct because it does transfer correctly.
I believe my issue has to do with the way I am reading the file and passing it.
So after many hours....this actually worked. Although the transfer is a bit slow, im sure there must be a better way.
https://stackoverflow.com/a/53260957/11116189

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

How to auto-upload an image from django app to aws s3

When a user creates or registers for a new account on my website, an image is created(generated) and is supposed to be uploaded to the s3 bucket. The image is successfully created(verified by running the ls command on the server in the media directory) but it's not getting uploaded to s3. However, when I try uploading an image for a user account from the admin panel, changes are correctly reflected in s3 (i.e newly uploaded image from admin panel is shown in s3 bucket's directory, but this is not feasible as the users cannot be given admin panel access). I aim to auto-upload the generated image to the s3 bucket when a new account is created.
Here's some related code.
views.py
def signup(request):
if request.method == "POST":
base_form = UserForm(data=request.POST)
addnl_form = AddnlForm(data=request.POST)
if base_form.is_valid() and addnl_form.is_valid():
usrnm = base_form.cleaned_data['username']
if UserModel.objects.filter(user__username=usrnm).count()==0:
user = base_form.save()
user.set_password(user.password)
user.save()
#print(img)
addnl = addnl_form.save(commit=False )
addnl.user = user
img = qr.make_image() #create a qr code image, full code not included.
img.save('media/qrcodes/%s.png'%usrnm)
addnl.qr_gen = 'qrcodes/%s.png'%usrnm
addnl.save()
else:
messages.error(request,base_form.errors,addnl_form.errors)
else:
base_form = UserForm()
addnl_form = AddnlForm()
return render(request,'app/signup.html',{'base_form':base_form,'addnl_form':addnl_form} )
models.py
class UserModel(models.Model):
.
.
.
qr_gen = models.ImageField(upload_to='qrcodes',default=None,null=True,blank=True)
settings.py
DEFAULT_FILE_STORAGE = 'project.storage_backend.MediaStorage'
storage_backend.py
from storages.backends.s3boto3 import S3Boto3Storage
class MediaStorage(S3Boto3Storage):
location = 'media'
default_acl = 'public-read'
file_overwrite = False
UPDATE
Instead of auto-generating, an image and uploading it to s3, if I upload any image in the registration form, even in that case it's successfully uploading to s3, the only case where it fails is when I need to auto-upload without user intervention.
Please help me solve this problem. Thank you.
I would recommend taking a look at django-storages which automates all of this so you should only worry about the form and the view instead of anything else. In there you will find help on how to deal with images easily.
Instead of globally setting media storage settng, set it on the field
class UserModel(models.Model):
...
qr_gen = models.ImageField(upload_to='qrcodes',storage=MediaStorage())
Auto uploading an image directly to s3 requires one to directly communicate with S3's backend API. Plainly using django-storages or tweaking DEFAULT_FILE_STORAGE path isn't just enough as it only helps to point user-uploaded files to the specified s3 bucket/path. This problem can be tackled using the boto3 library's upload_file method.
Usage example:
import boto3
s3 = boto3.resource('s3')
s3.Bucket('mybucket').upload_file('/tmp/hello.txt', 'hello.txt')
Params:
Filename (str) -- The path to the file to upload.
Key (str) -- The name of the key to upload to.
ExtraArgs (dict) -- Extra arguments that may be passed to the client operation.
Callback (function) -- A method which takes a number of bytes transferred to be periodically called during the upload.

Wrong media location using Django management command

I'm downloading an image and saving it to a models image field, on a separate media app. Everything was working fine while the code was in a view but soon as I moved the code into a management command I can't get the image to save into the separate media location. Before it was correctly saving to /home/me/webapps/myapp_production_media/images now the files are being saved incorrectly to /home/me/webapps/myapp_production_django/src/media/images
command:
download_image('temp', model_instance.image, new_image)
def download_image(name, image, url):
input_file = StringIO(urllib2.urlopen(url).read())
output_file = StringIO()
img = Image.open(input_file)
if img.mode != "RGB":
img = img.convert("RGB")
img.save(output_file, "JPEG")
image.save(name+".jpg", ContentFile(output_file.getvalue()), save=False)
model:
class MyModel(models.Model):
image = models.ImageField(upload_to='images', null=True, blank=True)
I've added myapp_production_media/images path to the name+".jpg" but it doesn't change anything. I'm guessing this is happening because the image field in the model doesn't access the media_root in settings.py (as the code is a management command)?
Double-check that you are using the same settings file when running the management command. Production settings are usually not configured as default and in these cases need to be given on command line.
I suggest doing the following at the beginning of the command file.
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings")
where app.setting is where the setting.py resides.

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

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.

Categories