Skip to content

Commit

Permalink
-
Browse files Browse the repository at this point in the history
  • Loading branch information
erikvw committed Oct 18, 2023
1 parent e89dba2 commit 48fd62f
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 15 deletions.
14 changes: 8 additions & 6 deletions edc_reference/reference/reference_getter.py
Expand Up @@ -44,6 +44,7 @@ def __init__(
timepoint: Decimal | None = None,
site=None,
create: bool | None = None,
proxy_model_reference_name: str | None = None,
):
self._object: Reference | None = None
self.created: bool = False
Expand All @@ -55,10 +56,11 @@ def __init__(
if model_obj:
if model_obj._meta.proxy:
# always revert to the proxy_for_model
proxy_model_reference_name = model_obj.reference_name
model_obj = model_obj._meta.proxy_for_model.objects.get(id=model_obj.id)
try:
# given a crf model as model_obj
self.name = model_obj.reference_name
self.name = proxy_model_reference_name or model_obj.reference_name
self.report_datetime = model_obj.related_visit.report_datetime
self.schedule_name = model_obj.related_visit.schedule_name
self.site = model_obj.related_visit.site
Expand All @@ -71,7 +73,7 @@ def __init__(
if "related_visit" not in str(e):
raise
# given a visit model as model_obj
self.name = model_obj.reference_name
self.name = proxy_model_reference_name or model_obj.reference_name
self.report_datetime = model_obj.report_datetime
self.schedule_name = model_obj.schedule_name
self.site = model_obj.site
Expand All @@ -81,7 +83,7 @@ def __init__(
self.visit_code_sequence = model_obj.visit_code_sequence
self.visit_schedule_name = model_obj.visit_schedule_name
elif related_visit:
self.name = name
self.name = proxy_model_reference_name or name
self.report_datetime = related_visit.report_datetime
self.schedule_name = related_visit.schedule_name
self.site = related_visit.site
Expand All @@ -92,7 +94,7 @@ def __init__(
self.visit_schedule_name = related_visit.visit_schedule_name
else:
# given only the attrs
self.name = name
self.name = proxy_model_reference_name or name
self.report_datetime = report_datetime
self.schedule_name = schedule_name
self.site = site
Expand All @@ -102,11 +104,11 @@ def __init__(
self.visit_code_sequence = visit_code_sequence
self.visit_schedule_name = visit_schedule_name

reference_model: str = site_reference_configs.get_reference_model(name=self.name)
if site_reference_configs.get_model(self.name)._meta.proxy:
if not model_obj and site_reference_configs.get_model(self.name)._meta.proxy:
raise ReferenceGetterError(
"May not be a proxy model. Provide the concrete model instead."
)
reference_model: str = site_reference_configs.get_reference_model(name=self.name)
self.reference_model_cls: Type[Reference] = django_apps.get_model(reference_model)

# note: updater needs to "update_value"
Expand Down
14 changes: 9 additions & 5 deletions edc_reference/reference/reference_updater.py
Expand Up @@ -38,16 +38,17 @@ class ReferenceUpdater:
getter_cls = ReferenceGetter

def __init__(self, model_obj: AnyNonCrfModel | AnyCrfModel | ReferenceModelMixin = None):
proxy_model_reference_name: str | None = None
self.model_obj = model_obj
reference_name = self.model_obj.reference_name
if self.model_obj._meta.proxy:
proxy_model_reference_name: str = self.model_obj.reference_name
self.model_obj = self.model_obj._meta.proxy_for_model.objects.get(id=model_obj.id)
# raise ReferenceUpdaterModelError(
# "Not allowed. ReferenceUpdater does not accept proxy models. "
# f"Got `{self.model_obj.reference_name}`. "
# )
reference_fields = site_reference_configs.get_fields(
name=self.model_obj.reference_name
)
reference_fields = site_reference_configs.get_fields(name=reference_name)
# loop through fields and update or create each
# reference model instance
for field_name in reference_fields:
Expand All @@ -58,12 +59,15 @@ def __init__(self, model_obj: AnyNonCrfModel | AnyCrfModel | ReferenceModelMixin
except IndexError:
raise ReferenceFieldNotFound(
f"Reference field not found on model. Got '{field_name}'. "
f"See reference config for {self.model_obj.reference_name}. "
f"See reference config for {reference_name}. "
f"Model fields are "
f"{[fld.name for fld in self.model_obj._meta.get_fields()]}"
)
reference_getter = self.getter_cls(
model_obj=self.model_obj, field_name=field_name, create=True
proxy_model_reference_name=proxy_model_reference_name,
model_obj=self.model_obj,
field_name=field_name,
create=True,
)
if field_obj.name == "report_datetime":
try:
Expand Down
37 changes: 34 additions & 3 deletions edc_reference/tests/tests/test_reference_with_proxy.py
@@ -1,14 +1,16 @@
from django.contrib.sites.models import Site
from django.test import tag
from edc_lab.models.panel import Panel
from edc_lab_panel.constants import CD4, FBC, VL
from edc_visit_schedule.site_visit_schedules import site_visit_schedules
from edc_visit_tracking.models import SubjectVisit

from edc_reference.models import Reference
from edc_reference.reference import ReferenceGetter, ReferenceUpdater
from reference_app.models import CrfOne, CrfOneProxyOne
from reference_app.models import CrfOne, CrfOneProxyOne, CrfOneProxyTwo
from reference_app.register_reference_configs import register_reference_configs
from reference_app.visit_schedules import visit_schedule2
from reference_app.visit_schedules.visit_schedule3 import visit_schedule3

from .test_case import TestCase

Expand All @@ -19,12 +21,13 @@ def setUp(self):
self.panel_vl = Panel.objects.get(name=VL)
self.panel_fbc = Panel.objects.get(name=FBC)
self.site = Site.objects.get_current()

@tag("2")
def test_with_proxy(self):
site_visit_schedules._registry = {}
site_visit_schedules.register(visit_schedule2)
register_reference_configs()
self.prepare_subject_visit("reference_app.onscheduletwo")

def test_with_proxy(self):
self.subject_visit = SubjectVisit.objects.get(
visit_code="1000", visit_schedule_name="visit_schedule2"
)
Expand All @@ -44,3 +47,31 @@ def test_with_proxy(self):
ReferenceUpdater(model_obj=model_obj)
reference = ReferenceGetter(field_name="field_str", model_obj=model_obj)
self.assertEqual(reference.value, "bob")

@tag("1")
def test_with_proxy_without_registered_proxy_for_model(self):
site_visit_schedules._registry = {}
site_visit_schedules.register(visit_schedule3)
register_reference_configs(proxy_only=True)
self.prepare_subject_visit("reference_app.onscheduletwo")
self.subject_visit = SubjectVisit.objects.get(
visit_code="1000", visit_schedule_name="visit_schedule3"
)

model_obj = CrfOneProxyOne.objects.create(
subject_visit=self.subject_visit, field_str="erik"
)
ReferenceUpdater(model_obj=model_obj)
reference = Reference.objects.get(
identifier=self.subject_identifier,
timepoint=self.subject_visit.timepoint,
field_name="field_str",
)
self.assertEqual(reference.value, "erik")

model_obj = CrfOneProxyTwo.objects.create(
subject_visit=self.subject_visit, field_str="bob"
)
ReferenceUpdater(model_obj=model_obj)
reference = ReferenceGetter(field_name="field_str", model_obj=model_obj)
self.assertEqual(reference.value, "bob")
21 changes: 20 additions & 1 deletion reference_app/register_reference_configs.py
@@ -1,7 +1,7 @@
from edc_reference import site_reference_configs


def register_reference_configs():
def register_reference_configs(visit_schedule_name: str = None):
site_reference_configs.registry = {}
site_reference_configs.loaded = False

Expand All @@ -20,7 +20,26 @@ def register_reference_configs():
"field_datetime",
"field_int",
],
"reference_app.crfoneproxyone": [
"field_str",
"field_date",
"field_datetime",
"field_int",
],
"reference_app.crfoneproxytwo": [
"field_str",
"field_date",
"field_datetime",
"field_int",
],
}

if visit_schedule_name == "visit_schedule1":
del configs["reference_app.crfoneproxyone"]
del configs["reference_app.crfoneproxytwo"]

if visit_schedule_name == "visit_schedule3":
del configs["reference_app.crfone"]

for reference_name, fields in configs.items():
site_reference_configs.add_fields_to_config(name=reference_name, fields=fields)
77 changes: 77 additions & 0 deletions reference_app/visit_schedules/visit_schedule3.py
@@ -0,0 +1,77 @@
from dateutil.relativedelta import relativedelta
from edc_lab_panel.panels import cd4_panel, fbc_panel, vl_panel
from edc_visit_schedule.schedule import Schedule
from edc_visit_schedule.visit import Crf, FormsCollection, Requisition, Visit
from edc_visit_schedule.visit_schedule import VisitSchedule

from ..lab_profiles import panel_one, panel_two

crfs = FormsCollection(
Crf(show_order=20, model="reference_app.crfoneproxyone", required=True),
Crf(show_order=30, model="reference_app.crfoneproxytwo", required=True),
Crf(show_order=40, model="reference_app.testmodel", required=True),
)

requisitions = FormsCollection(
Requisition(show_order=10, panel=cd4_panel, required=True, additional=False),
Requisition(show_order=20, panel=panel_one, required=True, additional=False),
Requisition(show_order=30, panel=panel_two, required=True, additional=False),
Requisition(show_order=40, panel=fbc_panel, required=True, additional=False),
Requisition(show_order=50, panel=vl_panel, required=True, additional=False),
)

visit0 = Visit(
code="1000",
title="Day 1",
timepoint=0,
rbase=relativedelta(days=0),
rlower=relativedelta(days=0),
rupper=relativedelta(days=6),
crfs=crfs,
requisitions=requisitions,
facility_name="7-day-clinic",
)

visit1 = Visit(
code="2000",
title="Day 2",
timepoint=1,
rbase=relativedelta(days=7),
rlower=relativedelta(days=6),
rupper=relativedelta(days=6),
crfs=crfs,
requisitions=requisitions,
facility_name="7-day-clinic",
)

visit2 = Visit(
code="3000",
title="Day 3",
timepoint=2,
rbase=relativedelta(days=14),
rlower=relativedelta(days=6),
rupper=relativedelta(days=6),
crfs=crfs,
requisitions=requisitions,
facility_name="7-day-clinic",
)

schedule = Schedule(
name="schedule2",
onschedule_model="reference_app.onscheduletwo",
offschedule_model="reference_app.offscheduletwo",
appointment_model="edc_appointment.appointment",
consent_model="reference_app.subjectconsent",
)

schedule.add_visit(visit0)
schedule.add_visit(visit1)
schedule.add_visit(visit2)

visit_schedule3 = VisitSchedule(
name="visit_schedule3",
offstudy_model="reference_app.subjectoffstudy",
death_report_model="reference_app.deathreport",
)

visit_schedule3.add_schedule(schedule)

0 comments on commit 48fd62f

Please sign in to comment.