Static files - Django Azure - django

I am hosting a website on Microsoft Azure. I have updated all the configurations within Azure and my settings.py file looks as below -
DEFAULT_FILE_STORAGE = 'storages.backends.azure_storage.AzureStorage'
STATICFILES_STORAGE = 'custom_storage.custom_azure.AzureStaticStorage'
AZURE_ACCOUNT_NAME = os.environ.get('AZURE_ACCOUNT_NAME')
AZURE_STORAGE_KEY = os.environ.get('AZURE_STORAGE_KEY', False)
AZURE_MEDIA_CONTAINER = os.environ.get('AZURE_MEDIA_CONTAINER', 'media')
AZURE_STATIC_CONTAINER = os.environ.get('AZURE_STATIC_CONTAINER', 'static')
AZURE_CUSTOM_DOMAIN = f'{AZURE_ACCOUNT_NAME}.blob.core.windows.net/'
STATIC_URL = f'https://{AZURE_CUSTOM_DOMAIN}/{AZURE_STATIC_CONTAINER}/'
MEDIA_URL = f'https://{AZURE_CUSTOM_DOMAIN}/{AZURE_MEDIA_CONTAINER}/'
STATIC_ROOT = f'https://{AZURE_CUSTOM_DOMAIN}/{AZURE_STATIC_CONTAINER}/'
I have a custom_storage folder with a custom_azure.py file with following -
from django.conf import settings
from storages.backends.azure_storage import AzureStorage
class AzureMediaStorage(AzureStorage):
account_name = settings.AZURE_ACCOUNT_NAME
account_key = settings.AZURE_STORAGE_KEY
azure_container = settings.AZURE_MEDIA_CONTAINER
expiration_secs = None
class AzureStaticStorage(AzureStorage):
account_name = settings.AZURE_ACCOUNT_NAME
account_key = settings.AZURE_STORAGE_KEY
azure_container = settings.AZURE_STATIC_CONTAINER
expiration_secs = None
However I am now pulling a static admin file and not the static project file containing css, scss and js files..

As a work around the the install of whitenoise enables the static files when hosting on Azure. However does not solve the problem of storing the static files on the Azure platform.

Related

Django PDF media files are not displayed on my web page

I have been looking on the internet all over the place for this
and it seems that everything is in check, also media images are very well displayed
so I have a django web app that has a FileField where you can upload pdfs and now I am trying to display thouse pdfs but they get displayed with the error as the image below shows.
settings.py
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR,'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
X_FRAME_OPTIONS = 'SAMEORIGIN'
show_pdf.html
<iframe
src="{{pdf.url}}"
frameBorder="0"
scrolling="auto"
height="1200px"
width="1200px"
></iframe>
models.py
class File_pdf(models.Model):
title = models.CharField(max_length=50)
pdf = models.FileField(upload_to='portfolio/pdfs')
main_resume = models.BooleanField(default=False,help_text="set only one pdf as the main pdf for the main page")
def __str__(self):
return self.title
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('portfolio.urls')),
path('blog/',include('blog.urls'))
]
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
views.py
def pdf_view(request,pdf_id,resume):
dic = {}
if resume == "yes":
pdf_files = File_pdf.objects.filter(main_resume=True)
pdf_file = pdf_files[0]
dic['pdf'] = pdf_file.pdf
dic['title'] = pdf_file.title
else:
pdf_files = get_object_or_404(File_pdf,pk=pdf_id)
pdf_file = pdf_files[0]
dic['pdf'] = pdf_file.pdf
dic['title'] = pdf_file.title
The error looks like this:
this is actually the correct link
In your settings.py add the following code:
X_FRAME_OPTIONS = 'ALLOW-FROM <your localhost URL>'
for example
X_FRAME_OPTIONS = 'ALLOW-FROM http://127.0.0.1:8000/'
it turns out that everything was correct but the brave cache somehow was in conflict with the X_FRAME_OPTIONS updating itself. so after deleting brave's cache it was enough :)

Django static url with digitalocean spaces

