2009-10-19 6 views
11

Niedawno zaimplementowałem doskonałą strukturę pamięci podręcznej Django. Jednak z tego, co rozumiem, Django nie buforuje widoku, który przekazuje parametry w żądaniu pobierania. Mam widok Ajax, który jest przekazywany uzyskać parametry, które chciałbym buforować przez X sekund, jaki byłby łatwy sposób to zrobić?Pamięć podręczna widoku django, który ma parametry adresu URL

W kodzie psuedo Obecnie mam URL:

http://mysites/ajaxthing/?user=foo&items=10 

Chciałabym buforować dowolny ten url tak długo, jak to ma takie same parametry dostać.

Jestem obecnie za pomocą dekoratorów cache moim zdaniem:

myview(stuff) 

myview = cache_page(myview, 60 * 3) 

Czytałem o django's vary headers ale to poszło trochę nad moją głową, a ja nie jestem nawet pewien, czy jego poprawne rozwiązanie

+2

Czy jest jakiś powód, dla którego nie chcesz po prostu użyj: 'http: // mysites/ajaxthing/user/foo/items/10 /' W ten sposób dobrze rozwiążesz ten problem. –

+0

Proszę przeczytać odpowiedź euqidron poniżej, to zachowanie zmieniło się w Django 1.3. –

Odpowiedz

16

Prawo, zmieniać nagłówki nie jest prawidłowe rozwiązanie, to jest używane, gdy chcemy buforować na podstawie nagłówków żądań klientów, takich jak łatwość agenta itp

trzeba użyć low-level API lub template fragment caching. To zależy od twoich poglądów.

Z niskopoziomowego API wygląda mniej więcej tak:

from django.core.cache import cache 

def get_user(request): 
    user_id = request.GET.get("user_id") 
    user = cache.get("user_id_%s"%user_id) 
    if user is None: 
     user = User.objects.get(pk=user_id) 
     cache.set("user_id_%s"%user_id, user, 10*60) # 10 minutes 
    ... 
    .. 
    . 
+0

+1 dla buforowania fragmentów szablonów. Jest to bardzo przydatne w niektórych sytuacjach. –

+0

Dzięki za zwięzły zarys, to naprawdę przydatne. –

8

Tak, można użyć django-View-cache-utils, tutaj jest kod w Twoim przypadku:

from view_cache_utils import cache_page_with_prefix 
from django.utils.hashcompat import md5_constructor 
... 
@cache_page_with_prefix(60*15, lambda request: md5_constructor(request.get_full_path()).hexdigest()) 
def my_view(request): 
    ... 
+2

To podejście jest dobre, ale trafiliśmy dwa główne problemy z kodem, 1. może być konflikt dla dwóch widoków z tymi samymi argumentami URL, 2. the str (request.GET) może zwracać inaczej, ponieważ wyświetlanie wpisu w słowniku nie ma określonych zamówienie. Później użyłem tego kodu: @ cache_page_with_prefix (60 * 15, żądanie lambda: md5_constructor (request.build_absolute_uri()). Hexdigest()). –

+0

Dzięki za wskazówkę, zaktualizowaną odpowiedź. –

1

że już nie trzeba robić nic bardziej skomplikowanego niż umieszczenie @cache_page ([długość czasu]) powyżej Państwa zdanie funkcji, którą próbujesz pamięci podręcznej, niezależnie od tego, czy parametry w adresie URL .

Na przykład, jeśli masz url jak:

http://example.com/user/some_user_id 

Twoja funkcja widoku w views.py będzie wyglądać mniej więcej tak:

from django.views.decorators.cache import cache_page 
... 

@cache_page(60 * 10) 
def get_user_detail(request, user_id=None): 
    ... 
    return render(...) 
+0

Próbowałem tego, ale dostałem AttributeError z urls.py podczas korzystania z ogólnych widoków: url (r '^ (? P [0-9] +)/teams/(? P [0-9] +)/szczegóły/$ ', widoki.TeamDetailView.as_view(), name = 'team_detail'), AttributeError: Obiekt 'function' nie ma atrybutu "as_view" – simi