I was wondering if there is a field (A model field) that represents a remote image.
What I need is to add an image field to my model that isn't stored locally, but is given a remote URL and can only be viewed, not edited or uploaded.
Edit: To make myself more clear, I meant I need a field such as URLField that can store a URL (to the image) but that in the admin page, (or other forms) it will show the image like ImageField does.
A URLField is an extension of the CharField and can store a valid URL that points to an image. Note that you will not be able to upload an image, only reference an image that already exists on the web.
class MyModel(models.Model):
remote_image = models.URLField()
In your view you can set the remote image with a string:
my_instance = MyModel()
my_instance.remote_image = 'http://example.com/images/example.jpg'
my_instance.save()
You can display the remote image in your template by setting the src attribute:
<img src="{{ my_instance.remote_image }}">
Django has a file storage API. The default storage class is the FileSystemStorage, that stores your images using the file system.
One of the best things about Django is its huge ecosystem: you can find storage classes for S3 and other popular hosting services.
It is somewhat easy to write your own, also.
You can use URLField to store the source URL and handle viewing the image a django View that you build, I can imagine that your django View can read data using your model (including the image source URL), set it in context dictionary object, which can be read from the HTML template of your view to display the image.
Please read about django Views and Templates for more info.
Related
I have field:
image = models.ImageField(
max_length=500,
upload_to='images'
)
and some settings to upload an image to AWS S3 Bucket, where PublicMediaStorage is my custom storage:
PUBLIC_MEDIA_LOCATION = 'media'
AWS_S3_MEDIA_ENDPOINT_URL = env('AWS_S3_MEDIA_ENDPOINT_URL', None)
DEFAULT_FILE_STORAGE = 'new_project.storages.PublicMediaStorage'
I need to store and get my images from database(postgres).
For now my image stores at the database like
here.
And if i write image.url i will get the url of my image(that's why I don't need to store urls of images in my database).
But is it right way? Maybe it will be better to store immediately links at the database? Any solutions?
OP is doing well using ImageField . OP might want to add blank=True so that OP's forms don't require the image.
image = models.ImageField(upload_to='images', blank=True)
The reason to use ImageField is that it checks whether the image is valid and also uploads it to the right location, which is something one wouldn't get with a simple URL. That is why the docs mention it requires the Pillow library.
With regards to the DB path, it is better to store the the relative path. OP can access the rest of the URL in the template if needed too and if the rest of the URL changes then OP only has to change in one place and not in the database(s).
I'm trying to use REST API framework in Django and I noticed that the JSON format for it always takes the particular model's field name as the key. eg: A field called image in my model stores images in the database. When viewed in JSON format, it's seen as : {"image": "apple.png"}
I want to change the image to my own personalized label. How can I do this?
You can create a serializer with your custom label name and then use custom attribute to instruct drf to use image field data.
Something like
custom_label = serializers.TextField(source="image")
So i wanted to ask how does these 2 fields works.
As my friend told me that his ios will sent byte format image to me, does it matter if i use imageField instead of BinaryField ?
I did try adding a Binaryfield into my User models but when testing it out on django admin and also django rest framework api, it doenst work
In django admin : the binaryfield did not appear in it
In django rest framework : got an error that says editable is false for binary field. Setting the binaryfield editable=True also doesnt work.
The documentation about Binaryfield in django is also not much.
Can anyone please explain to me how does these 2 field work ? does sending byte format to the imagefield work ?
The ImageField takes care of pictures. Otherwise, ImageField and FileField are the same. Both store the path to a file of the pysical volume.
And both do not meet the requirements.
The database requires a BinaryField:
models.BinaryField (blank = true, null = true, editable = true)
So far so good. With editable = True, the field should appear in the admin interface. But to see the picture, it has to be transformed again before
encoded = b64encode (model.image) .decode ('ascii')
and e.g. poured into a form.
render_to_string ('lib / forms / imageform.html', {"image": encoded}, request).
The form element in my case looks like this:
<form id = "{{form.fid}}" class = "form-horizontal data-form" enctype = "multipart / form-data" method = "post">
<img src = "data: image / png; base64, {{image}}">
</ Form>
ImageField or FileField is what you should use to save images. Both of these fields just save the file_path (Ex: /static/user_images/smith.jpg) to the physical image stored on the server.
For more detail read this FileField and ImageField
BinaryField not used to save images. For more detail
Note : that you never store a physical file to a Database. That is you don't use BinaryField for images.
I have a Page model that basically describes an HTML page. Pages are then served with URLs, such as http://www.mysite.com/page/1234/ for the page of id (pk) 1234.
I want to be able to add or attach images to my page. Therefore, I would like to use an Image class with a foreign key to a Page object:
class Page(models.Model):
title = ...
content = ...
class Image(models.Model):
page = models.ForeignKey(Page)
image = models.ImageField(...)
Here is my problem: I would like to deliver images to the client with urls of the form:
http://www.mysite.com/images/1234/image_name.jpg, i.e a URL that includes the page id. Also on the server, the paths should reflect the page structure: /path/to/media/images/1234/image_name.jpg
I don't know how to tackle this problem. On one hand, I would like to keep the features of an ImageField related to path formatting. For example when uploading two images with the same name, Django creates two paths ending with "image.jpg" and "image_2.jpg" or so to make the difference between both images.
On the other hand, the upload_to option has limited capability, and I don't know how to insert the page id in the path. Especially, some tricky cases such as uploading an image at the same time a page is created (using the same form), which means a page id should be generated before uploading the image.
Is it reasonably easy to make an image model that would behave as described above? If so, how do I have to modify the Image model to insert the page id in the image path?
I have seen the question Customize save path for ImageField, but it does not address the problem of primary key that might not be assigned.
Thanks.
Actually, a simple function passed as an upload_to parameter works, and there is no problem of non-existing id. So I guess that Django's default behaviour saves the image after saving the parent page model, as I wanted to.
In the Image model:
image = models.ImageField(upload_to=get_image_path)
with the following function:
def get_image_path(instance, filename):
return 'pics/' + str(instance.page.id) + '/' + filename
I'm trying to create some kind of 'media manager' model which will allow the user to upload different kings of media (images, swfs, pdfs) similar to the way WordPress does. My media model looks something like this:
class Media(models.Model):
id = models.AutoField(primary_key=True)
url = models.FileField(upload_to="uploads")
mimetype = models.CharField(max_length=64, editable=False)
created = models.DateTimeField(auto_now_add=True, editable=False)
When a user uploads a file, I want to first determine what kind of file it is and if it's an image, manipulate it further. I want to be able to to specify the dimensions (crop) of the uploaded image via a view, so when I call the .save() method, the model will resize and crop the image, upload it and populate the database with the url to the file.
I also want to ensure that the upload of the image is done AFTER the post processing (cropping etc), I have no need to keep the original file.
So the question I am asking is how do I got about passing parameters to the FileFields save method (so I can pass dynamic properties for image post processing) and how can I ensure the post processing is done BEFORE the image is uploaded?
Edit: When I say before the image is uploaded, I mean before it's saved to it's final destination. I understand the image has to go int othe tmp folder first before I can post process it. Sorry for the misleading question.
Hope someone can help :)
You cannot do anything before the image is uploaded (because you have nothing to work with).
But if you want modify the image before saving it into db, you can do it in model's save() method, before calling parent's save()
If you are uploading it via admin, override method save_model() in admin.py, ie:
def save_model(self, request, obj, form, change):
file = request.FILES.get('url') # name of field
if file:
# proceed your code
return super(AdminClassName, self).save_model(request, obj, form, change)
Here is my code how to change file before actually upload it. I think you should get my idea
from django.core.files.uploadedfile import InMemoryUploadedFile
#....
#some form
def clean_avatar(self):
av = self.cleaned_data['avatar']
resized = make_avatar(av,65) # My custom function than returns image
return InMemoryUploadedFile(resized, av.field_name, av.name, av.content_type, resized.len, av.charset)
You can read django code for InMemoryUploadedFile "documentation".
And in your resize/crop function you should use StringIO not file to save result
How could the processing be done before the image is uploaded? That doesn't make sense. The server doesn't have any access to the file until you upload it.
If you actually want to handle the file before it's saved, you can write a custom upload handler. You can test there whether the file is an image, then crop it appropriately, before saving. (You'll need the Python Imaging Library for both of those tasks.)