File Fields
Learn how to work with file fields in Djing.
Djing offers several types of file fields: File
, Image
, Avatar &
Gravatar
. The File
field is the most basic form of file upload field, and is the base class for both the Image
and Avatar
fields. In the following documentation, we will explore each of these fields and discuss their similarities and differences.
Overview
To illustrate the behavior of Djing file upload fields, let’s assume our application’s users can upload “profile photos” to their account. So, our users
database table will have a profile_photo
column. This column will contain the path to the profile photo on disk or Django Storage.
Defining the Field
Next, let’s attach the file field to our User
resource. In this example, we will create the field and instruct it to store the underlying file on the django storage
.
from djing.core.Fields.File import File
from djing.core.Http.Requests.DjingRequest import DjingRequest
from djing_admin.app.Djing.Resource import Resource as DjingResource
class User(DjingResource):
# ...
def fields(self, request: DjingRequest):
return [
File.make("Avatar"),
]
When uploading files, Django Storage must be configured in settings.py
STORAGES = {
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
"OPTIONS": {
"location": BASE_DIR / "media", # Replace with your media directory path
},
},
"staticfiles": {
"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
},
}
MEDIA_URL = "/media/"
MEDIA_ROOT = BASE_DIR / "media"
When a file is uploaded using this field, it by default store all files to media folder.
Disabling File Downloads
By default, the File
field allows the user to download the corresponding file. To disable this, you may call the disable_download
method on the field definition:
from djing.core.Fields.File import File
from djing.core.Http.Requests.DjingRequest import DjingRequest
from djing_admin.app.Djing.Resource import Resource as DjingResource
class User(DjingResource):
# ...
def fields(self, request: DjingRequest):
return [
File.make("Avatar").disable_download(),
]
Manually Storing files by passing Storage callback
By default, you don't have to do anything special but only specifying Storage information in settings.py, but if you wish to store file manually, you can pass storage_callback to File field.
import os
from Illuminate.Support.Str import Str
from djing.core.Fields.File import File
from djing.core.Http.Requests.DjingRequest import DjingRequest
from djing_admin.app.Djing.Resource import Resource as DjingResource
from django.db.models import Model
from django.core.files.storage import Storage
from django.core.files.base import ContentFile
class User(DjingResource):
# ...
def _storage_callback(
self,
request: DjingRequest,
request_attribute: str,
model: Model,
attribute: str,
file,
storage: Storage,
):
random_string: str = Str.random()
file_extension: str = os.path.splitext(file.name)[1].lstrip(".")
file_name = f"{random_string}.{file_extension}"
response = storage.save(file_name, ContentFile(file.read()))
return {
request_attribute: response,
}
def fields(self, request: DjingRequest):
return [
File.make("Avatar").store(self._storage_callback),
]
By default you will get a default Django Storage instance while handling storage_callback, but if you have a specific Storage for Django, you can overwrite using disk method:
pip install django-storages[boto3]
from djing.core.Fields.File import File
from djing.core.Http.Requests.DjingRequest import DjingRequest
from djing_admin.app.Djing.Resource import Resource as DjingResource
from storages.backends.s3boto3 import S3Boto3Storage
s3_storage = S3Boto3Storage()
class User(DjingResource):
# ...
def _storage_callback(
self,
request: DjingRequest,
request_attribute: str,
model: Model,
attribute: str,
file,
storage: S3Boto3Storage,
):
random_string: str = Str.random()
file_extension: str = os.path.splitext(file.name)[1].lstrip(".")
file_name = f"{random_string}.{file_extension}"
response = storage.save(file_name, ContentFile(file.read()))
return {
request_attribute: response,
}
def fields(self, request: DjingRequest):
return [
File.make("Avatar")
.disk(s3_storage)
.store(self._storage_callback),
]
This wil storage the file to aws s3 bucket.
Last updated