Skip to content

Commit fe39f52

Browse files
committed
Construct model only based on data without overwriting existing data.
1 parent c908044 commit fe39f52

File tree

8 files changed

+64
-26
lines changed

8 files changed

+64
-26
lines changed

conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ def pytest_configure():
1414

1515
installed_apps = [
1616
"example.coffee.apps.Config",
17+
"example.books.apps.Config",
1718
]
1819

1920
unicorn_settings = {

django_unicorn/serializer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def _parse_field_values_from_string(model: Model) -> None:
3939
"""
4040
Convert the model fields' value to match the field type if appropriate.
4141
42-
This is mostly to deal field string values that will get saved as a date-related field.
42+
This is mostly to deal with field string values that will get saved as a date-related field.
4343
"""
4444

4545
for field in model._meta.fields:

django_unicorn/views/utils.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import logging
22
from dataclasses import is_dataclass
3-
from typing import Any, Union
3+
from typing import Any, Dict, Set, Union
44

55
from django.db.models import Model, QuerySet
66

@@ -199,10 +199,38 @@ class TestComponent(UnicornView):
199199

200200
for (idx, model) in enumerate(queryset._result_cache):
201201
if model.pk == model_value.get("pk"):
202-
queryset._result_cache[idx] = model_type(**model_value)
202+
constructed_model = _construct_model(
203+
model_type, model_value, constructed_models
204+
)
205+
queryset._result_cache[idx] = constructed_model
203206
model_found = True
204207

205208
if not model_found:
206-
queryset._result_cache.append(model_type(**model_value))
209+
constructed_model = _construct_model(
210+
model_type, model_value, constructed_models
211+
)
212+
queryset._result_cache.append(constructed_model)
207213

208214
return queryset
215+
216+
217+
def _construct_model(model_type, model_data: Dict):
218+
if not model_data:
219+
return None
220+
221+
model = model_type()
222+
223+
for field_name in model_data.keys():
224+
for field in model._meta.fields:
225+
if field.name == field_name or (field_name == "pk" and field.primary_key):
226+
# if field.is_relation:
227+
# related_model = _construct_model(
228+
# field.model, model_data[field_name]
229+
# )
230+
# setattr(model, field.name, related_model)
231+
# else:
232+
233+
setattr(model, field.name, model_data[field_name])
234+
break
235+
236+
return model

example/books/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
default_app_config = "books.apps.Config"

example/books/apps.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from django.apps import AppConfig
2+
3+
4+
class Config(AppConfig):
5+
name = "example.books"

example/books/models.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
from django.db.models import Model
2-
from django.db.models.fields import CharField, DateField
1+
from django.db import models
32

43

5-
class Book(Model):
6-
title = CharField(max_length=255)
7-
date_published = DateField()
4+
class Book(models.Model):
5+
title = models.CharField(max_length=255)
6+
date_published = models.DateField()
7+
8+
9+
class Author(models.Model):
10+
name = models.CharField(max_length=1024)
11+
books = models.ManyToManyField(Book)

tests/serializer/test_dumps.py

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,7 @@
11
import json
22
from decimal import Decimal
33

4-
from django.db.models import (
5-
SET_NULL,
6-
CharField,
7-
DateField,
8-
DateTimeField,
9-
DurationField,
10-
ForeignKey,
11-
Model,
12-
TimeField,
13-
)
14-
from django.db.models.fields import CharField
4+
from django.db import models
155
from django.utils.timezone import now
166

177
import pytest
@@ -21,16 +11,16 @@
2111
from example.coffee.models import Flavor
2212

2313

24-
class SimpleTestModel(Model):
25-
name = CharField(max_length=10)
14+
class SimpleTestModel(models.Model):
15+
name = models.CharField(max_length=10)
2616

2717
class Meta:
2818
app_label = "tests"
2919

3020

31-
class ComplicatedTestModel(Model):
32-
name = CharField(max_length=10)
33-
parent = ForeignKey("self", blank=True, null=True, on_delete=SET_NULL)
21+
class ComplicatedTestModel(models.Model):
22+
name = models.CharField(max_length=10)
23+
parent = models.ForeignKey("self", blank=True, null=True, on_delete=models.SET_NULL)
3424

3525
class Meta:
3626
app_label = "tests"
@@ -179,7 +169,7 @@ def test_model_foreign_key():
179169
assert expected == actual
180170

181171

182-
def test_model_foreign_key_recurive_parents():
172+
def test_model_foreign_key_recursive_parent():
183173
test_model_one = ComplicatedTestModel(id=1, name="abc")
184174
test_model_two = ComplicatedTestModel(id=2, name="def", parent=test_model_one)
185175
test_model_one.parent = test_model_two

tests/views/utils/test_set_property_from_data.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,15 @@ def test_set_property_from_data_queryset_none_with_typehint():
138138
component_queryset_field_asserts(component, "queryset_with_typehint")
139139

140140

141+
def test_set_property_from_data_queryset_parent():
142+
component = FakeQuerySetComponent(component_name="test", component_id="12345678")
143+
assert component.queryset_with_typehint is None
144+
145+
set_property_from_data(component, "queryset_with_typehint", [{"name": "test-qs"}])
146+
147+
component_queryset_field_asserts(component, "queryset_with_typehint")
148+
149+
141150
def test_set_property_from_data_all_querysets():
142151
component = FakeAllQuerySetComponent(component_name="test", component_id="12345678")
143152

0 commit comments

Comments
 (0)