4

settings.py

STATIC_URL = '/static/'
STATICFILES_DIRS= [str(BASE_DIR.joinpath('static'))]
STATIC_ROOT = BASE_DIR.joinpath('staticfiles')
MEDIA_URL = '/media/'
MEDIA_ROOT = str(BASE_DIR.joinpath('media'))

config/urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('proj.urls')),
] += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

models.py

class Book(models.Model):
    image = models.ImageField(upload_to='upload/', blank=True, default=None, null=True)

views.py

class BookCreateView(CreateView):
    model = Book
    template_name = "book_new.html"
    fields = "__all__"

book_new.html

{% extends 'base.html' %}

{% block content %}
    <h1>New Book</h1>
    <form action="" method="post" enctype="multipart/form-data">{% csrf_token %}
        {{ form.as_p }}
        <input type="submit" value="Save">
    </form>
{% endblock content %}

proj/urls.py

urlpatterns = [
    path("", home_view, name="home"),
    path("book/new/", BookCreateView.as_view(), name="book_new"),
]

I have written this code which will upload the image to /media/upload/ and the path of the file will be saved on the database like upload/image_file.png. I don't want to store the file path in the database, I want to read the file, convert it to base64 and store the encoded string in the database. How can I do that? I've searched a lot and tried to figure this out on my own as I usually do, but this one's a little hard for me, here's what I've read so far:

Shayan
  • 709
  • 1
  • 15
  • 31
  • Forget about base64; use `models.BinaryField` instead of `models.ImageField`. You can store an arbitrary `bytes` object in it. Presumably the uploaded image is already a `bytes` object, so you don't even have to decode or re-encode it. You will also need to add a route that actually serves the image. – Thomas Feb 03 '22 at 12:39
  • 1
    I think it's not worth doing that, because in the end you will receive your full-sized image go from database to server, then from server to client. As far as django has sync database connection, it is not good to request big/hard requests – sudden_appearance Feb 03 '22 at 12:42

1 Answers1

0

ImageField, as far as the database is concerned, is a simple VARCHAR(100). That means you can only store up to 100 characters in it. Most of the "magic" of ImageField is that it provides an interface to store the file in the MEDIA_ROOT with particular paths and provides tools to retrieve it again. It also provides tools to store height and width of the image and provide form elements.

If you really want to store binary files in the database, you'll have to create your own system using a BinaryField or something like that. Remember that you'll likely also need to store some meta information such as filename or mimetype (since the raw binary won't have that).

In most cases, storing binary files in a database is usually not the best solution as it'll be slower than just fetching files from a file system. If you want the files to be accessible between machines, then you'd be better with a network mount or something like AWS S3.

Tim Tisdall
  • 9,914
  • 3
  • 52
  • 82