Skip to content

Commit deff580

Browse files
authored
fix computed fk field handling (#155)
Fix for Issue #155
2 parents 6bf64bd + a2ed67a commit deff580

File tree

4 files changed

+79
-6
lines changed

4 files changed

+79
-6
lines changed

computedfields/resolver.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ def extract_computed_models(self) -> Dict[Type[Model], Dict[str, IComputedField]
195195
raise ResolverException(f'{model} is not a subclass of ComputedFieldsModel')
196196
computed_models[model] = {}
197197
for field in computedfields:
198-
computed_models[model][field.attname] = field
198+
computed_models[model][field.name] = field
199199

200200
return computed_models
201201

example/example/settings.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,11 @@
9292
DATABASES = {
9393
'default': {
9494
'ENGINE': 'django.db.backends.postgresql',
95-
'NAME': 'postgres',
96-
'USER': 'postgres',
97-
'PASSWORD': 'mysecretpassword',
98-
'HOST': 'localhost',
99-
'PORT': 5432,
95+
'NAME': os.environ.get('DATABASE_NAME', 'postgres'),
96+
'USER': os.environ.get('DATABASE_USER', 'postgres'),
97+
'PASSWORD': os.environ.get('DATABASE_PASSWORD', 'mysecretpassword'),
98+
'HOST': os.environ.get('DATABASE_HOST', 'localhost'),
99+
'PORT': int(os.environ.get('DATABASE_PORT', '5432')),
100100
}
101101
}
102102

example/test_full/models.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,3 +1137,38 @@ def comp(self):
11371137
class RNM2MBar(models.Model):
11381138
b = models.CharField(max_length=10)
11391139
foos = models.ManyToManyField(RNM2MFoo, related_name='bars', related_query_name='bar')
1140+
1141+
1142+
# Computed Foreign Key models
1143+
## Base catalogues
1144+
class CFKCatalogue1(models.Model):
1145+
name = models.CharField(max_length=10)
1146+
1147+
class CFKCatalogue2(models.Model):
1148+
name = models.CharField(max_length=10)
1149+
1150+
## Some data in catalogues
1151+
class CFKData(ComputedFieldsModel):
1152+
c1name = models.CharField(max_length=10)
1153+
c2name = models.CharField(max_length=10)
1154+
1155+
@computed(models.ForeignKey(CFKCatalogue1, on_delete=models.CASCADE))
1156+
def c1(self):
1157+
return CFKCatalogue1.objects.get(name=self.c1name)
1158+
1159+
@computed(models.ForeignKey(CFKCatalogue2, on_delete=models.CASCADE))
1160+
def c2(self):
1161+
return CFKCatalogue2.objects.get(name=self.c2name)
1162+
1163+
## Some data related to parent data in catalogues
1164+
class CFKRelatedData(ComputedFieldsModel):
1165+
parent = models.ForeignKey(CFKData, on_delete=models.CASCADE)
1166+
value = models.CharField(max_length=10)
1167+
1168+
@computed(models.ForeignKey(CFKCatalogue1, on_delete=models.CASCADE))
1169+
def c1(self):
1170+
return self.parent.c1
1171+
1172+
@computed(models.ForeignKey(CFKCatalogue2, on_delete=models.CASCADE))
1173+
def c2(self):
1174+
return self.parent.c2
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from django.test import TestCase
2+
from .. import models
3+
4+
5+
class ComputedForeignKeys(TestCase):
6+
def setUp(self):
7+
self.names = ['a', 'b', 'c', 'd', 'e', 'f']
8+
for name in self.names:
9+
models.CFKCatalogue1.objects.create(name='c1%s' % name)
10+
models.CFKCatalogue2.objects.create(name='c2%s' % name)
11+
12+
def test_basic(self):
13+
for c1 in models.CFKCatalogue1.objects.all():
14+
for c2 in models.CFKCatalogue2.objects.all():
15+
m = models.CFKData.objects.create(c1name=c1.name, c2name=c2.name)
16+
self.assertEqual(m.c1, c1)
17+
self.assertEqual(m.c2, c2)
18+
for value in self.names:
19+
v = models.CFKRelatedData.objects.create(parent=m, value=value)
20+
self.assertEqual(v.c1, c1)
21+
self.assertEqual(v.c2, c2)
22+
23+
def test_cascade_delete(self):
24+
for c1 in models.CFKCatalogue1.objects.all():
25+
for c2 in models.CFKCatalogue2.objects.all():
26+
m = models.CFKData.objects.create(c1name=c1.name, c2name=c2.name)
27+
for value in self.names:
28+
models.CFKRelatedData.objects.create(parent=m, value=value)
29+
self.assertGreater(models.CFKData.objects.all().count(), 0)
30+
self.assertGreater(models.CFKRelatedData.objects.all().count(), 0)
31+
32+
# on deleting all CFKCatalogue1 instances
33+
# CFKData and CFKRelatedData should drop to zero count
34+
# due to cascade deletion
35+
for c1 in models.CFKCatalogue1.objects.all():
36+
c1.delete()
37+
self.assertEqual(models.CFKData.objects.all().count(), 0)
38+
self.assertEqual(models.CFKRelatedData.objects.all().count(), 0)

0 commit comments

Comments
 (0)