Skip to content

Commit e7e3c73

Browse files
committed
Add model value serializer.
1 parent f57233f commit e7e3c73

File tree

4 files changed

+97
-0
lines changed

4 files changed

+97
-0
lines changed

django_unicorn/components/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from .mixins import ModelValueMixin
12
from .typing import QuerySetType
23
from .unicorn_view import UnicornField, UnicornView
34
from .updaters import HashUpdate, LocationUpdate, PollUpdate
@@ -10,4 +11,5 @@
1011
"HashUpdate",
1112
"LocationUpdate",
1213
"PollUpdate",
14+
"ModelValueMixin",
1315
]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from django_unicorn.serializer import model_value
2+
3+
4+
class ModelValueMixin:
5+
"""
6+
Adds a `value` method to a model similar to `QuerySet.values(*fields)` which serializes
7+
a model into a dictionary with the fields as specified in the `fields` argument.
8+
"""
9+
10+
def value(self, *fields):
11+
return model_value(self, *fields)

django_unicorn/serializer.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,21 @@ def loads(str: str) -> dict:
197197
return orjson.loads(str)
198198
except orjson.JSONDecodeError as e:
199199
raise JSONDecodeError from e
200+
201+
202+
def model_value(model: Model, *fields: str):
203+
"""
204+
Serializes a model into a dictionary with the fields as specified in the `fields` argument.
205+
"""
206+
207+
model_data = {}
208+
model_dict = _get_model_dict(model)
209+
210+
if not fields:
211+
return model_dict
212+
213+
for field in fields:
214+
if field in model_dict:
215+
model_data[field] = model_dict[field]
216+
217+
return model_data
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
from django.db import models
2+
3+
from django_unicorn.components import ModelValueMixin
4+
from django_unicorn.serializer import model_value
5+
from example.coffee.models import Flavor
6+
7+
8+
def test_model_value_all_fields():
9+
flavor = Flavor(name="flavor-1")
10+
11+
expected = {
12+
"date": None,
13+
"datetime": None,
14+
"decimal_value": None,
15+
"duration": None,
16+
"float_value": None,
17+
"name": flavor.name,
18+
"label": "",
19+
"parent": None,
20+
"pk": None,
21+
"time": None,
22+
"uuid": str(flavor.uuid),
23+
}
24+
25+
actual = model_value(flavor)
26+
27+
assert expected == actual
28+
29+
30+
def test_model_value_one_field():
31+
expected = {"name": "flavor-1"}
32+
33+
flavor = Flavor(name="flavor-1")
34+
actual = model_value(flavor, "name")
35+
36+
assert expected == actual
37+
38+
39+
def test_model_value_multiple_field():
40+
expected = {
41+
"pk": 77,
42+
"name": "flavor-1",
43+
}
44+
45+
flavor = Flavor(name="flavor-1", id=77)
46+
actual = model_value(flavor, "pk", "name")
47+
48+
assert expected == actual
49+
50+
51+
class FakeModel(ModelValueMixin, models.Model):
52+
name = models.CharField(max_length=255)
53+
54+
class Meta:
55+
app_label = "tests"
56+
57+
58+
def test_model_value_mixin():
59+
test_model = FakeModel(name="test-model")
60+
expected = {"name": test_model.name}
61+
62+
actual = test_model.value("name")
63+
assert expected == actual
64+
65+
actual = model_value(test_model, "name")
66+
assert expected == actual

0 commit comments

Comments
 (0)