在 Django 里写 REST API 是简单的,如何让 API 的速度更快呢?本文分享一种方法:用 Redis 作为缓存,可以让你的 API 的速度提升 10 倍。
这里假定你已经安装了 Redis,并且自己可以按照官方文档写出一个 Django REST API,对 Django 有一定的基础。
首先,让我们安装一个插件:
复制
pip install django-redis
1.
然后在配置文件 settings.py 中添加一下内容:
复制
CACHES = {"default": {"BACKEND": "django_redis.cache.RedisCache","LOCATION": "redis://127.0.0.1:6379/1", # Local Link provided by the redis-server command"OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient",}}}
1.
2.
3.
4.
5.
6.
7.
8.
9.
然后在 views.py 中导入 redis 并创建一个 redis 实例:
复制
from django.core.cache import cache import timeimport redisfrom rest_framework.response import Response redis_instance = redis.StrictRedis(host='127.0.0.1', port=6379, db=1)
1.
2.
3.
4.
5.
通过在我们的 views.py 中创建一个列表函数来实现 Redis。此视图功能将检查数据是否在 Redis 中。如果在 Redis 服务器中找到数据,则从那里获取数据,如果没有,则从数据库中获取数据并将其存储在 Redis 中以备下次使用,这会导致速度增加,示例代码如下:
复制
class MusicianViewSet(viewsets.ModelViewSet):serializer_class = MusicianSerializer queryset = Musician.objects.all()@log_db_queries def list(self, request):first_name = self.request.query_params.get('first_name')if first_name is not None:cache_key = 'name' + first_name else:cache_key = 'name'if cache_key in cache:print("redis")queryset = cache.get(cache_key)return Response(queryset)else:print('db')queryset = Musician.objects.all()if first_name is not None:queryset = queryset.filter(first_name__contains=first_name) serializer_class = MusicianSerializer(queryset, many=True)cache.set(cache_key , serializer_class.data, timeout=60*60)return Response(serializer_class.data)
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
在这里 timeout 设置数据在 Redis 服务器中保留多长时间的超时,在这段代码中,它设置为 1 小时。1 小时后,它将自动从 Redis 中删除。
细心的你可能看到了装饰器 log_db_queries,它来测试 API 的访问速度,具体代码如下:
复制
def log_db_queries ( f )from django.db import connection def new_f ( * args , ** kwargs )start_time = time.time()res = f ( * args , ** kwargs )print ( "\n\n" )print ( "-"*80 )print ("db queries log for %s:\n" % (f.__name__))print ( " TOTAL COUNT : % s " % len ( connection.queries ) )for q in connection.queries :print ("%s: %s\n" % (q["time"] , q["sql"]))end_time = time.time ()duration = end_time - start_time print ('\n Total time: {:.3f} ms'.format(duration * 1000.0))print ("-"*80)return res return new_f
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
这为我们提供了获取数据所需时间的详细视图,以及数据是否来自数据库或 Redis。
来个使用缓存的前后对比:
使用前:1219.266 ms:
使用后:134.002 ms:
缓存确实有助于提高 Django REST API 的速度,而 Redis 又是最佳的缓存工具,可以从这里获取Django-Redis[1] 的源代码。