نکتههای جنگویی - کش کردن - قسمت دوم
در قسمت قبلی پایهی سری مطالب نکات جنگویی رو آماده کردم. و در این مطلب و مطالب بعدی نکتههایی که ممکنه بدردمون بخوره رو با هم یاد میگیریم.
کش کردن انواع مختلفی داره که هدف این مطلب، کش کردن با memcache هستش. برای استفاده از memcache باید روی سیستم خودتون نصبش کنید. بسته به سیستمعاملی که دارید memcache رو نصب کنید یا میتونید از داکر برای نصبش استفاده کنید.
نکته: تو یه پست جمع و جور پروژهی جنگویی خودمونو داکری میکنیم تا خرکیف شیم.
حالا اگر لینوکس دارید با وارد کردن خط زیر میتونید memcache رو نصب کنید:
sudo apt install memcached
بعد هم نیاز به یه کتابخونه memcache دارم که نصب میکنم:
pip3 install django-memcached
حالا تنظیمات memcache رو به A/settings.py اضافه میکنم:
# Cache CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': '127.0.0.1:11211', } }
انواع کش کردن:
The per-site cache
The per-view cache
Template fragment caching
The low-level cache API
که در ادامه با هر کدوم از موارد بالا آشنا میشیم.
The per-site cache
در این روش، کل پروژه کش میشه. با تغییر دادن MIDDLEWARE در A/settings.py :
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
من ۷۳۸ داستان کوتاه رو وارد دیتابیسم کردم. و بدون اینکه کش انجام بدم، خوندن اطلاعات و هربار نشون دادنش چند ثانیهای طول میکشه. اما با کش فقط دفعهی اول چند ثانیهای طول میکشه و دفعات بعدی بهجای اینکه اطلاعات رو مستقیم از دیتابیس دیسک بخونه، اطلاعات رو از حافظه رم میخونه که سرعت خیلی بالاست.
The per-view cache
اگر میخواید که فقط بخشی از وبسایت رو کش کنید و کش کردن کل وبسایت نیاز ندارید، در stories/views.py:
from django.views.decorators.cache import cache_page
و دیکوریتور cache_page رو به شکل زیر استفاده میکنیم:
@cache_page(5 * 60) def stories_list(request): context = {} stories = Story.objects.filter(status=True) context['stories'] = stories return render(request, 'stories/index.html', context)
که 5 * 60 نشون دهندهی مدت زمان 5 دقیقهای کش کردن هست.
روش دیگه اینه که کش کردن رو در stories/urls.py انجام بدیم که باز هم باید cache_page رو وارد کنیم و بعد:
from django.views.decorators.cache import cache_page app_name = 'stories' urlpatterns = [ path('', (cache_page(5 * 60))(views.stories_list), name='stories_list'), ]
به این ترتیب کش کردن ما بهجای views در urls انجام میشه. شخصا خودم از views کش میکنم. تمیزتره :).
Template fragment caching
همونطور که اسمش پیداست کش کردن در templateها انجام میشه. مثلا:
{% load cache %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>لیست داستانها</title> </head> {% cache 300 content %} <body style="direction: rtl; text-align: justify"> <h1>فهرست داستانها</h1> <hr> {% for story in stories %} <h3><a href="{% url 'stories:stories_detail' story.slug %}">{{ story.title }}</a></h3> <small>{{ story.created|timesince }}</small><span>{{ story.user }}</span> {% endfor %} </body> {% endcache %} </html>
اول کش رو لود کردم. و بعد اون ناحیهای که میخوام کش شه رو داخل تگ کش content میذارم. ۳۰۰ (ثانیه) مدت زمان کش هست.
The low-level cache API
در روش آخر بهصورت دستی اطلاعاتی که میخوایم رو وارد کش میکنیم. اول cache رو وارد میکنم:
from django.core.cache import cache
بعد از اون من میخوام که هر بار که داستانی باز میشه، اون داستان وارد کش شه و دفعات بعدی داستان مستقیما از دیتابیس خونده نشه. برای همین میام این کد زیر رو مینویسم:
@cache_page(5 * 60) def stories_detail(request, slug): cache_key = f'story-{slug}' cache_time = 5 * 60 story = cache.get(cache_key) if not story: story = get_object_or_404(Story, slug=slug, status=True) cache.set(cache_key, story, cache_time) return render(request, 'stories/detail.html', {'story': story})
یک کلید براساس slug درست میکنم و براساس این کلید کش رو میگیرم یا میسازم.
سعی کردم بهصورت خلاصه و بهدور از زیادهگویی یه سیستم کش ساده رو تو جنگو بنویسم. اگر نظری حرفی حدیثی هست خوشحال میشم با من در میون بذارید.
پایان./
سلام
خسته نباشید - ممنون از توضحات عالی
2تا سوال داشتم
در روش template fragment caching یا حتی روش های دیگه ،
اگر اون زمانی که بهش دادیم ، تموم شه چه اتفاقی میفته ؟ دیگه از رو کش نمیخونه؟
سوال دوم : اگر قبل از اتمم اون زمان می یه تغییری دایدم ، بر فرض به به دسته بندی های سایت یه مورد اضافه کردیم ؟ چه اتفاقی میفتهه ؟