mirror of
https://github.com/jazzband/django-eav2.git
synced 2026-03-16 22:40:26 +00:00
* Add debug Q-expr print function * Change old __unicode__ methods to __str__ format * Move __unicode__ methods to __str__ * Rewrite AND Q-expressions to safe form * Make Q-expr debug print method use nicer format * Document rewrite_q_expr function * Rewrite/improve queries' test * Document some more code * Reorganize and document queryset module * Add more tests for queries * Use generic relation attribute instead instead of 'eav_values' * Update docstring * Fix a typo * Move up a variable * Rename a function * Check if 'in' filter rhs is not a QuerySet * Add newline to the end of file * Fix typo; tweak docstring
141 lines
5 KiB
Python
141 lines
5 KiB
Python
from django.contrib.auth.models import User
|
|
from django.core.exceptions import MultipleObjectsReturned
|
|
from django.db.models import Q
|
|
from django.test import TestCase
|
|
|
|
import eav
|
|
from eav.models import Attribute, EnumGroup, EnumValue, Value
|
|
from eav.registry import EavConfig
|
|
|
|
from .models import Encounter, ExampleModel, Patient
|
|
|
|
|
|
class Queries(TestCase):
|
|
def setUp(self):
|
|
eav.register(Encounter)
|
|
eav.register(Patient)
|
|
|
|
Attribute.objects.create(name='age', datatype=Attribute.TYPE_INT)
|
|
Attribute.objects.create(name='height', datatype=Attribute.TYPE_FLOAT)
|
|
Attribute.objects.create(name='weight', datatype=Attribute.TYPE_FLOAT)
|
|
Attribute.objects.create(name='city', datatype=Attribute.TYPE_TEXT)
|
|
Attribute.objects.create(name='country', datatype=Attribute.TYPE_TEXT)
|
|
|
|
self.yes = EnumValue.objects.create(value='yes')
|
|
self.no = EnumValue.objects.create(value='no')
|
|
self.unknown = EnumValue.objects.create(value='unknown')
|
|
|
|
ynu = EnumGroup.objects.create(name='Yes / No / Unknown')
|
|
ynu.enums.add(self.yes)
|
|
ynu.enums.add(self.no)
|
|
ynu.enums.add(self.unknown)
|
|
|
|
Attribute.objects.create(name='fever', datatype=Attribute.TYPE_ENUM, enum_group=ynu)
|
|
|
|
def tearDown(self):
|
|
eav.unregister(Encounter)
|
|
eav.unregister(Patient)
|
|
|
|
def test_get_or_create_with_eav(self):
|
|
p = Patient.objects.get_or_create(name='Bob', eav__age=5)
|
|
self.assertEqual(Patient.objects.count(), 1)
|
|
self.assertEqual(Value.objects.count(), 1)
|
|
p = Patient.objects.get_or_create(name='Bob', eav__age=5)
|
|
self.assertEqual(Patient.objects.count(), 1)
|
|
self.assertEqual(Value.objects.count(), 1)
|
|
p = Patient.objects.get_or_create(name='Bob', eav__age=6)
|
|
self.assertEqual(Patient.objects.count(), 2)
|
|
self.assertEqual(Value.objects.count(), 2)
|
|
|
|
def test_get_with_eav(self):
|
|
p1, _ = Patient.objects.get_or_create(name='Bob', eav__age=6)
|
|
self.assertEqual(Patient.objects.get(eav__age=6), p1)
|
|
|
|
p2, _ = Patient.objects.get_or_create(name='Fred', eav__age=6)
|
|
self.assertRaises(MultipleObjectsReturned, lambda: Patient.objects.get(eav__age=6))
|
|
|
|
def test_filtering_on_normal_and_eav_fields(self):
|
|
yes = self.yes
|
|
no = self.no
|
|
|
|
data = [
|
|
# Name, age, fever, city, country.
|
|
['Anne', 3, no, 'New York', 'USA'],
|
|
['Bob', 15, no, 'Bamako', 'Mali'],
|
|
['Cyrill', 15, yes, 'Kisumu', 'Kenya'],
|
|
['Daniel', 3, no, 'Nice', 'France'],
|
|
['Eugene', 2, yes, 'France', 'Nice']
|
|
]
|
|
|
|
for row in data:
|
|
Patient.objects.create(
|
|
name=row[0],
|
|
eav__age=row[1],
|
|
eav__fever=row[2],
|
|
eav__city=row[3],
|
|
eav__country=row[4]
|
|
)
|
|
|
|
# Check number of objects in DB.
|
|
self.assertEqual(Patient.objects.count(), 5)
|
|
self.assertEqual(Value.objects.count(), 20)
|
|
|
|
# Nobody
|
|
q1 = Q(eav__fever=yes) & Q(eav__fever=no)
|
|
p = Patient.objects.filter(q1)
|
|
self.assertEqual(p.count(), 0)
|
|
|
|
# Anne, Daniel
|
|
q1 = Q(eav__age__gte=3) # Everyone except Eugene
|
|
q2 = Q(eav__age__lt=15) # Anne, Daniel, Eugene
|
|
p = Patient.objects.filter(q2 & q1)
|
|
self.assertEqual(p.count(), 2)
|
|
|
|
# Anne
|
|
q1 = Q(eav__city__contains='Y') & Q(eav__fever=no)
|
|
q2 = Q(eav__age=3)
|
|
p = Patient.objects.filter(q1 & q2)
|
|
self.assertEqual(p.count(), 1)
|
|
|
|
# Anne, Daniel
|
|
q1 = Q(eav__city__contains='Y', eav__fever=no)
|
|
q2 = Q(eav__city='Nice')
|
|
q3 = Q(eav__age=3)
|
|
p = Patient.objects.filter((q1 | q2) & q3)
|
|
self.assertEqual(p.count(), 2)
|
|
|
|
# Everyone
|
|
q1 = Q(eav__fever=no) | Q(eav__fever=yes)
|
|
p = Patient.objects.filter(q1)
|
|
self.assertEqual(p.count(), 5)
|
|
|
|
# Anne, Bob, Daniel
|
|
q1 = Q(eav__fever=no) # Anne, Bob, Daniel
|
|
q2 = Q(eav__fever=yes) # Cyrill, Eugene
|
|
q3 = Q(eav__country__contains='e') # Cyrill, Daniel, Eugene
|
|
q4 = q2 & q3 # Cyrill, Daniel, Eugene
|
|
q5 = (q1 | q4) & q1 # Anne, Bob, Daniel
|
|
p = Patient.objects.filter(q5)
|
|
self.assertEqual(p.count(), 3)
|
|
|
|
# Everyone except Anne
|
|
q1 = Q(eav__city__contains='Y')
|
|
p = Patient.objects.exclude(q1)
|
|
self.assertEqual(p.count(), 4)
|
|
|
|
# Anne, Bob, Daniel
|
|
q1 = Q(eav__city__contains='Y')
|
|
q2 = Q(eav__fever=no)
|
|
q3 = q1 | q2
|
|
p = Patient.objects.filter(q3)
|
|
self.assertEqual(p.count(), 3)
|
|
|
|
# Anne, Daniel
|
|
q1 = Q(eav__age=3)
|
|
p = Patient.objects.filter(q1)
|
|
self.assertEqual(p.count(), 2)
|
|
|
|
# Eugene
|
|
q1 = Q(name__contains='E', eav__fever=yes)
|
|
p = Patient.objects.filter(q1)
|
|
self.assertEqual(p.count(), 1)
|