Skip to content

Commit

Permalink
Switch to django-cacheops
Browse files Browse the repository at this point in the history
  • Loading branch information
agoncharov-reef committed Oct 8, 2024
1 parent d9a452a commit 4a9ac25
Show file tree
Hide file tree
Showing 10 changed files with 225 additions and 212 deletions.
21 changes: 13 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,16 +167,21 @@ class MyView(ListView):

# URL caching

In order to reduce database load, there is a caching mechanism for URL model. It's enabled be default and will use Django's **default** cache backend. To use a custom cache backend, add this to your settings:
In order to reduce database load, it is highly recommended to enable caching mechanism for `Url` model. This can be easily acieved using `django-cacheops`:

```python
FINGERPRINT_CACHE = 'memcached' # this has to be a valid key from settings.CACHES
```

To disable caching, set this to `None`:

```python
FINGERPRINT_CACHE = None
INSTALLED_APPS = [
# ...
'cacheops',
]
CACHEOPS_REDIS = "redis://localhost:6379/1"
CACHEOPS = {
'fingerprint.url': {
'ops': 'get',
'local_get': True,
'timeout': int(timedelta(minutes=15).total_seconds()),
},
}
```

# Included licenses
Expand Down
11 changes: 11 additions & 0 deletions demo/demo/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from __future__ import annotations

from datetime import timedelta
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
Expand Down Expand Up @@ -39,6 +40,7 @@
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"cacheops",
"demo",
"fingerprint",
"debug_toolbar",
Expand Down Expand Up @@ -91,6 +93,15 @@
},
}

CACHEOPS_REDIS = "redis://localhost:6379/1"
CACHEOPS = {
'fingerprint.url': {
'ops': 'get',
'local_get': True,
'timeout': int(timedelta(minutes=15).total_seconds()),
},
}

AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
Expand Down
13 changes: 8 additions & 5 deletions demo/demo/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest
from cacheops import invalidate_all
from django.contrib.auth import get_user_model
from django.core.cache import caches
from django.test import Client


Expand All @@ -17,9 +17,12 @@ def user_client(client, user) -> Client:
return client


@pytest.fixture
def nocache(settings) -> None:
settings.CACHEOPS_ENABLED = False


@pytest.fixture(autouse=True)
def clear_cache(settings):
def clear_cache():
yield

for cache in settings.CACHES.keys():
caches[cache].clear()
invalidate_all()
51 changes: 1 addition & 50 deletions demo/demo/tests/test_models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from collections import Counter

from fingerprint.models import RequestFingerprint, Url
from fingerprint.models import RequestFingerprint


def test__models__get_count_for_urls__logic(db, client, user):
Expand Down Expand Up @@ -57,51 +56,3 @@ def test__models__get_count_for_urls__num_queries(db, client, django_assert_num_

with django_assert_num_queries(4):
RequestFingerprint.get_count_for_urls([absolute_url1, absolute_url2])


def test_url_from_value_cache(db, django_assert_num_queries):
url = "http://example.com"
other_url = "http://example.com/other"

with django_assert_num_queries(4):
instance = Url.from_value(url)

with django_assert_num_queries(0):
assert Url.from_value(url) == instance

with django_assert_num_queries(4):
Url.from_value(other_url)


def test_url_from_value_alternative_cache(db, django_assert_num_queries, settings, tmpdir):
settings.CACHES["alternative"] = {
"BACKEND": "django.core.cache.backends.filebased.FileBasedCache",
"LOCATION": str(tmpdir),
}

settings.FINGERPRINT_CACHE = "alternative"

url = "http://example.com"

with django_assert_num_queries(4):
instance = Url.from_value(url)

with django_assert_num_queries(0):
assert Url.from_value(url) == instance

settings.FINGERPRINT_CACHE = "default"

with django_assert_num_queries(1):
assert Url.from_value(url) == instance


def test_url_from_value_cache_cache_disabled(db, django_assert_num_queries, settings):
settings.FINGERPRINT_CACHE = None

url = "http://example.com"

with django_assert_num_queries(4):
instance = Url.from_value(url)

with django_assert_num_queries(1):
assert Url.from_value(url) == instance
6 changes: 6 additions & 0 deletions demo/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: '3'
services:
redis:
image: redis:latest
ports:
- 6379:6379
4 changes: 2 additions & 2 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,9 @@ def lint(session):
@nox.session(python=PYTHON_VERSIONS, tags=["test", "check"])
@nox.parametrize("django", DJANGO_VERSIONS)
def test(session, django: str):
install(session, "test")
install(session, "test", "cache")
session.run("pip", "install", f"django~={django}.0")
session.run("pytest", "-vv", "-n", "auto", *session.posargs)
session.run("pytest", "-vv", *session.posargs)


@nox.session(python=PYTHON_DEFAULT_VERSION)
Expand Down
Loading

0 comments on commit 4a9ac25

Please sign in to comment.