django-cache-champ est une application Django qui fournit céleri-différé, les champs mis en cache sur Django ORM pour données coûteuses à calculer
Utiliser Django ORM et céleri, garder coûteuse à calculer les attributs mis à jour.
Exemple
Disons que vous avez une méthode lente sur l'un de vos modèles:
Lampadaire classe (models.Model):
& Nbsp;property
& Nbsp; def slow_full_name (auto):
& Nbsp; le sommeil (30)
& Nbsp; retour »de% du% s de% s 'l'% (self.weight, self.first_name, self.country)
Ugh; trop lent. Disons cache. Nous voulons quelques outils. Céleri
de CachedIntegerField d'importation de django_cached_field, ModelWithCachedFields
Lampadaire classe (models.Model, ModelWithCachedFields):
& Nbsp; slow_full_name = CachedTextField (null = True)
& Nbsp; def calculate_slow_full_name (auto):
& Nbsp; le sommeil (30)
& Nbsp; retour »de% du% s de% s 'l'% (self.weight, self.first_name, self.country)
(Ouais, calculate_ est juste une convention. Je ai clairement ne ont pas donné le fantôme rails ...)
Ensuite, migrer votre schéma db pour inclure le nouveau champ en cache utilisant sud, ou rouler votre propre. Notez que deux champs seront ajoutés à ce tableau, cached_slow_full_name de type texte et slow_full_name_recalculation_needed de type booléen, probablement défaut à true.
Déjà ce est un peu mieux. lamppost.slow_full_name peut prendre 30 secondes la première fois qu'elle est appelée pour un enregistrement donné, mais à partir de là, ça va être instantanée proche. Bien sûr, à ce stade, il ne sera jamais changer après ce premier appel.
La pièce importante du puzzle restante est d'invalider notre cache. Thoses domaines constitutifs sont probablement changé dans certains views.py (cela pourrait être plus intelligent à propos de remarquer si les valeurs correspondantes sont mises à jour):
render_to ("lampadaire / edit.html")
def modifier (demande, lamppost_id):
& Nbsp; lampadaire = Lamppost.objects.get (pk = lamppost_id)
& Nbsp; si request.method == 'POST':
& Nbsp; form = LamppostForm (request.POST)
& Nbsp; si form.is_valid ():
& Nbsp; form.save ()
& Nbsp; form.instance.flag_slow_full_name_as_stale ()
& Nbsp; d'autre:
& Nbsp; form = LamppostForm ()
& Nbsp; return {«forme»: forme, «lampadaire»: lampadaire}
Ce est la partie la plus difficile que le développeur! La mise en cache nécessite vous traquer partout la valeur pourrait être modifié et appelant cette méthode flag_slow_full_name_as_stale. Est le pays affecté une nouvelle valeur aléatoire chaque matin à cron'o'clock? Ce drapeau avait mieux être vicié par cron'o'one. Avez-vous calculer le poids en fonction de la somme de tous les pigeons associés? Accrochez sur l'atterrissage de pigeons. Et le décollage. Et tout ce qui change le poids d'un pigeon individu. Comme l'a dit Abraham Lincoln, "Il ya seulement deux problèmes difficiles dans la programmation: nommage, invalidation du cache et des erreurs off-by-one."
Installation
Vous pouvez rendre les choses faciles sur vous-même:
pip installer django-cache-champ
Ou, pour une installation manuelle, vous pouvez cloner le repo et l'installer en utilisant Python et setup.py:
git clone git: //github.com/aquameta/django-cached-field.git
cd django-cache-champ /
python setup.py install
Testé avec django 1.3.1, 2.3.1 le céleri, le céleri-django 2.3.3.
Configuration
Deux changements de paramètres sont à peu près nécessaires pour que tout fonctionne: assurez-vous que ce est une application recommandée, assurez-vous que le céleri voit son fichier de tâches:
INSTALLED_APPS + = ['django_cached_field',]
CELERY_IMPORTS + = [']', django_cached_field.tasks
Un changement est facultatif: si le nouveau calcul devrait se produire lorsque signalé comme vicié (par défaut) ou être laissée à la prochaine fois que l'attribut est accessible. Ce est utile pour les environnements de test où vous ne vous souciez pas que vos valeurs mises en cache ne sont pas valides. Notez que dans cette situation, vous ne auriez pas besoin de céleri.
CACHED_FIELD_EAGER_RECALCULATION = True ou False # pour les environnements de test
Ce est une option globale, de sorte exceptions individuelles devraient plutôt être traitées en passant l'argument and_recalculate à l'appel de flag_FIELD_as_stale.
Mises en garde
- Condition de course si vous marquez un domaine aussi vicié dans une transaction de db qui prend plus de temps que le travail de céleri faut pour être appelé.
- Toutes les méthodes d'ORM (par exemple order_by, filtres) doivent utiliser cached_FIELD.
- Recalculate_FIELD utilise .update (cached_FIELD = pour définir la valeur.
- Flag_FIELD_as_stale utilise .update, ainsi
Exigences :
- Python .
- Django
Commentaires non trouvées