Dans mon application Flask, je sers les actifs statiques via l'application dans le dev env, mais j'aimerais utiliser un CDN en production. Chaque actif est chargé dans un modèle appelé base.hmtl
, donc je suppose que la solution la plus simple est de passer une variable à la fonction de rendu et de l'utiliser dans le modèle comme:
<script src="{{ STATIC_URL }}/js/main.js"></script>
Normalement, ce serait une chaîne vide dans le dev env, et l'url du cdn en production. Je voudrais éviter de transmettre cette variable STATIC_URL
à chaque vue. Je pourrais le faire fonctionner avec
@bp.context_processor
def set_static_path():
return dict(STATIC_URL='https://foo.bar.com')
Mais pour moi, cela semble un peu hacky. Existe-t-il une meilleure façon de résoudre ce problème?
3 réponses
Il n'est pas nécessaire de modifier la façon dont vous créez un lien vers des fichiers statiques, vous pouvez toujours utiliser url_for('static', filename='myfile.txt')
. Remplacez la vue statique par défaut par une vue qui redirige vers le CDN s'il est configuré.
from urllib.parse import urljoin
# or for python 2: from urlparse import urljoin
from flask import redirect
@app.endpoint('static')
def static(filename):
static_url = app.config.get('STATIC_URL')
if static_url:
return redirect(urljoin(static_url, filename))
return app.send_static_file(filename)
Que vous soyez sur une machine de développement ou de production, définissez la valeur de configuration STATIC_URL
sur le CDN et les demandes de fichiers statiques y seront redirigées.
Les redirections sont relativement bon marché et sont mémorisées par les navigateurs. Si vous arrivez au point où les performances en sont affectées de manière significative, vous pouvez écrire une fonction qui établit un lien directement lors de l'utilisation du CDN.
@app.template_global()
def static_url(filename):
static_url = app.config.get('STATIC_URL')
if static_url:
return urljoin(static_url, filename)
return url_for('static', filename=filename)
Le décorateur template_global
rend la fonction disponible dans tous les modèles. Utilisez-le à la place de url_for
lorsque vous avez besoin d'URL pour des fichiers statiques.
Il peut y avoir une extension Flask qui le fait déjà pour vous. Par exemple, Flask-S3 fournit un url_for
qui sert des fichiers statiques d'AWS S3.
J'ai rencontré un problème similaire en utilisant Flask Assets et Flask-CDN. J'ai trouvé que Flask-CDN essayait et échouait à générer des horodatages pour chaque actif. En cas d'échec, il reviendrait aux URL relatives.
L'ajout de app.config['CDN_TIMESTAMP'] = False
a résolu le problème.
Ce guide d'intégration de cdn flacon peut valoir la peine d'être lu. Fondamentalement, vous pouvez installer Flask-CDN extension et définir votre URL CDN dans votre fichier app.py comme alors:
from flask import Flask
from flask.ext.cdn import CDN
app = Flask(__name__)
app.config['CDN_DOMAIN'] = 'cdn.yourdomain.com'
CDN(app)
Questions connexes
De nouvelles questions
python
Python est un langage de programmation multi-paradigme, typé dynamiquement et polyvalent. Il est conçu pour être rapide à apprendre, comprendre, utiliser et appliquer une syntaxe propre et uniforme. Veuillez noter que Python 2 est officiellement hors support à partir du 01-01-2020. Néanmoins, pour les questions Python spécifiques à la version, ajoutez la balise [python-2.7] ou [python-3.x]. Lorsque vous utilisez une variante Python (par exemple, Jython, PyPy) ou une bibliothèque (par exemple, Pandas et NumPy), veuillez l'inclure dans les balises.