I have an droplet on digitalocean which for the most part is working great, however i have enabled the cdn option in digitalocean spaces (similar to aws s3 storage) and in trying to load static files using the cdn url, i cannot seem to get the url working correctly so suspect i am missing the obvious?
For example when i change the STATIC_URL in settings to the cdn no change is seen in the web page source?
If i change the AWS_S3_ENDPOINT_URL and MEDIA_ENDPOINT_URL then the source does change but the files are not found and as one can guess a collectstatic no longer works, So i assume that the AWS_S3_ENDPOINT_URL & MEDIA_ENDPOINT_URL need to remain as is and i merely need to ensure the static_url is used?
I did read somewhere that it was not good practice to change the templates from {%static.... to {%static_url so have not done that, is this something i should update or not?
Settings:
AWS_S3_ENDPOINT_URL = 'https://nyc3.digitaloceanspaces.com'
MEDIA_ENDPOINT_URL = 'https://nyc3.digitaloceanspaces.com/media/'
AWS_STORAGE_BUCKET_NAME = 'mysitestaging'
#STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
# if False it will create unique file names for every uploaded file
AWS_S3_FILE_OVERWRITE = False
STATICFILES_STORAGE = 'mysite.settings.storage_backends.StaticStorage'
DEFAULT_FILE_STORAGE = 'mysite.settings.storage_backends.MediaStorage'
AWS_S3_OBJECT_PARAMETERS = {
'CacheControl': 'max-age=86400',
}
# the sub-directories of media and static files
STATIC_ROOT = 'static'
MEDIA_ROOT = 'media'
AWS_DEFAULT_ACL = 'public-read'
BUCKET_ROOT = '{}/{}/'.format(AWS_S3_ENDPOINT_URL, STATIC_ROOT)
# the regular Django file settings but with the custom S3 URLs
STATIC_URL = '{}/{}/'.format('https://cdn.mysite.com', STATIC_ROOT)
MEDIA_URL = '{}/{}/'.format('https://cdn.mysite.com', MEDIA_ROOT)
Source view returns:
https://nyc3.digitaloceanspaces.com/mysitestaging/static/img/apple-touch-icon.png?AWSAccessKeyId=37FLLPUJLEUO5IG7R4GQ&Signature=eof5%2BZvHPo%2FRSzvKQsrobXkcOZ0%3D&Expires=1586789962
cdn.mysite.com
is an alias of
mysitestaging.nyc3.cdn.digitaloceanspaces.com.
My storage_backends.py:
import os
from storages.backends.s3boto3 import S3Boto3Storage
from my_site.settings import core_settings
class StaticStorage(S3Boto3Storage):
location = core_settings.STATIC_ROOT
class MediaStorage(S3Boto3Storage):
location = core_settings.MEDIA_ROOT
Ok figured this out by actually re-reading the docs:
https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html
Adding the following worked immediately:
AWS_S3_CUSTOM_DOMAIN = 'cdn.mysite.com'
Hope it helps someone else.

Django model FileField is set to "null" instead of url to the file when using Google Cloud Storage

I am running a File manager app on Local machine using Google Cloud Sql Proxy and storing the files in a Google Cloud Storage bucket.
The file is being saved in the bucket, but the FileField is set to "null". I want it to show the url by which I can access the file.
I am following this answer Configure Django and Google Cloud Storage?
I have set the Google Cloud Storage bucket to public.
Django Model:
class Document(models.Model):
docfile = models.FileField(upload_to='documents/%Y/%m/%d')
Setting.py:
#MEDIA_URL = "/media/"
#MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
DEFAULT_FILE_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage'
GS_BUCKET_NAME = 'printhub-files'
GS_PROJECT_ID = 'preasy-53c43'
GS_MEDIA_BUCKET_NAME = 'printhub-files'
# GS_STATIC_BUCKET_NAME = '<name-of-static-bucket>'
# STATIC_URL = 'https://storage.googleapis.com/{}/'.format(GS_STATIC_BUCKET_NAME)
MEDIA_URL = 'https://storage.googleapis.com/{}/'.format(GS_MEDIA_BUCKET_NAME)
Expected Result:
{
"id": 13,
"docfile": "https://storage.googleapis.com/bucket/documents/2019/11/03/myfile.pdf",
}
Actual Result:
{
"id": 13,
"docfile": null,
}
If I change my Settings.py to (uncomment line 1,2. Comment line 4), the file is saved on my local machine media/ folder, and "docfile" is set to the bucket url:
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
#DEFAULT_FILE_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage'
GS_BUCKET_NAME = 'printhub-files'
GS_PROJECT_ID = 'preasy-53c43'
GS_MEDIA_BUCKET_NAME = 'printhub-files'
# GS_STATIC_BUCKET_NAME = '<name-of-static-bucket>'
# STATIC_URL = 'https://storage.googleapis.com/{}/'.format(GS_STATIC_BUCKET_NAME)
MEDIA_URL = 'https://storage.googleapis.com/{}/'.format(GS_MEDIA_BUCKET_NAME)
I get the output:
{
"id": 13,
"docfile": "https://storage.googleapis.com/bucket/documents/2019/11/03/myfile.pdf",
}
It seems that you're not configuring the settings.py file correctly. Check this documentation to use Google Cloud Storage Bucket for Djanjo project.
As you can see in the documentation, settings.py should be like this:
settings.py
.....
GCS_ROOT = "https://storage.googleapis.com/{bucket_name}/".format(
bucket_name=os.environ.get("GCS_BUCKET")
)
MEDIA_PREFIX = "media"
MEDIA_URL = "{gcs_root}{prefix}/".format(
gcs_root=GCS_ROOT,
prefix=MEDIA_PREFIX,
)
......
Let me know if it works for you.

Override the DEFAULT_FILE_STORAGE with MEDIA_URL to integrate Azure CDN

I'm using Azure Storage account for storing my media files
Setting it is simple in settings.py like this:
DEFAULT_FILE_STORAGE = 'storages.backends.azure_storage.AzureStorage'
AZURE_ACCOUNT_NAME = 'my_account_name'
AZURE_ACCOUNT_KEY = 'my_account_key'
AZURE_CONTAINER = 'my-container'
However, I considered later that I want to use Azure CDN instead for serving my media files. How will I point it to the CDN URL instead? I tried setting it in the MEDIA_URL like
MEDIA_ROOT = os.path.join(BASE_DIR, 'upload')
MEDIA_URL = '//my-media.azureedge.net/my-container/'
However my storage-account blob is the one being shown as default URL which is 'xxxxx.blob.core.windows.net' instead of my MEDIA URL..
How will I show the MEDIA_URL instead of 'xxxxx.blob.core.windows.net'?
Thankfully I already have an answer for this one. You need to override the storage backend class of Azure on the 'storages' library replacing the blob hostname with the CDN hostname.
settings.py
MEDIA_URL = '//my-media.azureedge.net/my-container/'
storages.py
import re
from jaguar import settings
from storages.backends.azure_storage import AzureStorage
class AzureCDNURL(AzureStorage):
def url(self, name):
ret = super(AzureCDNURL, self).url(name)
_ret = re.sub('//[a-z.0-9A-Z]*/', settings.MEDIA_URL, ret)
return _ret

Django storages or avatar sets https on my urls so I get certificate errors

I have set my server up with django-storages and django-avatar. When I go to view my site, none of my css or images loads. When I inspect the url i see it is a https and that is causing a certificate error. If I remove the s to make it a normal http then it works fine. What setting have I messed up that is causing the issue?
Django 1.4.5
django-storages
django-avatar
import os
PROJECT_ROOT = os.path.dirname(__file__) + '/'
MEDIA_ROOT = PROJECT_ROOT + 'media/'
MEDIA_URL = 'http://static.XXXX.com.s3.amazonaws.com/'
STATIC_ROOT = PROJECT_ROOT + 'static/'
STATIC_URL = 'http://static.XXXX.com.s3.amazonaws.com/'
STATIC_DOC_ROOT = PROJECT_ROOT + 'static/'
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
AWS_ACCESS_KEY_ID = 'XXXX'
AWS_SECRET_ACCESS_KEY = 'XXXX'
AWS_STORAGE_BUCKET_NAME = 'static.XXXX.com'
AWS_QUERYSTRING_AUTH = False
AWS_S3_SECURE_URLS = False
#AVATAR
AVATAR_DEFAULT_SIZE = 80
AVATAR_THUMB_FORMAT = "PNG"
AVATAR_THUMB_QUALITY = 90
AVATAR_HASH_FILENAMES = False
AVATAR_HASH_USERDIRNAMES = False
AVATAR_GRAVATAR_BACKUP = False
AVATAR_DEFAULT_URL = MEDIA_URL + 'avatars/default.png'
I have used storages (on the same shared server) before with no issue so it leads me to believe that it is avatar that is the issue. Any pointers would be greatly appreciated.
EDIT:
linked files that are using {{ MEDIA_URL }} on the front end are fine
Images that were uploaded using the avatar are not showing due to the https
admin styles and images are not showing due to https
If it helps the images that are not showing are in a section that requires users to be logged in?
...I am just checking other images now
EDIT 2:
Other images (log & bg image) are ok , but are loaded via a css file on s3
I have fixed the issue. The way I did it was by replacing:
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
with:
DEFAULT_FILE_STORAGE = 'storages.backends.s3.S3Storage'
from S3 import CallingFormat
AWS_CALLING_FORMAT = CallingFormat.SUBDOMAIN