Wenn zwei Django-Instanzen sich den gleichen memcached als Cache-Backend teilen, kann es zu Anzeige-Problemen der Templates kommen. Dieser Artikel beschreibt die Bedingungen sowie eine entsprechende Lösung genauer. Wenn zwei Django-Instanzen den gleichen memcached als Caching-Backend nutzen, kann dies zu Anzeige-Problemen führen, falls die Templates Dateien mit gleichem Namen, aber unterschiedlichem Inhalt verwenden: es wird das falsche Template zum eigentlichen Inhalt angezeigt. Dieses Verhalten kann auch in allen Django-Programmen beobachtet werden, welche die Einstellung CACHE_MIDDLEWARE_KEY_PREFIX nicht berücksichtigen. Der entsprechende Bug report erwähnt, dass in einem solchen Fall eine Design-Entscheidung notwendig ist – die oben genannte Einstellung sollte eigentlich nur in Middleware-Installationen genutzt werden, und nicht im Rahmen der Templates. Ohne diese Einstellung können sich aber unterschiedliche Django-Instanzen gegenseitig beeinflussen. Dies ist nicht nur wegen der möglichen optischen Erscheinung der Instanzen von Gewicht, sondern auch wegen der Möglichkeit, CMS-Nutzerberechtigungen in den memcached einzubringen, und so die Rechte anderer Instanzen zu verändern. Eine Möglichkeit ist nun, sicherzustellen, dass die Konfigurationsoption CACHE_MIDDLEWARE_KEY_PREFIX für jeden Zugriff genutzt wird. Der dargestellte Code, als benutzerdefiniertes Cache-Backend genutzt, garantiert dies.
from django.conf import settings from django.core.cache.backends.memcached import CacheClass as DjangoMemcachedCacheClass from django.utils.hashcompat import md5_constructor class CacheClass(DjangoMemcachedCacheClass): def __init__(self, server, params): self.key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX super(CacheClass, self).__init__(server, params) def _genkey(self, origkey): return md5_constructor("%s:%s" %(self.key_prefix, origkey)).hexdigest() def add(self, key, value, timeout=0): return super(CacheClass, self).add(self._genkey(key), value, timeout) def get(self, key, default=None): return super(CacheClass, self).get(self._genkey(key), default) def set(self, key, value, timeout=0): return super(CacheClass, self).set(self._genkey(key), value, timeout) def delete(self, key): return super(CacheClass, self).delete(self._genkey(key)) def get_many(self, keys): return super(CacheClass, self).get_many(self._genkey(key)) def incr(self, key, delta=1): return super(CacheClass, self).incr(self._genkey(key), delta) def decr(self, key, delta=1): return super(CacheClass, self).decr(self._genkey(key), delta)
Darüber hinaus ist es wesentlich schwerer, gefälschten Cache-Inhalt einzufügen, wenn ein md5hex-digest als Schlüssel genutzt wird. Allerdings sollten sowieso nie wichtige Informationen in einem memcached gespeichert werden – in einem solchen Fall wäre locmem, file oder db als Backend wesentlich besser geeignet, da sie eine bessere Rechteverwaltung ermöglichen!
Dieser Artikel wurde ursprünglich geschrieben von Bernd Zeimetz.
Kategorien: | HowTos |
---|---|
Tags: | Django |
Sie sehen gerade einen Platzhalterinhalt von Brevo. Um auf den eigentlichen Inhalt zuzugreifen, klicken Sie auf die Schaltfläche unten. Bitte beachten Sie, dass dabei Daten an Drittanbieter weitergegeben werden.
Mehr InformationenSie müssen den Inhalt von reCAPTCHA laden, um das Formular abzuschicken. Bitte beachten Sie, dass dabei Daten mit Drittanbietern ausgetauscht werden.
Mehr InformationenSie müssen den Inhalt von Turnstile laden, um das Formular abzuschicken. Bitte beachten Sie, dass dabei Daten mit Drittanbietern ausgetauscht werden.
Mehr Informationen