References/Specimen Definition
More languages
More actions
A SpecimenDefinition is a reusable, facility-scoped template for a kind of specimen: what material to collect, how to prepare the patient, how to collect it, and how it's held in a container for testing. A lab maintains a repository of these, and an References/Activity Definition or References/Service Request references one so the same container and handling rules apply every time. When a concrete References/Specimen is instantiated from a definition, the link is kept and the specimen copies the definition's data for history and integrity.
The Django model is only the storage layer: type_collected, patient_preparation, collection, and type_tested are opaque JSONFields. Their real structure — the enums, value-set bindings, and read/write API schemas — lives in the Pydantic resource specs documented below.
Source:
- Model: [https://github.com/ohcnetwork/care/blob/develop/care/emr/models/specimen_definition.py
care/emr/models/specimen_definition.py] - Resource spec: [https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/specimen_definition/spec.py
care/emr/resources/specimen_definition/spec.py] - Value sets: [https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/specimen_definition/valueset.py
care/emr/resources/specimen_definition/valueset.py] - Conversion helper: [https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/specimen_definition/specimen.py
care/emr/resources/specimen_definition/specimen.py] - ViewSet: [https://github.com/ohcnetwork/care/blob/develop/care/emr/api/viewsets/specimen_definition.py
care/emr/api/viewsets/specimen_definition.py]
Models
| Model | Purpose |
|---|---|
SpecimenDefinition
|
Reusable definition of a kind of specimen: what to collect, how to prepare the patient, how to collect it, and how it is contained and tested |
SpecimenDefinition extends SlugBaseModel: the Care EMR base with FACILITY_SCOPED = True, a facility-scoped slug, external_id, history/meta JSON, audit fields, and soft-delete semantics.
SpecimenDefinition fields
Identity & status
| Field | Type | Required | Notes |
|---|---|---|---|
facility |
FK → facility.Facility (PROTECT) |
model: optional | |
version |
IntegerField |
default 1
| |
slug |
CharField(255) |
yes (server-built) | |
title |
CharField(1024) |
yes | |
derived_from_uri |
TextField |
optional | |
status |
CharField(255) |
yes | |
description |
TextField |
yes |
Collection & testing detail (JSON fields)
The model stores these as raw JSON; the spec defines their true shape and value-set bindings.
| Field | Model type | Spec type | Notes |
|---|---|---|---|
type_collected
|
JSONField (null=True)
|
Coding bound to Specimen Type Code value set
|
Required on write. The kind of material collected. See [[#bound-value-sets |
patient_preparation
|
JSONField (default=list)
|
list[Coding] bound to Prepare Patient Prior Specimen Code value set
|
Defaults to []. Steps the patient follows before collection
|
collection
|
JSONField (null=True)
|
Coding bound to Specimen Collection Code value set, optional
|
The specimen collection procedure |
type_tested
|
JSONField (default=dict)
|
TypeTestedSpec (nested), optional
|
Container, handling, and testing detail. See [[#typetestedspec |
Each bound coded field accepts a
Codingobject ({ system, version?, code, display? });ValueSetBoundCodingvalidates thecodeagainst the bound value set at de-serialization time.
Related models
| Type | Where | Shape |
|---|---|---|
Coding
|
[https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/common/coding.py resources/common/coding.py]
|
{ system: str?, version: str?, code: str (required), display: str? }, extra="forbid"
|
QuantitySpec
|
spec.py | { value: Decimal (max_digits=20, decimal_places=0), unit: Coding } — decimal_places=0, so integer-valued
|
MinimumVolumeSpec
|
spec.py | { quantity: QuantitySpec?, string: str? }; a validator forbids supplying both
|
ContainerSpec
|
spec.py | { description: str?, capacity: QuantitySpec?, minimum_volume: MinimumVolumeSpec?, cap: Coding? (bound to Container Cap), preparation: str? }
|
DurationSpec
|
spec.py | { value: Decimal (max_digits=20, decimal_places=0), unit: Coding } — unit not yet restricted to datetime units
|
RangeSpec
|
spec.py | { low: QuantitySpec?, high: QuantitySpec? }
|
HandlingSpec
|
spec.py | { temperature_qualifier: HandlingConditionOptions?, temperature_range: RangeSpec?, max_duration: DurationSpec?, instruction: str? }
|
TypeTestedSpec
|
spec.py | see [[#typetestedspec |
TypeTestedSpec
The structured shape of the type_tested JSON field. A definition holds a single container; for multiple containers per test, repeat the definition in the References/Activity Definition spec.
| Field | Type | Required | Notes |
|---|---|---|---|
is_derived |
bool |
yes | |
preference |
PreferenceOptions |
yes | |
container |
ContainerSpec |
optional | |
requirement |
str |
optional | |
retention_time |
DurationSpec |
optional | |
single_use |
bool |
optional | |
handling |
HandlingSpec |
optional |
Enums
SpecimenDefinitionStatusOptions values
| Value | Meaning |
|---|---|
draft
|
Being authored, not yet in use |
active
|
In use |
retired
|
Withdrawn from use |
PreferenceOptions values
| Value | Meaning |
|---|---|
preferred
|
Preferred specimen for the test |
alternate
|
Acceptable alternative specimen |
HandlingConditionOptions values
| Value | Meaning |
|---|---|
room
|
Room temperature |
refrigerated
|
Refrigerated |
frozen
|
Frozen |
Resource specs (API schema)
All specs build on EMRResource (serialize/de_serialize, perform_extra_serialization/perform_extra_deserialization). __exclude__ = ["facility"] keeps facility out of both directions. The ViewSet wires pydantic_model = SpecimenDefinitionWriteSpec for create/update and pydantic_read_model = SpecimenDefinitionReadSpec for list/retrieve.
| Spec class | Role | Fields / behaviour |
|---|---|---|
BaseSpecimenDefinitionSpec
|
shared base | id, title, derived_from_uri, status, description, type_collected, patient_preparation, collection, type_tested. Holds the coded-field value-set bindings and the nested type_tested shape
|
SpecimenDefinitionWriteSpec
|
write · create & update | Base fields plus slug_value: SlugType. perform_extra_deserialization copies slug_value → obj.slug (the ViewSet then fully-qualifies it). facility, version, and the stored slug are never client-supplied
|
SpecimenDefinitionReadSpec
|
read · list & detail | Base fields plus version: int?, slug: str, slug_config: dict. perform_extra_serialization sets id = obj.external_id and slug_config = obj.parse_slug(obj.slug), decomposing the qualified slug into { facility, slug_value }
|
Nested specs used by the schemas: TypeTestedSpec, ContainerSpec, MinimumVolumeSpec, QuantitySpec, DurationSpec, RangeSpec, HandlingSpec (see Related models).
Validation rules
slug_value(SlugType): string, length 5–50, matching^[a-zA-Z0-9][a-zA-Z0-9_-]*[a-zA-Z0-9]$(URL-safe; starts and ends alphanumeric).- Coded fields
type_collected,patient_preparation[*],collection, andcontainer.cap:ValueSetBoundCodingvalidates eachCoding.codeagainst its bound value set during de-serialization and rejects unknown codes. MinimumVolumeSpec:quantityandstringare mutually exclusive — supplying both raises"Only one of quantity or string should be provided".QuantitySpec/DurationSpecvalue:Decimal,max_digits=20,decimal_places=0(integer-valued).- Slug uniqueness (ViewSet
validate_data): the fully-qualifiedf-<facility>-<slug_value>must be unique within the facility (case-insensitive), else"Specimen Definition with this slug already exists."On update, the current record is excluded from the check.
Bound value sets
| Field | Value set | Slug | Source system(s) |
|---|---|---|---|
type_collected
|
Specimen Type Code | system-specimen_type-code
|
HL7 v2-0487 (unbounded include) |
patient_preparation[*]
|
Prepare Patient Prior Specimen Code | system-prepare_patient_prior_specimen_code
|
SNOMED CT, is-a 703763000
|
collection
|
Specimen Collection Code | system-specimen_collection_code
|
SNOMED CT (curated list: aspiration, biopsy, puncture, excision, scraping, clean-catch/timed/catheterized urine, coughed sputum, finger-prick) |
container.cap
|
Container Cap | system-container_cap-code
|
HL7 container-cap code system
|
Methods & save behaviour
SpecimenDefinition overrides no save()/delete() and defines no custom methods. Slug helpers, audit fields, and soft-delete come from SlugBaseModel. The side effects below live in the resource spec and the ViewSet, not the model:
- Slug qualification (write). Clients send a bare
slug_value.SpecimenDefinitionWriteSpec.perform_extra_deserializationsetsobj.slug = slug_value; then the ViewSet'sperform_create/perform_updaterewrites it viaSpecimenDefinition.calculate_slug_from_facility(facility.external_id, slug)→f-<facility_external_id>-<slug_value>. - Facility binding (create).
perform_createsetsinstance.facilityfrom thefacility_external_idURL kwarg before saving. - Slug decomposition (read).
SpecimenDefinitionReadSpec.perform_extra_serializationexposesslug_config = obj.parse_slug(obj.slug), splitting the stored slug back into{ facility, slug_value }. - Specimen instantiation.
convert_sd_to_specimen([https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/specimen_definition/specimen.pyspecimen.py]) builds aSpecimenfrom a definition withstatus="available",specimen_type = definition.type_collected, andspecimen_definition = <definition>, preserving the link and a copy of the type.
API integration notes
- Endpoints are facility-scoped. The ViewSet supports create, retrieve, update, list, and upsert with
lookup_field = "slug". Every operation requiresfacility_external_idin the URL. - Authorization. Writes require
can_write_facility_specimen_definition; list/retrieve requirecan_list_facility_specimen_definitionon the facility — otherwise403 PermissionDenied. The queryset is filtered to the URL facility. - Filtering / ordering.
status(iexact) andtitle(icontains) filters; ordering bycreated_date/modified_date. - Write payload (
SpecimenDefinitionWriteSpec): sendslug_value,title,status,description, the coded fields (type_collected,patient_preparation,collection) asCodingobjects, andtype_tested. Don't sendfacility,version, or the qualifiedslug— they're server-managed. - Read payload (
SpecimenDefinitionReadSpec): addsid(=external_id),version, the qualifiedslug, andslug_config. - The model maps to the FHIR
SpecimenDefinitionresource. Care's spec is intentionally minimal: one container per definition, and behaviour changes bumpversionrather than mutate published records.
Related
Pages that link here:
- Reference: References/Value Set