Skip to content

Commit

Permalink
manage Pickle when PARLER_ENABLE_CACHING is True
Browse files Browse the repository at this point in the history
Because parler cache translations, depending the cache solution is used,
Wagtail's Blocks could not be serialized. This patch is temp, and should
be fixed into wagtail soon.
  • Loading branch information
DylannCordel committed Sep 13, 2023
1 parent 92c153c commit b609f41
Show file tree
Hide file tree
Showing 9 changed files with 388 additions and 122 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ wagtail's snippets.
This app is tested to runs with:

* Django 3.2, 4.2
* Wagtail TODO
* Parler TODO
* Wagtail 4.1, 4.2, 5.0, 5.1
* Parler 2.3 (probably older ones to, it's just not tested)
* Python 3.7, 3.9, 3.11

To ensure code quality and consistency:
Expand Down
Binary file removed test.sqlite
Binary file not shown.
280 changes: 161 additions & 119 deletions test_fixtures.json
Original file line number Diff line number Diff line change
@@ -1,122 +1,164 @@
[
{
"model": "wagtail_parler_tests.foodtranslation",
"pk": 1,
"fields": {
"language_code": "fr",
"name": "Gelée",
"summary": "Summary FR",
"content": "Content FR",
"master": 1
}
},
{
"model": "wagtail_parler_tests.foodtranslation",
"pk": 2,
"fields": {
"language_code": "fr",
"name": "Pudding de Noël",
"summary": "Summary FR",
"content": "Content FR",
"master": 2
}
},
{
"model": "wagtail_parler_tests.foodtranslation",
"pk": 3,
"fields": {
"language_code": "fr",
"name": "Omelette au fromage",
"summary": "Summary FR",
"content": "Content FR",
"master": 3
}
},
{
"model": "wagtail_parler_tests.foodtranslation",
"pk": 4,
"fields": {
"language_code": "fr",
"name": "Raclette",
"summary": "Summary FR",
"content": "Content FR",
"master": 4
}
},
{
"model": "wagtail_parler_tests.foodtranslation",
"pk": 5,
"fields": {
"language_code": "en",
"name": "Jelly",
"summary": "Summary EN",
"content": "Content EN",
"master": 1
}
},
{
"model": "wagtail_parler_tests.foodtranslation",
"pk": 6,
"fields": {
"language_code": "en",
"name": "Christmas Pudding",
"summary": "Summary EN",
"content": "Content EN",
"master": 2
}
},
{
"model": "wagtail_parler_tests.food",
"pk": 1,
"fields": {
"yum_rating": 3,
"vegetarian": true,
"vegan": true
}
},
{
"model": "wagtail_parler_tests.food",
"pk": 2,
"fields": {
"yum_rating": 5,
"vegetarian": false,
"vegan": false
}
},
{
"model": "wagtail_parler_tests.food",
"pk": 3,
"fields": {
"yum_rating": 8,
"vegetarian": true,
"vegan": false
}
},
{
"model": "wagtail_parler_tests.food",
"pk": 4,
"fields": {
"yum_rating": 10,
"vegetarian": true,
"vegan": false
}
},
{
"model": "auth.user",
"pk": 1,
"fields": {
"password": "md5$Xibmtaqa1WGE7j0V46OcOQ$8e5148fef28cc57db487f7a8978cb345",
"last_login": "2023-08-02T08:25:40.786Z",
"is_superuser": true,
"username": "admin",
"first_name": "",
"last_name": "",
"email": "[email protected]",
"is_staff": true,
"is_active": true,
"date_joined": "2023-08-02T06:58:26.271Z",
"groups": [],
"user_permissions": []
}
{
"model": "wagtail_parler_tests.foodtranslation",
"pk": 1,
"fields": {
"language_code": "fr",
"name": "Gelée",
"summary": "Summary FR",
"content": "Content FR",
"qa": "[{\"type\": \"QaBlock\", \"value\": {\"text\": \"Pouvez-vous emmener une \\u00ab Jelly \\u00bb dans un avion ?\"}, \"id\": \"8c23eadb-60e0-4271-831d-332dd33ce36b\"}]",
"master": 1
}
},
{
"model": "wagtail_parler_tests.foodtranslation",
"pk": 2,
"fields": {
"language_code": "fr",
"name": "Pudding de Noël",
"summary": "Summary FR",
"content": "Content FR",
"qa": "[{\"type\": \"QaBlock\", \"value\": {\"text\": \"De quelle origine est ce plat ?\"}, \"id\": \"6b40015d-0cd9-48b4-8a06-3719cd6bce60\"}]",
"master": 2
}
},
{
"model": "wagtail_parler_tests.foodtranslation",
"pk": 3,
"fields": {
"language_code": "fr",
"name": "Omelette au fromage",
"summary": "Summary FR",
"content": "Content FR",
"qa": "[{\"type\": \"QaBlock\", \"value\": {\"text\": \"De quelle s\\u00e9rie parle t-on de \\\"Omelette du fromage\\\"\"}, \"id\": \"05aeb9c2-b6e3-42cb-ac6b-195f93885af4\"}]",
"master": 3
}
},
{
"model": "wagtail_parler_tests.foodtranslation",
"pk": 4,
"fields": {
"language_code": "fr",
"name": "Raclette",
"summary": "Summary FR",
"content": "Content FR",
"qa": "[{\"type\": \"QaBlock\", \"value\": {\"text\": \"Est-ce di\\u00e9t\\u00e9tique ?\"}, \"id\": \"a414bab0-97e9-4e3d-9ef1-5f2b2d165ece\"}]",
"master": 4
}
},
{
"model": "wagtail_parler_tests.foodtranslation",
"pk": 5,
"fields": {
"language_code": "en",
"name": "Jelly",
"summary": "Summary EN",
"content": "Content EN",
"qa": "[{\"type\": \"QaBlock\", \"value\": {\"text\": \"Can you bring a Jelly in a plane ?\"}, \"id\": \"bbc8985f-f249-4ce2-9cab-cee966ffb4aa\"}]",
"master": 1
}
},
{
"model": "wagtail_parler_tests.foodtranslation",
"pk": 6,
"fields": {
"language_code": "en",
"name": "Christmas Pudding",
"summary": "Summary EN",
"content": "Content EN",
"qa": "[{\"type\": \"QaBlock\", \"value\": {\"text\": \"What is the origin of this meal ?\"}, \"id\": \"a2a0a74c-7817-4129-a6d5-490c5af3afe9\"}]",
"master": 2
}
},
{
"model": "wagtail_parler_tests.food",
"pk": 1,
"fields": {
"yum_rating": 3,
"vegetarian": true,
"vegan": true
}
},
{
"model": "wagtail_parler_tests.food",
"pk": 2,
"fields": {
"yum_rating": 5,
"vegetarian": false,
"vegan": false
}
},
{
"model": "wagtail_parler_tests.food",
"pk": 3,
"fields": {
"yum_rating": 8,
"vegetarian": true,
"vegan": false
}
},
{
"model": "wagtail_parler_tests.food",
"pk": 4,
"fields": {
"yum_rating": 10,
"vegetarian": true,
"vegan": false
}
},
{
"model": "auth.user",
"pk": 1,
"fields": {
"password": "md5$Xibmtaqa1WGE7j0V46OcOQ$8e5148fef28cc57db487f7a8978cb345",
"last_login": "2023-09-12T07:47:24.764Z",
"is_superuser": true,
"username": "admin",
"first_name": "",
"last_name": "",
"email": "[email protected]",
"is_staff": true,
"is_active": true,
"date_joined": "2023-08-02T06:58:26.271Z",
"groups": [],
"user_permissions": []
}
},
{
"model": "auth.group",
"pk": 1,
"fields": {
"name": "Moderators",
"permissions": [
1,
2,
3,
5,
4,
6,
7,
9,
8
]
}
},
{
"model": "auth.group",
"pk": 2,
"fields": {
"name": "Editors",
"permissions": [
1,
2,
3,
5,
4,
6,
7,
9,
8
]
}
}
]
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ envlist =
py37-django32-wagtail{41,42,50},
py39-django42-wagtail{50,51},
py311-django42-wagtail51,
; py{39,311}-django42-wagtailmain
py{39,311}-django42-wagtailmain
qa

[testenv]
Expand Down
1 change: 1 addition & 0 deletions wagtail_parler/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
__version__ = "0.1.0"
default_app_config = "wagtail_parler.apps.WagtailParlerConfig"
53 changes: 53 additions & 0 deletions wagtail_parler/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Standard libs
import importlib
from typing import Optional
from typing import Tuple
import warnings

# Django imports
from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _

# Third Party
from wagtail.blocks.base import Block


class WagtailParlerConfig(AppConfig):
name = "wagtail_parler"
verbose_name = _("Wagtail Parler 🧀 🐦")

def ready(self) -> None:
if Block.__reduce__.__qualname__ == "object.__reduce__":
"""
Monkey Patch wagtail to be able to Pickle Blocks.
FIXME: remove this when related PR will be merged into wagtail.
It's required when parler cache translations which can have
StreamValue fields with Blocks as values.
If Block or it's bases (but object) don't have any __reduce__ method,
we need one to be able to Pickle instances of Blocks.
"""

def block_reduce(self: Block) -> Tuple:
path, args, kwargs = self.deconstruct()
return unreduce, (path, (args, kwargs))

Block.__reduce__ = block_reduce
else: # pragma: no cover
warnings.warn(
"Monkey Patch `block_reduce` is deprecated with this version of Wagtail",
DeprecationWarning,
stacklevel=2,
)


def unreduce(path: str, args_and_kwargs: Optional[Tuple] = None) -> object:
path_part = path.rsplit(".", 1)
module = importlib.import_module(path_part[0])
cls = getattr(module, path_part[1])
args: Tuple = tuple()
kwargs = {}
if args_and_kwargs and len(args_and_kwargs) >= 1:
args = args_and_kwargs[0]
if len(args_and_kwargs) >= 2:
kwargs = args_and_kwargs[1]
return cls(*args, **kwargs) # type: ignore
Loading

0 comments on commit b609f41

Please sign in to comment.