Models

MEG Forms

Main models representing institution and form structure

class megforms.models.ComplianceLevels(pass_first, pass_second)

Create new instance of ComplianceLevels(pass_first, pass_second)

pass_first

Alias for field number 0

pass_second

Alias for field number 1

class megforms.models.ObservationQueryset(model=None, query=None, using=None, hints=None)

Base QuerySet class for observation model subclasses

aggregate_by_answer(*fields: Question | str, compliance=True, counter_logic: Literal['audits', 'observations'] = 'observations') QuerySet[dict[str, Any]]

Groups observations by answers and returns number of observations/compliance having that answer.

Example result can look like this:

[
    {"field_name": 'value1', "field_2": 1', "compliance": 0.95, "count": 50},
    {"field_name": 'value2', "field_2": 1', "compliance": 0.20, "count": 3},
    {"field_name": 'value2', "field_2": 2', "compliance": None, "count": 10},
]

Notes:

  • the key of the answer depends on the question’s field name

  • if question is a multichoice field, the result will treat each combination of answers as a separate answer. This method will not split multichoice items.

  • if multiple fields are passed, the results will be aggregated by unique combination of values in those fields. If you need to split answers, use expand_aggregate_compliances()

If you are expecting one of the fields to have multiple values (multichoice), use expand_aggregate_compliances(), and then combine_aggregates_values() to combine those values. For example:

agg = qs.aggregate_by_answer(ward, multichoice_field)
expanded = expand_aggregate_compliances(agg)
combined_dict = combine_aggregates_values(expanded)
Parameters:
  • fields

    Questions or fields to use for grouping. Can be one of the following:

    • hardcoded field belonging to this observation model

    • custom field - either observation, or custom subform field.

    • string representing django query (e.g. ‘ward__department__name’)

  • compliance – whether to include average compliance in the result

  • counter_logic – whether to count by audit sessions or observations. Defaults to counting observations

Returns:

queryset containing field values with their respective count, and optionally average compliance of observations having this value

get_distinct_answers(field: Question) Iterator[Answer]

Gets one instance of each answer used in any of the observations or subobservations in this queryset. Null answers are excluded. if field is a subform field, a subobservation queryset is used for all observations in this qs. If field belongs to another hardcoded model than queryset, no answers are returned and no error is raised. If field is a foreign key, only object ids are returned

NOTE: you may get duplicate values if the field is a multichoice field as the choices are flattened. In this case it is a good idea to pass result into a set to ensure items are unique.

annotate_datetime() Self

Adds datetime annotation with value from session end time.

Returns:

annotated queryset

annotate_compliance_data(*, field_name='compliance_data', query='compliance_data') ObservationQueryset

Annotates the observation queryset with compliance data fields. The field represents a dict, mapping field name to field compliance, or subform name to list of sub-observation compliance maps.

Parameters:
  • field_name – name of the field to annotate as

  • query – name or path of the field to get compliance from. By default, returns compliance dict from compliance_data field, but it is also possible to use answer_compliance, or subform compliance field, or extract value for particular subform, for exmaple “compliance_data__subform_name” - in this case, the annotated value will be a list.

Returns:

observation queryset with added annotation.

annotate_average_compliance(annotation_name='compliance', *, weights: dict[str, float], compliance_field: Literal['field_compliance', 'subform_compliance'] = 'field_compliance') ObservationQueryset

Annotates the queryset with weighted average compliance data for a subset of compliance fields or subforms

Parameters:
  • annotation_name – name for the annotation

  • weights – names (mapped to weights to use); maps field/subform name to its weight. This data will typically be extracted from fields/subforms themselves.

  • compliance_field – Field in observation compliance to use, depending if field or subform compliance is calculated.

Examples:

>>> observations = CustomObservation.objects.annotate_average_compliance(weights={'important_field': 2.0, 'lesser_field': 1.0}, compliance_field='field_compliance')
>>> observations.get(pk=1).compliance
0.85
>>> observations.aggregate(avg_compliance=models.Avg('compliance'))
0.95
annotate_compliance(annotation_name='compliance', *, field_name: str | None = None) ObservationQueryset

Annotates the queryset with compliance data

Parameters:
  • annotation_name – name for the annotation

  • field_name – calculate compliance only for this field (as opposed for entire observation)

Examples:

>>> observations = CustomObservation.objects.annotate_compliance()
>>> observations.get(pk=1).compliance
0.85
>>> observations.aggregate(avg_compliance=models.Avg('compliance'))
0.95
delete()

Delete the records in the current QuerySet.

prefetch_subobservations(*select_related) ObservationQueryset

Selects related subobservations using select_related method Args: select_related: additional fields to be selected

for_user(user: User) ObservationQueryset

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

for_auditor_forms(auditor: Auditor, *forms: AuditForm, readonly: bool = True) Self

Filters CustomObservations for an auditor across one or more forms and applys ward ringfencing in a single query.

This method combines the logic for handling single forms, multiple forms, ward-based permissions into one optimized operation.

  • A global auditor bypasses all filtering.

  • If no auditor is provided, only the base form filter is applied.

  • Ward ringfencing includes:
    1. Ward permissions from AuditorPermissionCache.

    2. Read-only access for forms with advanced ringfencing enabled.

Parameters:
  • auditor – The Auditor to filter observations for.

  • forms – A list of one or more AuditForm objects.

  • readonly – If True, includes observations the auditor has read-only access to via advanced ward ringfencing.

Returns:

A filtered ObservationQuerySet.

property related_observation_ids: Iterable[int]

Set of primary keys of the CustomObservation instances related to observation queryset. Both way link relation is included in this set.

Returns:

set of ids

property related_observations: ObservationQueryset

Related observations - observations linked to this observation queryset or linking to this observation queryset Note: This includes all related observations, including:

  • unpublished observations

  • observation whose relation is no longer valid (form relation was removed)

class megforms.models.BaseAuditModel(*args, **kwargs)
classmethod get_subforms() Sequence[Type[BaseSubObservation]]

Gets tuple of subform class for this form.

Returns:

tuple, or empty tuple if this form doesn’t have subforms

get_sub_observations() Iterator[BaseSubObservation]

Yields sub observation instances for this observation. Only yields non-null subobsrvations. Yields nothing if this model has no subobservations, or none have been submitted to this observation instance.

classmethod get_questions(config: AuditFormConfig | None = None, include_fields: list[str] = None) Iterator[Field]

Gets field iterator for question fields Excludes non-question fields such as inherited from base class

get_field_compliance(field_name) float | None

Calculates compliance for a single field

Returns:

compliance value (0.0 - 1.0) or None

get_compliance(field_names=None) float | None

Should return a number between 0.0 and 1.0 representing how compliant this observation is. Optionally can return None if compliance cannot be determined.

clean_fields(exclude=None)

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

property review_url: str

url to the review page of this observation

class megforms.models.SubObservationQuerySet(model=None, query=None, using=None, hints=None)
class megforms.models.BaseSubObservation(*args, **kwargs)

Base class for sub-observations

issues_queryset

Queryset of issues for this sub-observation

classmethod get_questions(config=None) Iterator[Field]

Gets field iterator for question fields Excludes non-question fields such as inherited from base class

get_compliance(field_names=None) float | None

Calculate average compliance and return as a float between 0 and 1 returns None if there are no answers

calculate_average_compliance(field_names=None) float | None

Calculate average compliance and return as a float between 0 and 1 returns None if there are no answers

class megforms.models.FormTypeQuerySet(model=None, query=None, using=None, hints=None)
get_or_create_by_name(name: str, **kwargs) FormType

Gets form type by its (English) name, or creates a new type if it does not already exist

Parameters:
  • name – name of the form type, in English, for example “audit” or “incident”

  • kwargs – any additional arguments to use when creating object (e.g. ‘module’)

Returns:

form type with given name. Creates a new form type if one does not already exist

audit() FormType

Gets or creates the default (audit) form type.

class megforms.models.FormType(id, order, publish, uid, created, modified, name, name_plural, color, slug, logo, module, confidential_label)
property all_forms_description: str

Translatable placeholder to describe all forms of this type. e.g.: all audit forms, all questionnaire forms

exception DoesNotExist
exception MultipleObjectsReturned
clean_fields(exclude: Collection[str] | None = None) None

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

get_deferred_fields() set[str]

Return a set containing names of deferred fields for this instance.

refresh_from_db(using: str | None = None, fields: Sequence[str] | None = None) None

Reload field values from the database.

By default, the reloading happens from the database this instance was loaded from, or by the read router if this instance wasn’t loaded from any database. The using parameter will override the default.

Fields can be used to specify which fields to reload. The fields should be an iterable of field attnames. If fields is None, then all non-deferred fields are reloaded.

When accessing deferred fields of an instance, the deferred loading of the field will call this method.

class megforms.models.AuditFormQueryset(model=None, query=None, using=None, hints=None)
qip()

Only forms having QIP enabled

valid()

Filters out audit forms with invalid observation model selection.

for_institutions(institutions: Iterable[Institution]) AuditFormQueryset

Returns audit forms of the selected institutions

for_institution(institution)

Returns audit forms of the selected institutions

without_subforms()

filters out audit forms with subforms

with_subforms()

filters out audit forms without subforms

accepting_new_submissions()

Only forms accepting new submissions

exception IncompatibleCustomAuditsError(main_form, second_form, fields_data)

Error raised when merging custom audits where audits are not compatible

Args:

main_form: the main audit form where other forms are merged second_form: the form beinge merged fields_data: set of fields (subform name, field name) present in second_form, but not in main_form

merge() AuditForm

Merge audit forms in the queryset into a single (possible group-level) audit form all observations are moved into the first audit form, and the rest of the forms are unpublished

Returns:

single audit form

update_schema_modified()

Update schema modified to Now on selected audit forms

with_subform_count() Self

Add a count of related published CustomSubforms. None for hardcoded AuditForms that cannot be related to the CustomSubform model.

megforms.models.default_form_type() int

Returns the id of the default form type (audit)

class megforms.models.AuditForm(id, order, publish, uid, created, modified, name, type, pricing_status, slug, description, original_file, observation_model, institution, level, patient_data, cloned_from, schema_modified, archive, credits, profile)
get_observation_str

Gets a function that takes observation and returns its string representation based on form’s config (app_review_fields)

property report_rules_list: ReportRuleQuerySet

Report rules relevant to this form. Group level forms can be associated with all report rules in the group. Institution level forms can be associated with institution level report rules from the same institution, or group level report rules from the group.

clean_fields(exclude: Collection[str] | None = None) None

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

clean()

Hook for doing any extra model-wide validation after clean() has been called on every field by self.clean_fields. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field defined by NON_FIELD_ERRORS.

exception FormDoesNotExistError(model)
get_observation_model() Type[BaseAuditModel]

Imports observation_model as class

Returns:

Class for observation_model

property observation_model_cls: Type[BaseAuditModel]

Imports observation_model as class

Returns:

Class for observation_model

is_custom_form

Tells whether this form is a custom form

property is_hardcoded_form: bool

Tells whether this form is a hardcoded form

get_hardcoded_fields() Iterator[Field]

Gets all hardcoded fields in this audit, including subform fields

property custom_fields_allowed: bool

Whether this audit can have custom fields

get_subform_count() int

Return the number of subforms on the AuditForm. Runs more efficiently for custom AuditForms if the Queryset is annotated with ‘with_subform_count()’. Hardcoded AuditForms behaviour cannot be improved.

get_subform(name: str) Subform | None

Gets subform by name Returns hardcoded or custom subform

property entries: ObservationQueryset

Collection of ALL entries for this form published or not

Returns:

Queryset for entries for this form

get_observations(auditor: Auditor) ObservationQueryset

Filter CustomObservation for this form and user by custom answer filters

Parameters:

auditor – Auditor

Returns:

CustomObservationQuerySet

get_field(field_name: str) Question

Gets Field or CustomField instance by name. Looks for model fields first, then custom fields, so passing any non-question field (Ward, auditor, date, etc) will result in that model field being returned. If custom field is unpublished, it will still be returned.

Parameters:

field_name – name of the field, or custom field

Returns:

CustomField or model field instance

Raises:

KeyError – if field with given name does not exist in the form or any subform.

get_questions(include_subforms: bool = True, include_base: bool = False, include_related: bool = False, subforms: Sequence[Subform] | None = None, compliance_only: bool = False) Iterator[Question]

All questions in this form, optionally including subform questions and fields inherited from base observation (auditor, ward, etc)

Parameters:
  • include_subforms – whether to include fields from subforms in the result

  • include_base – whether to include fields from BaseAuditModel such as ward, auditor, etc.

  • include_related – whether to include fields from related AuditForm.

  • subforms – narrow down fields to only those belonging to the selected subforms. Leave empty to return fields from all observations

  • compliance_only – whether to include only compliance fields

Yields:

Instances of django model fields and custom fields

field_map(include_related: bool = False) dict[str, Question]

All questions in this form mapped by their field name

get_authorised_auditors(include_global: bool = True) AuditorQueryset

Auditors with access to this form and an active account

Custom fields linked to this audit form via related observations.

get_level_name_display()

Get level related institution or group name

exception DoesNotExist
exception MultipleObjectsReturned
get_deferred_fields() set[str]

Return a set containing names of deferred fields for this instance.

refresh_from_db(using: str | None = None, fields: Sequence[str] | None = None) None

Reload field values from the database.

By default, the reloading happens from the database this instance was loaded from, or by the read router if this instance wasn’t loaded from any database. The using parameter will override the default.

Fields can be used to specify which fields to reload. The fields should be an iterable of field attnames. If fields is None, then all non-deferred fields are reloaded.

When accessing deferred fields of an instance, the deferred loading of the field will call this method.

class megforms.models.AuditFormConfigQueryset(model=None, query=None, using=None, hints=None)
qip()

Only configs having QIP enabled

class megforms.models.AuditFormConfig(*args, **kwargs)

Stores configuration options for an audit form (AuditForm)

config: FormConfig

As per Task #29398 any bespoke config options should utilize the json config field below

property originator_editable_days: int

Returns allowed number of days that originator is allowed to edit his own submissions. when value is zero editing is not allowed

Forms related by this config and relating to this audit form (two way)

get_instant_report_fields(model: Type[BaseAuditModel]) Iterator[str]

Yields field names one by one filters out fields that dont belong to the specified model only yields field names, stripping out model name Also includes subform fields that don’t have a model prefix

get_default_review_cycle() str | None

Returns the default review cycle from the json config if present

get_expiry_date_field() str | None

Returns the expiry date field from the json config if present

property compliance_levels: ComplianceLevels

Compliance first and second threshold as a tuple

property check_add_observation: bool

Returns whether the form requires users to have add_customobservation permission to submit observations. Defaults to False.

clean_fields(exclude: Collection[str] | None = None) None

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

get_profession_choices() Sequence[Tuple[str, str]]

Profession choices (list of choice tuples) for HH audit based on this configuration. if profession choices config is not set, will return empty list

sub_form_models

Set of subform models selected by user

Returns:

Set containing model classes

terms_dict

Dictionary containing terms used in this form to refer to issues and sub-issues.

exception DoesNotExist
exception MultipleObjectsReturned
get_deferred_fields() set[str]

Return a set containing names of deferred fields for this instance.

refresh_from_db(using: str | None = None, fields: Sequence[str] | None = None) None

Reload field values from the database.

By default, the reloading happens from the database this instance was loaded from, or by the read router if this instance wasn’t loaded from any database. The using parameter will override the default.

Fields can be used to specify which fields to reload. The fields should be an iterable of field attnames. If fields is None, then all non-deferred fields are reloaded.

When accessing deferred fields of an instance, the deferred loading of the field will call this method.

class megforms.models.AuditSessionQueryset(model=None, query=None, using=None, hints=None)
for_user(user: User) AuditSessionQueryset

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

in_progress() AuditSessionQueryset

Submissions whose current stage is less than form’s max stage. This effectively filters out submissions from single-stage forms and submissions at the final (complete) stage.

model_dict() dict[type[megforms.models.BaseAuditModel], type[megforms.models.BaseAuditModel]]

Translate uk and us models to the base model to fix issue with reverse relation

aggregated_sessions() QuerySet

Groups audit sessions by the following parameters:

  • audit_form_uid: The audit form uid

  • institution_uid: institution uid

  • month: The month in which the submission was created

  • count: The count of submissions for the above parameters

Institution data and extra form data will be included in the output.

Returns:

Annotated queryset.

for_month(month_date: datetime, field_name: str = 'end_time') QuerySet

Given a datetime, returns objects that occurred within that month.

Parameters:
  • month_date – A date in the target month.

  • field_name – The model field to filter the data by.

Returns:

The filtered queryset.

annotate_originator_can_change(auditor: Auditor) Self

Annotate Whether the current user can edit custom observation as originator on originator_can_change

class megforms.models.AuditSession(id, order, publish, uid, created, modified, audit_form, auditor, ward, start_time, end_time, comment, form_view_url, stage)
update_dates()

Keeps the date of Issues assumed to have been created during this session in line with the session’s date.

clean_fields(exclude=None)

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

increment_stage()

Increments current stage by 1 up until form’s max stage

property date: date

date of (end of) the audit localized to the current timezone

property start_date: date

date of (start of) the audit localized to the current timezone

property start_time_cleaned: str

time of the audit localized to the current timezone and formatted for display

property updated_date: date

date of (modified) the audit localized to the current timezone

compliance

Weighted average of published observations in this session

clean()

Hook for doing any extra model-wide validation after clean() has been called on every field by self.clean_fields. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field defined by NON_FIELD_ERRORS.

property duration: timedelta

Time difference between audit start and end

Returns:

datetime.timedelta representing time taken to carry out the audit

property observation_duration: timedelta

Average time taken to carry out one observation

Returns:

datetime.timedelta representing time taken to carry out the audit divided by number of observations

property compliance_percentage: int | None

Compliance as a number in 0-100 range, or None

get_used_subforms() Iterator[Type[BaseSubObservation]]

models of subforms used in this session

exception DoesNotExist
exception MultipleObjectsReturned
class megforms.models.AuditSignature(id, order, publish, uid, created, modified, session, image)
exception DoesNotExist
exception MultipleObjectsReturned
class megforms.models.InstitutionGroupQuerySet(model=None, query=None, using=None, hints=None)
class megforms.models.InstitutionGroup(id, order, publish, uid, created, modified, name, slug, institution_label, logo, color_palette, parent)
get_absolute_url() str

Links to this group’s dashboard. Institution groups don’t have their own dashboard, so this method returns a link to institution dashboard with all institutions from this group selected.

exception DoesNotExist
exception MultipleObjectsReturned
class megforms.models.InstitutionQuerySet(model=None, query=None, using=None, hints=None)
audit_forms() AuditFormQueryset

Audit forms for the institutions includes audit forms directly related to the institutions and indirectly by being group level forms

wards() WardQuerySet

Wards for the institutions

teams() TeamQuerySet

Published Teams for the institutions

order() InstitutionQuerySet

Orders institutions by natural order (group, order, name) with ungrouped institutions first

all_tags(wards: QuerySet | None = None) QuerySet

Set of tags from all institutions, departments, wards and custom fields

Parameters:

wards – narrow down tags by wards (also propagates to department and institution tags)

Returns:

tags for all institutions in this queryset and all its departments/wards/custom fields

for_institution(institution: Institution) Self

Gets the institutions for the given institution. If the institution is part of a group, it will return all group institutions.

for_audit_form(*audit_form: AuditForm, **kwargs) QuerySet

Gets Institutions for given audit forms. If group level forms exist it adds another sub query to find institutions with matching group ids.

for_user(user: User) InstitutionQuerySet

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

with_prefetched_relations() QuerySet

Shorthand method for fetching an institution prefetching it’s nested relationships.

Returns:

Queryset of institutions.

annotate_megdocs_enabled() Self

Annotates the queryset with megdocs_enabled. If it’s disabled at the institution level but enabled at group level, it will still be disabled. The default is false.

class megforms.models.Institution(id, order, publish, uid, created, modified, country, code, name, slug, group, logo, status, trial_expiry, timezone_name, max_auditors, department_label, ward_label, user_display_format, speech_quota, maintenance, language, languages, allow_form_creation, color_palette, email_domain_whitelist, twilio_caller_id, confidential_label)
get_twilio_caller_id

Returns twilio sender id if it exists for model or for group of institutions, otherwise returns default twilio ID

get_language_display() str | None

Gets display name of this institution’s language if set, or null if not set

group_institutions

Returns this institution and other institutions within the same group if it’s a part of a group. Note that returned object can be a tuple of a queryset depending whether this institution belong to a group or not.

get_effective_color_palette_key() str | None

Returns the palette key enforced for this institution. If the group has a non-default palette selected, it overrides the institution setting. Otherwise, when the group palette is MEG Default, the institution’s palette is prioritized, falling back to the global default.

adjacent_institutions

Institutions in the same group, excluding this one and any unpublished instututions

language_set

Set of languages supported by this institution

get_language_choices(include_null=True) list[tuple[str, str]]

Languages available in this institution, including blank choice List of tuples containing language code and its name

property groups: Sequence[InstitutionGroup]

Shim for legacy eGuide logic where institution with multiple groups was allowed. This returns a tuple of one or zero groups this institution belongs to.

can_add_more_auditors() bool

Checks whether more auditors can be added to this institution

terms_dict

Dictionary containing terms used in this institution to refer to wards, departments, institution, their plural forms etc.

property audit_forms: AuditFormQueryset

Queryset of audit forms in this institution includes Group-evel audit forms associated with other institutions in this group

get_local_url(request_path: str) str

Returns local base url for institution based on current module open, if module is not detected or not supported, it will fallback to dashboard reports page

Parameters:

request_path

Returns:

megdocs_config

Get the MegDocsConfig for this institution

exception DoesNotExist
exception MultipleObjectsReturned
class megforms.models.Department(id, order, publish, uid, created, modified, name, institution, slug, managed_by, archive)
exception DoesNotExist
exception MultipleObjectsReturned
class megforms.models.WardQuerySet(model=None, query=None, using=None, hints=None)
names() Sequence[str]

returns just names of the selected wards

annotate_display_name(institution_name=False, **kwargs) BaseQuerySet

Annotate ward queryset with its name and department name. By default, annotation includes ward name and department name: “Ward (Department)”. Optionally, institution name can be added: “Ward (Department, Institution)”

Parameters:

institution_name – whether to include institution name in the annotation besides department name

for_audit_form(*audit_form: AuditForm, **kwargs)

Filter items related to this audit form.

Parameters:
  • audit_form – one or more audit form instances

  • kwargs – any additional kwargs that sub-classes may accept

Returns:

filtered queryset

sort_for_display(include_department_data=True, include_institution_data=False) WardQuerySet

Custom sort of wards use for display to users, not included in base model for performance reasons.

for_form_user(auditor: Auditor, form: AuditForm) WardQuerySet

DEPRECATED use megforms.models.Auditor.get_form_wards() directly

Returns wards available for user in the given form. Takes into account user’s global restrictions and form’s global restrictions.

class megforms.models.Ward(id, order, publish, uid, created, modified, ward_number, name, department, slug, managed_by, archive)
exception DoesNotExist
exception MultipleObjectsReturned
class megforms.models.RoomTypeQuerySet(model=None, query=None, using=None, hints=None)
for_user(user: User) RoomTypeQuerySet

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

class megforms.models.RoomType(id, order, publish, uid, created, modified, name, institution)
exception DoesNotExist
exception MultipleObjectsReturned
class megforms.models.RoomQuerySet(model=None, query=None, using=None, hints=None)
for_audit_form(*audit_form: AuditForm, **kwargs)

Filter items related to this audit form.

Parameters:
  • audit_form – one or more audit form instances

  • kwargs – any additional kwargs that sub-classes may accept

Returns:

filtered queryset

annotate_display_name(include_ward=True, **kwargs) BaseQuerySet

Adds annotated_display_name annotation to the queryset containing str representation of each object. Sub-classes should implement this to build querysets containing full object name with its relations. Model’s __str__() implementation should use this annotation to return a display name without making additional queries to related objects.

Parameters:

kwargs – pass custom arguments depending on implementation

class megforms.models.Room(id, order, publish, uid, created, modified, name, ward, room_type)
exception DoesNotExist
exception MultipleObjectsReturned
class megforms.models.AuditorQueryset(model=None, query=None, using=None, hints=None)
create_issue_handler(username: str, institution: Institution, user_kwargs: dict = None, permissions: Collection[str] = ('qip.change_issue',), forms: Iterable[AuditForm] = (), **kwargs) Auditor

Creates an auditor with issue handler permission

users() QuerySet

Users queryset for auditors selected in this queryset

for_permission(permission: str, *forms: AuditForm) AuditorQueryset

DEPRECATED. Please use megforms.models.AuditorQueryset.with_permission()

with_permission(permission: Permission | str, *forms: AuditForm)

Only auditors who have the specified permission. if form obj is passed, checks permission on form level as well

Returns:

auditors who have change_issue permission globally, OR in ANY of the passed forms

issue_handler(*forms: AuditForm) AuditorQueryset

DEPRECATED: Use megforms.models.AuditorQueryset.issue_handlers()

issue_handlers(*forms: AuditForm) Self

exclude auditors who are not issue handlers in any forms

Parameters:

forms – list of forms to check. If empty, only auditors who have the permission globally will be returned

for_institution(institution: Institution) AuditorQueryset

Filter auditors by institution Returns auditors from given institution, including group-level auditors if institution belongs to a group. Group-level auditors with restricted_institutions that don’t include this institution are excluded.

for_institution__subquery(institution_ref_name: str) AuditorQueryset

Filter auditors in a subquery by institution. :param institution_ref_name: The term that the OuterRef uses to reference a single Institution. :return: auditors from the referenced institution, including group-level auditors if institution belongs to a group

for_department(department: Department) AuditorQueryset
Returns all Auditors who have access to the department via
  • Auditor is explicitly associated with a department Ward

  • Auditor is a member of the Department’s institution and can access all Wards

  • Auditor is a Group Level Auditor for the Department’s Institution’s Group

  • Superusers that are members of the Department’s Institution

Excludes:
  • Global Level Auditors

for_wards(wards: Collection[Ward], has_all: bool = False) AuditorQueryset

Return auditors who have access to selected wards. If the ward list is empty, this will return users who have access to no wards.

Parameters:
  • wards – list of wards

  • has_all – If the auditor needs to have access to all wards or any one of them

Returns:

auditors

for_ward(ward: Ward | int) Self

Filters auditors by access to a specific ward(s)

Parameters:

ward – Ward ID or instance to filter by

Returns:

auditors queryset who have access to the specified ward

for_audit_forms(audit_forms: Iterable[AuditForm], include_global=False) AuditorQueryset

Filters auditors based on audit forms. Returned auditors have access to at least one of the requested forms.

Parameters:
  • audit_forms – list of audit forms to filter by

  • include_global – whether to include global users outside of forms’ institutions such as superusers

Returns:

QuerySet of auditors having access to any of the selected audit forms

for_audit_form(*audit_form: AuditForm, include_global=True, **kwargs) AuditorQueryset

Filters auditors based on audit form

Parameters:
  • audit_form – audit form(s) to filter auditors by

  • include_global – whether to include global users outside of forms’ institutions such as superusers

Returns:

QuerySet of auditors having access to any of the provided forms

for_user(user: User) Self

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

for_auditor(auditor: Auditor) Self

auditors visible for specific auditor only auditors sharing common audit forms will be returned except for global auditors/superusers who can see all auditors. Users without access to any forms are visible to all users within the institution/group.

observation_ringfencing(observation: CustomObservation | CustomSubObservationInstance) Self

Filter auditors to only those capable of accessing a specified Observation. This method returns auditors who can be tagged in comments on an observation. It enforces ward ring-fencing to ensure users can only be tagged if they have actual access to view the observation (task #32863).

The filtering logic includes: 1. Auditors must have the ‘view_customobservation’ permission for the form (required for review page access) 2. Auditors must have access to the observation’s audit form 3. Auditors must be in the observation’s institution via ward (or have group/global access) 4. Auditors must have the observation’s ward in their form-specific permission cache OR be selected in a custom field 5. Auditors must be active users

Parameters:

observation – The observation or sub-observation to check access for

Returns:

QuerySet of auditors who can view and be tagged on this observation

for_issue(issue: Issue) AuditorQueryset

Auditors that are capable of viewing for a specified QIP Issue.

Parameters:

issue – The QIP Issue for which applicable handlers will be listed.

for_issue_assignable_handlers(issue: Issue, auditor: Auditor) AuditorQueryset

Auditors that can be assigned as the handler for a specified QIP Issue.

Parameters:
  • issue – The QIP Issue for which applicable handlers will be listed.

  • auditor – The Auditor that will be assigning the handler to the Issue.

with_email_address()

Only auditors who have an e-mail address

can_be_called()

Only auditors who have a phone number and receive a call

can_be_texted()

Only auditors who have a phone number and receive an SMS

as_recipients() Iterator[str]

yields auditors from this queryset as formatted e-mail recipients containing name and e-mail address, RFC 5322 compliant. Note that e-mail addresses are not guaranteed to be unique

annotate_display_name(**kwargs)

Annotate annotated_display_name using institution’s auditor display format, when this method is applied to a queryset, the __str__ representation of auditor will automatically use the annotated display name For inactive user, prepends REMOVED_PREFIX (Task #31403).

annotate_institution_ids() AuditorQueryset

Adds institution_ids annotation to the queryset containing array of institution ids the user belongs to. The institution ids do not have any specific ordering. The annotated institutions end at group level; for global level auditors, only their group institutions are included.

annotate_form_ids() AuditorQueryset

Annotate allowed form ids on user

Adds annotated_form_ids annotation to the queryset containing a list of form ids the user can access

annotate_ward_ids() AuditorQueryset

Annotate allowed ward ids on user

Adds annotated_ward_ids annotation to the queryset containing a list of ward ids the user can access globally. Excludes any wards the user can access only in some of the forms.

can_view_document(document: Document, include_global=True) AuditorQueryset

Auditors across the institution group that are allowed to view a specified Document. They must satisfy one of the following conditions: - be a superuser. - be a folder permission rule manager. - be the owner of the document. - be the owner of the document’s folder. - be ringfenced to have permission to view the document by folder permission rules.

Parameters:

document – The document.

Returns:

A filtered queryset of auditors.

can_view_document__subquery(include_global: bool = True) AuditorQueryset

Auditors across the institution group that are allowed to view a Document referenced via OuterRef(‘document’) Note: This method is specifically designed for use with querysets where the outer query has a ‘document’ field.

Auditors must satisfy one of the following conditions: - be a superuser. - be a folder permission rule manager. - be the owner of the document. - be the owner of the document’s folder. - be ringfenced to have permission to view the document by folder permission rules.

Returns:

A filtered queryset of auditors.

can_view_document_version(version: Version, include_global=True)

Auditors across the institution group that are allowed to view a specified Document Version. As well as having the permission to view Versions, they must satisfy one of the following conditions: - The permission to view the Document, if this Version is the document’s current version. - Being a contributor, creator, or reviewer of the Version. - Having the Institution-wide version approval permission.

Parameters:

version – The Version.

Returns:

A filtered queryset of auditors.

get_comment_tagging_details() list[dict[str, str]]

Return a list of dictionaries with the attributes of this queryset’s entries required for megforms.comments.user_tagging.

class megforms.models.TeamQuerySet(model=None, query=None, using=None, hints=None)
for_audit_form(*audit_form: Sequence[AuditForm], **kwargs)

Filter items related to this audit form.

Parameters:
  • audit_form – one or more audit form instances

  • kwargs – any additional kwargs that sub-classes may accept

Returns:

filtered queryset

auditors() AuditorQueryset

A qs of auditors belonging to the teams in this queryset

Note that this returns an un-validated queryset. Some of these account may be inactive, or moved to another institution.

for_user(user: User)

Teams containing selected user

get_eguide_ids() set[int]

Queryset of eGuides valid for selected teams

with_team_attestation_percentage(checkbox: DocumentCheckbox, version: Version) Self | AnnotatedTeam

Annotates properties that reflect team percentage calculation and its relevant auditors for a particular document checkbox and version

Parameters:
  • checkbox – The DocumentCheckbox to calculate attestation data for

  • version – The document version to check attestations against

Returns:

Queryset with the following annotations: - checked_count (int) – Count of auditors in this team who have checked the checkbox and can view the document - total_accessible_count (int) – Count of auditors in this team who can view the document - percentage (float) – Percentage of accessible auditors who have checked the checkbox (0-100) - checked_auditors (list[str]) – Array of display names of auditors who have checked the checkbox and can view the document - unchecked_auditors (list[str]) – Array of display names of auditors who can view the document but haven’t checked the checkbox - auditors_without_permission (list[str]) – Array of display names of auditors who cannot view the document

class megforms.models.Team(id, order, publish, uid, created, modified, name, institution, level)
property is_group_level: bool

Is this a group-level team

institutions

Institutions accessible by this team

get_level_display() str

Human readable value of the ‘level’ field.

exception DoesNotExist
exception MultipleObjectsReturned
clean_fields(exclude: Collection[str] | None = None) None

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

get_deferred_fields() set[str]

Return a set containing names of deferred fields for this instance.

refresh_from_db(using: str | None = None, fields: Sequence[str] | None = None) None

Reload field values from the database.

By default, the reloading happens from the database this instance was loaded from, or by the read router if this instance wasn’t loaded from any database. The using parameter will override the default.

Fields can be used to specify which fields to reload. The fields should be an iterable of field attnames. If fields is None, then all non-deferred fields are reloaded.

When accessing deferred fields of an instance, the deferred loading of the field will call this method.

class megforms.models.AuditorFormPermissionsQuerySet(model=None, query=None, using=None, hints=None)
for_audit_form(*audit_form, **kwargs) AuditorFormPermissionsQuerySet

Filter items related to this audit form.

Parameters:
  • audit_form – one or more audit form instances

  • kwargs – any additional kwargs that sub-classes may accept

Returns:

filtered queryset

with_ward_restrictions() AuditorFormPermissionsQuerySet

only objects containing wards

with_permission(permission: Permission | str) AuditorFormPermissionsQuerySet

Filter auditor form relationships by their permissions. Does not include relationships where user has a global permission

class megforms.models.AuditorFormPermissions(*args, **kwargs)

Links auditor model to Form and provides context for a set of permissions. The user retains their global permissions in addition to the permissions listed in this model.

clean_fields(exclude=None)

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

get_all_permissions() set[str]

Complete set of related permissions. Includes direct permissions and group permissions

exception DoesNotExist
exception MultipleObjectsReturned
class megforms.models.Auditor(id, order, publish, uid, created, modified, user, institution, phone_number, receive_voice_alerts, receive_sms_alerts, auditor_id, receive_emails, role, level, patient_data_access, avatar, language, app_access, account_type, timezone_name, title, can_impersonate, display_name, parent)
render_display_name(trim: bool = True) str

Render and return display name using institution’s auditor display format

Parameters:

trim – Trim display name to display_name field length, if False shows full display name

Returns:

get_language() str | None

Gets this user’s language. if no language set, defaults to institution’s language

get_language_display() str | None

Gets display name of this user’s language if set, or null if not set

has_form_perm(form: AuditForm | int | None, *perms: str) bool

Checks whether user has the given permission(s) to the form. If multiple permissions are provided, returns True only if all permissions are met. Empty permission list returns True.

get_forms_custom_observation_filters(*forms: AuditForm) dict[int, dict]

Returns filters for forms based on related class:~megforms.models.AuditorFormPermissions as a map.

Parameters:

forms – multiple Form objs

Returns:

map of form id <-> and filters as a dictionaries

get_custom_observation_filters(form: AuditForm) dict

Returns filters for form entries based on related class:~megforms.models.AuditorFormPermissions.

Parameters:

form – AuditorForm obj

Returns:

filters as a dictionary

get_forms_by_perm(*permissions: str) AuditFormQueryset

Returns forms to which this auditor has the given permission(s)

Parameters:

permissions – a permission or multiple permissions

Returns:

forms for which user has all the lister permissions

has_form_with_perm(*permissions: str) bool

Checks whether user has access to any form with all of the given permissions

is_issue_handler

Tells whether this auditor has issue handler permission (change issue) in any form. Note: user is not considered an issue handler if they have QIP permission to a form with QIP disabled

property email: str

Shortcut to get user’s email

email_recipient

Formats auditor’s e-mail address in a format usable for addressing e-mail Including first/last name or username, RFC 5322 compliant

get_level_int() int

Gets user level as an integer

property institution_group: InstitutionGroup | None

The institution group this user belongs to (if any). If user belongs to an institution without a group, None us returned

property is_group_level: bool

Is this a group-level or higher level auditor

is_global_auditor

Tells whether this auditor is global level and has access to all institutions on the system. Superuser is a superset of global auditor.

property is_demo_user: bool

Whether this is a demo account

property is_folder_permission_rule_manager: bool

Whether this is a folder permission rule manager

num_audits

Number of submissions (audit session) submitted by this user

ringfenced_institutions

Gets the institution(s) the user belongs to. If user is a superuser or global user, it still returns only their immediate institution and adjacent group institutions. If the user isn’t group level or the institution doesn’t have a group, restricted institutions is ignored.

Important

this utility ignores global/superusers

Returns:

a queryset representing institutions the user belongs to.

institutions

Institutions accessible by this auditor returns qs with just one institution for lead and junior auditors, and all institutions in the group for groupauditor and all institutions for superuser or global auditor

institution_groups

Institutions groups accessible by this auditor

allowed_wards

All published wards the user has access to, across all group institutions (if user is group level). Uses form permission cache.

allowed_departments

All published departments the user has access to based on their allowed_wards(). Includes empty departments (without wards) if user is not ringfenced to specific wards. Uses form permission cache.

get_form_wards(form: AuditForm | None) WardQuerySet

Gets wards accessible to user within given form

Parameters:

form – the audit form, or None to get wards the user has global access to

Returns:

queryset representing wards accessible by this user globally, or within given form

property allowed_forms: AuditFormQueryset

Forms allowed for this auditor Returns all published Forms for this institution If this is a junior auditor, filters only forms related to this user (any forms related to this user, bot not institution will be filtered out)

allowed_folders(permissions: list[str] = None) FolderQuerySet

Folders allowed for this auditor. Returns all protected folders for this institution the auditor has access to. Also returns all un protected folders for this institution. If user is rule manager, return all institution folders. Only published folders are returned.

Parameters:

permissions – Filters folder permission rules by list of permissions.

Returns:

Queryset of folders including descendants.

property anonymized_id: str

Returns auditor id if present, or username

first_last_name

First and last name of the Auditor If user has neither, returns null

first_last_name_with_title

First and last name of the Auditor, with the Auditor’s title. If user has no first or last name, returns null

form_names

List of form names associated with this user as per forms m2m field.

property group_permission_labels: Iterable[str]

Labels of all permission groups this auditor belongs to

clean_fields(exclude=None)

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

property global_level_allowed: bool

Determines if the current user can be made global

clean()

Hook for doing any extra model-wide validation after clean() has been called on every field by self.clean_fields. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field defined by NON_FIELD_ERRORS.

save(force_insert=False, force_update=False, using=None, update_fields=None, **kwargs)

Save the current instance. Override this in a subclass if you want to control the saving process.

The ‘force_insert’ and ‘force_update’ parameters can be used to insist that the “save” must be an SQL insert or update (or equivalent for non-SQL backends), respectively. Normally, they should not be set.

get_read_only_editor(form: AuditForm | int | None = None) bool

Determines if the user can edit custom fields that are read only.

locked_field_editor

Determines if the user can edit custom fields that are locked by an answer value.

get_session_ward_ringfencing_q(*forms: AuditForm, readonly=True) Q

Auditor ring-fence visible session by ward for forms.

Parameters:
  • forms – list of forms for the purpose of building the query

  • readonly – whether the resulting query should show only items for read-only access. This can result in showing more items if user has readonly access to more sessions due to ring-fencing settings.

Returns:

A Q object that can be used in a session queryset to filter by wards

get_issues_ward_ringfencing_q(*forms: AuditForm, wards: Iterable[Ward] | None = None) Q

Auditor ring-fence visible issues by ward and auditor if assigned

Parameters:
  • forms – list of forms for the purpose of building the query

  • wards – pass filtered down list or queryset of wards. Defaults to all wards visible to user.

property can_suggest_document_change: bool

Returns whether the auditor can suggest document changes, returns True if user has permission to add document change request, but returns False if user has permission to change documents to prevent admin/manager users from adding suggestions to documents they can already edit

property can_suggest_new_document: bool

Returns whether the auditor can suggest new documents, returns True if user has permission to suggest new document, but returns False if user has permission to create documents to prevent admin/manager users from adding new document suggestions when they can already create documents

property can_view_pending_requests: bool

Returns whether this auditor can view pending requests as a manager or suggestor

can_change_custom_observation_as_originator(observation: CustomObservation) bool

Return whether this observation can be edited by originator

get_preferences(save: bool = True) AuditorPreference | None

Get auditor’s preferences

Parameters:

save – Create auditor’s preferences object if it was not already created

Returns:

exception DoesNotExist
exception MultipleObjectsReturned
class megforms.models.AuditorPreference(*args, **kwargs)

Auditor app and cms preferences

clean()

Hook for doing any extra model-wide validation after clean() has been called on every field by self.clean_fields. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field defined by NON_FIELD_ERRORS.

property observation_review_pinned_sections: list[str]

Getter for observation_review_pinned_sections get from config

property qip_review_pinned_sections: list[str]

Getter for qip_review_pinned_sections get from config

exception DoesNotExist
exception MultipleObjectsReturned
class megforms.models.GroupDescriptionQuerySet(model=None, query=None, using=None, hints=None)
for_institution(institution: Institution)

If an institution has it’s own permission groups, don’t show the global ones.

class megforms.models.GroupDescription(id, order, publish, uid, created, modified, group, label, description, institution, slug)
exception DoesNotExist
exception MultipleObjectsReturned
clean_fields(exclude: Collection[str] | None = None) None

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

get_deferred_fields() set[str]

Return a set containing names of deferred fields for this instance.

refresh_from_db(using: str | None = None, fields: Sequence[str] | None = None) None

Reload field values from the database.

By default, the reloading happens from the database this instance was loaded from, or by the read router if this instance wasn’t loaded from any database. The using parameter will override the default.

Fields can be used to specify which fields to reload. The fields should be an iterable of field attnames. If fields is None, then all non-deferred fields are reloaded.

When accessing deferred fields of an instance, the deferred loading of the field will call this method.

class megforms.models.ModelLinkQueryset(model=None, query=None, using=None, hints=None)
to_model(model: type[django.db.models.base.Model] | Model) ModelLinkQueryset

Only links pointing at objects of specific type

Parameters:

model – model class of instance of a django model

new_instance(from_obj: Model, to_obj: Model, **kwargs) ModelLink

Shortcut to create new instance of a link. Uses object instances to infer Content type

Creates model link

Parameters:
  • from_obj – the object where the relation originates from

  • to_obj – an object to be linked to from_obj

Manual_link:

whether link was created manually (by user), or automatically, for example by matching patient’s MRN across observations in different forms

Returns:

created link instance

Creates model links

Parameters:
  • from_obj – the object where the relation originates from

  • to_obj – one or more objects linked to from_obj

Manual_link:

whether link was created manually (by user), or automatically, for example by matching patient’s MRN across observations in different forms

Returns:

list of created link instances

Finds and returns queryset with links that link from or to objects that no longer exist

exception DoesNotExist
exception MultipleObjectsReturned
class megforms.models.ObservationChange

ObservationChange is a dict object containing the following:

value: string

Current value of the specific custom field. Values can be int, bool, list, float, datetime.date, datetime.time, datetime.datetime, None, Model, ‘ObservationFile’, or None.

by: User

The user who did the action.

on: datetime

The datetime that the action happened.

action:

The specific action that happened. The EntryLog`s `ACTION_FLAG_CHOICES are used for action types. Supported Values: 1 = ADDITION 2 = CHANGE 3 = DELETION

class megforms.models.TrackerLogEntry(id, log_entry, field, old_value, value, extra_action_flag, is_hidden)
exception DoesNotExist
exception MultipleObjectsReturned
class megforms.models.TargetQueryset(model=None, query=None, using=None, hints=None)
for_audit_form(*audit_forms: AuditForm, **kwargs)

Filter items related to this audit form.

Parameters:
  • audit_form – one or more audit form instances

  • kwargs – any additional kwargs that sub-classes may accept

Returns:

filtered queryset

for_institution(institution: Institution)

Returns targets of the selected institution

for_target_type(target_type: Literal['user', 'ward', 'department', 'institution']) Self

Gets the targets for the specified target_type.

Parameters:

target_type – The target type.

class megforms.models.Target(*args, **kwargs)

For tracking time and location based performance targets.

property formatted_target: str

gets string representation of target action and value

exception DoesNotExist
exception MultipleObjectsReturned
class megforms.models.BaseCustomFieldQuerySet(model=None, query=None, using=None, hints=None)
class megforms.models.BaseCustomField(*args, **kwargs)
clean_fields(exclude=None)

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

property model_class: Type[BaseModel] | None

model class if this is a model select or model select multiple field

Returns:

model class, or none if no model selected

property verbose_name

Shim to allow using this model in place of django model Field class

property blank

Shim to allow using this model in place of django model Field class

property name

Shim to allow using this model in place of django model Field class

property is_multichoice: bool

Whether this field allows the user to pick more than one choice.

Returns:

True if this field is one of multichoice fields (select multiple or model select multiple), or a file field that allows multiple uploads.

property is_multivalue_input: str

Tells whether this field can store multiple values. This means that answers to this field serialize into a list.

property has_partial_compliance: bool

Tells whether this field has partial compliance or not

get_validators(form: Form | None = None) list[django.core.validators.BaseValidator]

Gets a list of validators (can be empty) ready to use in form field Uses published_validators field (if present by calling prefetch_validators) on the queryset, or uses a new query

choices_dict

Cached dictionary of choices to avoid N+1 queries during rendering. Built once per field instance.

get_choices(data_model: ObservationOrSubObservation | 'Issue' | None = None, current_auditor: 'Auditor' | None = None, current_form: 'AuditForm' | None = None) Iterator[Choice]

Generates choices as tuples filtered on the current data_model and auditor

Parameters:
  • data_model – Current Custom observation

  • current_auditor – current auditor

  • current_form – form to filter model instances by (model choice fields)

property choices: Iterator[Tuple[str, str]]

Generates choices as tuples. For model fields, generates all published items as choices

choices_qs

Queryset of choices for this model field. If model is not specified, returns an empty

extract_ward_id(data_model: 'CustomObservation' | 'CustomSubObservationInstance' | 'Issue' | None) int | None

Extracts the ward_id from the given data_model, which may be a CustomObservation, CustomSubObservationInstance, or Issue. Safely handles missing attributes and method calls.

Parameters:

data_model – Current Custom observation or issue for context

get_auditor_autocomplete_queryset(data_model: ObservationOrSubObservation | 'Issue' | None, current_auditor: 'Auditor' | None, current_form: 'AuditForm' | None) AuditorQueryset

Get queryset for auditor autocomplete initial values. Returns ONLY selected users (respecting ringfencing) when editing, empty when creating.

get_auditor_autocomplete_widget_forwarding_params(data_model: BaseAuditModel | BaseSubObservation | None, current_form: AuditForm | None) dict[str, Any]

Forward context so the API can reconstruct the Data Model (Observation, SubObs, or Issue).

configure_auditor_autocomplete_widget(widget_class: type, data_model: ObservationOrSubObservation | 'Issue' | None, current_form: 'AuditForm' | None) tuple[type, type, dict]

Configure widget, field class, and kwargs for auditor autocomplete.

get_choices_qs(data_model: ObservationOrSubObservation | 'Issue' | None = None, current_auditor: 'Auditor' | None = None, current_form: 'AuditForm' | None = None) QuerySet

Get choices qs filtered on the current data_model and auditor For auditor model class sort all users by lowercase display_name

Parameters:
  • data_model – Current Custom observation or issue for context

  • current_auditor – current auditor used to filter choices when the field uses Auditor.

  • current_form – current form used to filter choices by form access (QIP fields only). Leave null to not filter choices by form

Returns:

property use_api_choices: bool

Whether custom field should use api choices or not, If True choices from ModelCustomFieldChoicesView should be used

remote_form_choices_qs

Return CustomObservation Queryset for remote for choices

Returns:

CustomObservationQueryset with value, label annotated fields

property is_choice: bool

Whether this field is a choice field.

property is_input: bool

Tells whether this is a regular input field where used can answer a question

property is_heading: bool

Tells whether this is a heading field, only placed to give additional information to user

property is_model: bool

Checks if the custom field widget class is Multiple Select (Model) or Select (Model)

property is_multiple_choice_model: bool

Checks if the custom field widget class is Multiple Select (Model).

property is_ward_select: bool

Determines if the field is a Ward model single select field.

property is_lazy_field: bool

Only use lazy/autocomplete for Auditor model fields for observation fields (CustomField), not issue fields (CustomIssueField)

get_value_display(value: Answer, html=True, observation: ObservationOrSubObservation | None = None, null_placeholder: str = '-', array_delimiter: str = ', ') str

Gets human-readable value for this field. Observation is optional, but required to render clickable file link

Parameters:
  • value – Value to display

  • html – Whether to display as html

  • observation – Observation, necessary to render file url

  • null_placeholder – Placeholder when value is empty

  • array_delimiter – Seperator when the value is an array

Returns:

human-readable str value

class megforms.models.BaseCustomFieldValidatorQuerySet(model=None, query=None, using=None, hints=None)
validate(value)

Validate the value against every validator in this queryset

form_validators(form: Form | None = None) list[django.core.validators.BaseValidator]

Gets a list of validators (can be empty) ready to use in form field

class megforms.models.BaseCustomFieldValidator(*args, **kwargs)
validator

Class of the form validator

property form_validator: BaseValidator

Form validator instance. Can be called to validate values

classmethod from_form_validator(validator: BaseValidator, **kwargs)

Creates instance of the validator model from Django’s validator instance

validate(value)

Validates given value against this validator

clean_value(value)

Takes a value that may not pass validation and changes it so that it does pass validation. Used to generate dummy values

property value_class: type | None

Class of the value argument: int, str or None if no arguments are expected

typed_value

Value for the validator cast to the required type Note: number can be returned as an int if it’s an integer

Returns:

an instance of int, str or None if no argument is expected

clean_fields(exclude=None)

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

class megforms.models.EquipmentQuerySet(model=None, query=None, using=None, hints=None)
by_room() dict[int, list[megforms.models.Equipment]]

Creates dictionary mapping equipments by rooms they’re in

for_audit_form(*audit_form, **kwargs)

Filter items related to this audit form.

Parameters:
  • audit_form – one or more audit form instances

  • kwargs – any additional kwargs that sub-classes may accept

Returns:

filtered queryset

class megforms.models.Equipment(id, order, publish, uid, created, modified, name, slug, image)
property all_rooms: RoomQuerySet

All rooms having this equipment

exception DoesNotExist
exception MultipleObjectsReturned
clean_fields(exclude: Collection[str] | None = None) None

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

get_deferred_fields() set[str]

Return a set containing names of deferred fields for this instance.

refresh_from_db(using: str | None = None, fields: Sequence[str] | None = None) None

Reload field values from the database.

By default, the reloading happens from the database this instance was loaded from, or by the read router if this instance wasn’t loaded from any database. The using parameter will override the default.

Fields can be used to specify which fields to reload. The fields should be an iterable of field attnames. If fields is None, then all non-deferred fields are reloaded.

When accessing deferred fields of an instance, the deferred loading of the field will call this method.

class megforms.models.TaskAudioUsageQueryset(model=None, query=None, using=None, hints=None)
sum_duration() int

Total duration of all selected recordings in seconds

class megforms.models.TaskAudioUsage(*args, **kwargs)

A model used to track the usage of azure audio transcription per institution in celery / automated tasks.

exception DoesNotExist
exception MultipleObjectsReturned
class megforms.models.UserNotificationQuerySet(model=None, query=None, using=None, hints=None)
for_user(user: User) Self

filters notifications by the user

delete_orphaned() tuple[int, dict]

Deletes all notifications where the related object no longer exists.

This is useful because UserNotification uses a GenericForeignKey which doesn’t support CASCADE deletion. When the related object is deleted (e.g., Issue, Document, Version), the notification remains with an invalid object_id.

Uses ORM CASE/WHEN with Exists subqueries to efficiently identify and delete orphaned notifications in a single optimized query.

Returns:

Tuple of (number of deleted objects, dict with deletion details)

class megforms.models.UserNotification(id, order, publish, uid, created, modified, title, subtitle, auditor, type, extra_info, content_type, object_id)
exception DoesNotExist
exception MultipleObjectsReturned
property get_type_display: str

Custom method to get display name using the constants

property action_url: str

Get url of the notification based on object and notification type

static prepare_notification_data(subtitle: str, notification_type: str, auditor_id: int, obj: Issue | Document | Version, content_type: ContentType, extra_info: str | None = '') UserNotification

Static utility method to assist in construction of UserNotification objects that allows for inline creation of title depending on associated object.

Parameters:
  • subtitle – string representation of action message

  • notification_type – string representation of the notification’s type

  • auditor_id – ID of the auditor receiving the notification

  • obj – the related object (Issue, Document, or Version)

  • content_type – associated content type of the object

  • extra_info – optional added info to insert into notification

Returns:

unsaved UserNotification instance

Form Builder

Models used to build custom forms

class audit_builder.models.FieldAccordion(heading, fields)

Create new instance of FieldAccordion(heading, fields)

fields

Alias for field number 1

heading

Alias for field number 0

class audit_builder.models.CustomFieldQuerySet(model=None, query=None, using=None, hints=None)
create_quick(audit_form: AuditForm, label: str, widget: Type[Widget] | str, required=False, subform_label: str | CustomSubform | None = None, validators: Iterable[BaseValidator] | None = None, save=True, **kwargs) CustomField

Shorthand to create field

for_compliance()

returns only fields used or required for compliance calculation

with_compliance_data()

Returns only fields that have compliance logic, not necessarily used for calculating observation compliance

editable()

Fields editable in the Review page

inputs()

Excludes pseudo-fields that server a headings etc instead of data input

calc_fields() CustomFieldQuerySet

excludes fields with empty calc logic

prefetch_validators() CustomFieldQuerySet

Prefetches validators for fields in this queryset while also excluding unpublished validators

choice_fields() CustomFieldQuerySet

All choice fields (dropdowns and radio)

model_choice_fields(model: Model) CustomFieldQuerySet

Only model choice fields for given model

checkbox_filter_fields() CustomFieldQuerySet

Queryset of those custom fields for filtration and having the checkbox input widget

with_set_value_condition() CustomFieldQuerySet

Filters the Custom field QuerySet to include only Custom fields where the conditions JSONB array field contains at least one element (object) with the ‘set_value’ key.

Therefore this filter reduces the qs to fields using default value logic

Returns:

QuerySet: The filtered QuerySet.

with_always_update_condition() CustomFieldQuerySet

Filters the Custom field QuerySet to include only Custom fields where the conditions JSONB array field contains at least one element (object) with the ‘always_update’ key and value True.

Returns:

QuerySet: The filtered QuerySet.

class audit_builder.models.CustomField(*args, **kwargs)

Stores custom field per audit form/observation model

config: FieldConfig

Config Currently used for

  • copying image from a model field (Task #26622) using image_from

  • displaying field the latest change using display_field_latest_change

  • bypassing form validation (Task #31122) using bypass_form_validation

property is_subform_field: bool

Tells whether this field is a subform field.

Returns:

True if this field belongs in a subform, False if its ia Form field

get_value_annotation() Func

Gets observation annotation function that expresses value of this field.

The annotated value will be the relevant JSON type (str, int, float, list, etc), or in case of date/time fields it will be a postgres date/time type.

The expression should be used on observation querysets.

Important

If the field belongs to a subform with many=True, the queryset will contain duplicate observations, one for each subobservation instance. Observations with no answers will also be included, once

property shadows_ward_field: bool

Determins if the field is designed to shadow the hardcoded Ward field. If so, it should not be displayed in the review page or webform. It should only be displayed in app to allow the user to select the hardcoded Ward inside the form.

get_compliant_values() Dict[str, float | None]

Gets possible answers and their corresponding value. Values not present in this dictionary have implicit value of 0.0, except for value store in compliant_value which has implicit compliance of 1.0 unless specified in this field.

get_null_compliant_answer_values

Gets the answer values which are excluded from compliance calculation. :return: A list of answers.

compliant_values

A cached variant of get_compliant_values() method

range_answer_values

Filters and sorts the answer values based on whether the expression is an answer range expression. The output is sorted in ascending order based on the compliance value.

Returns:

A list of tuples. Each tuple contains an expression and Compliance.

has_compliance_data() bool

Whether this field can be used for calculating compliance

compliance_for_observation(observation: BaseAuditModel | BaseSubObservation) float | None

Calculates this field’s compliance for a given observation.

get_ignored_value()

Deserializes ignored value Ignored value must be validated beforehand

conditional_fields() Iterator[CustomField]

Iterator of custom fields depending on this field

get_value_display(value: Answer, html=True, html_as_thumbnail: bool = False, observation: ObservationOrSubObservation | None = None, null_placeholder: str = '-', array_delimiter: str = ', ') str

Gets human-readable value for this field. Observation is optional, but required to render clickable file link

Parameters:
  • value – Value to display

  • html – Whether to display as html

  • html_as_thumbnail – Whether to display image values as string or as thumbnail (required html=True)

  • observation – Observation, necessary to render file url

  • null_placeholder – Placeholder when value is empty

  • array_delimiter – Seperator when the value is an array

Returns:

human-readable str value

formatted_answer(observation: BaseAuditModel) str

Gets answer as a string

generate_observations(observation: BaseAuditModel | BaseSubObservation) Iterable[BaseAuditModel | BaseSubObservation]

Extract this field’s values for observation. Usually there will be only one value, except when subobservation has multiple instances of the subform Reads value from related subobservation or custom sub observation model if required. return iterable observations

generate_values_from_observation(observation: BaseAuditModel) Iterator[str | int | bool | list | float | None]

Extract this field’s values for observation. Usually there will be only one value, except when subobservation has multiple instances of the subform Reads value from related subobservation or custom sub observation model if required. Supports extracting value from related observation.

For form with subforms, this method iterates each sub-observation of the observation, triggering additional SQL queries. Use annotate_subform_answers() to pre-fetch answers and avoid making per-observation queries.

Yields:

raw value from answer dictionaries

get_value_from_observation(observation: BaseAuditModel) str | int | bool | list | float | None

Extract this field’s single value for observation. Reads value from related subobservation or custom sub observation model if required. NOTE: In case of multiple observations, only one (indeterminate) answer is returned

Returns:

raw value from answer dictionary or None

get_values_from_observations(observations: Iterable[CustomObservation], force_qs=False) Iterable[str | int | bool | list | float | None]

Extracts field answers in serialized form from given observations. If field is a subform field, a subobservation query is used internally. Does not filter out missing (null) values

Example:

# get only non-null values
field.get_values_from_observations(observations, force_qs=True).exclude(value=None)
# Get average value
field.get_values_from_observations(observations, force_qs=True).aggregate(
    average=Avg('value'),
)
Parameters:
  • observations – Any iterable of observations. Use a queryset to optimally extract only needed answers

  • force_qs – force result to be a QuerySet. This will allow to further filter and calculate resulting value without selecting them all from database.

Returns:

an iterable object containing answers. Can be either a queryset containing answers, or a generator if observations are provided in a list, and field is a form level Each individual answer is represented as a separate item in the iterator. Multichoice answers are returned as a list. Order of returned elements is not guaranteed

get_answer_from_observation(observation: Observation) Answer

Extract this field’s single answer for observation. Reads value from related subobservation or custom sub observation model if required. NOTE: In case of multiple observations, only one (indeterminate) answer is returned

Returns:

deserialized value from answer observation or None

filter_observations_by_answer(answer: str | int | bool | list | float | None) Q

Creates a Q object that can be used to filter observations by value in this field. Supports subform field by filtering observations by id. The Q object can be joined to filter by multiple fields using AND, OR and NOT queryset logic.

is_visible_for_observation(answers: dict) bool

Check if field should be visible based on conditions

clean_fields(exclude: Collection[str] | None = None) None

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

clean()

Hook for doing any extra model-wide validation after clean() has been called on every field by self.clean_fields. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field defined by NON_FIELD_ERRORS.

property choice_compliances: Iterator[Tuple[str, str, float | None]]

Yields tuples containing choice, display value and compliance of the choice

property full_label: str

Label including subform name (if exists)

property path: str

full, unique path to this question including base model name - subobservation or observation model

required_permissions

permissions required by user to see this field in review page

save(*args, **kwargs)

This forces all file fields to show the change history in the review screen, ref: #27427

get_default_values(observations_qs: CustomObservationQuerySet, data: dict[str, Union[str, int, bool, list, float, NoneType]]) list[Union[str, int, bool, list, float, NoneType]]

Get default value for custom field based on form’s observations

exception DoesNotExist
exception MultipleObjectsReturned
get_deferred_fields() set[str]

Return a set containing names of deferred fields for this instance.

refresh_from_db(using: str | None = None, fields: Sequence[str] | None = None) None

Reload field values from the database.

By default, the reloading happens from the database this instance was loaded from, or by the read router if this instance wasn’t loaded from any database. The using parameter will override the default.

Fields can be used to specify which fields to reload. The fields should be an iterable of field attnames. If fields is None, then all non-deferred fields are reloaded.

When accessing deferred fields of an instance, the deferred loading of the field will call this method.

class audit_builder.models.CustomFieldValidatorQuerySet(model=None, query=None, using=None, hints=None)
class audit_builder.models.CustomFieldValidator(id, order, publish, uid, created, modified, validator_class, value_from_field, value, error_message, field)
exception DoesNotExist
exception MultipleObjectsReturned
class audit_builder.models.CustomObservationQuerySet(model=None, query=None, using=None, hints=None)
annotate_subform_data() Self

Adds subform_data annotation to the queryset, containing a list of json objects where each json object contains answers in each of the sub-observations associated with the observation, in addition to id field containing PK of the sub-observation where those answers are stored, and subform_id holding the PK of the custom subform <~audit_builder.models.CustomSubform> object.

  • un-published sub-observations are excluded.

  • order of sub-observations is not defined (may be random)

the annotated list has a shape similar to the following:

subform_answers = [
    {'id': 1, 'subform_id': 1, 'answers': {
        'mrn': 'MRN123', 'name': 'John Doe'
    }},
    {'id': 2, 'subform_id': 2, 'answers': {
        'date': '2018-7-23', 'procedure': 'Appendectomy'
    }},
    {'id': 3, 'subform_id': 2, 'answers': {
        'date': '2022-7-23', 'procedure': 'Kidney transplant'
    }},
]

Note that the response may contain multiple answers to the same question if the subform has many=True (supports multiple instances per observations). Also note that each of the dictionaries contains answers to each of the fields, even if the subform does not have that field.

get_answers_dataframe(questions: Iterable[CustomField | Field], hardcoded_fields: Iterable[str] = ('id',), subobservation_qs: CustomSubObservationInstanceQuerySet | None = None, compliance_column=False)

Single dataframe containing answers to all fields within observations and sub-observations. questions - a list of hardcoded and custom fields to be extracted Returns single dataframe with all answers, including those in custom sub-observations (hardcoded subforms not currently supported). note that subforms with many=True may have unexpected results as rows will be duplicated for other subforms where a subform can have multiple instances.

create_with_subobservations(audit_form: AuditForm, subform_data: dict | None = None, **kwargs) CustomObservation

Creates observation with custom answers and subforms

Parameters:
  • subform_data – dictionary of subform names mapped to sub-observation custom values

  • kwargs – remaining kwargs to be passed to create(), including custom_answers

Returns:

observation instance

with_field(*fields: CustomField, include_subforms=False) ObservationQueryset

Filter only observations having answer to the given field. Excludes observations where the field has no value or has an empty value. If subform fields are passed, returned QS will contain observations for the relevant sub-observations

order_by_answer(field: CustomField, descending: bool = False) CustomObservationQuerySet

Order observations by custom field. The field can belong to form or subform level. In case of subform, if multiple instances of the sub-observations are present, only the first one is used for ordering.

filter_custom_field_value_q(field_name: str, value: str | int | bool | list | float | None | list[Union[str, int, bool, list, float, NoneType]]) Q

Return filter q for custom field value pair.

With Single value fields it will attempt to filter natively using exact, this behaviour can be changed using filter_suffix argument With Multiple value fields this q is not functional

Parameters:
  • field_name – custom field name to use in query

  • value – value to filter by - observation having this value in the field will be returned. If it’s a list: * observations containing any of the values in the list are returned * If the list is empty, no results are returned

Returns:

filter Q to apply to a CustomObservationQuerySet

filter_by_answer(**kwargs: str | int | bool | list | float | None) CustomObservationQuerySet

filters observation by custom answer.

Parameters:

kwargs – key, value pair where key is the field_name and value is the serialized value to filter by. Field name can be an observation or sub-observation field.

Resulting queryset will contain only observations having answers to all the specified fields with the specified value either in the observation itself or one of its sub-observation.

exclude_by_answer(**kwargs: str | int | bool | list | float | None) CustomObservationQuerySet

excludes observation by custom answer.

Parameters:

kwargs – key, value pair where key is the field_name and value is the serialized value to filter by. Field name can be an observation or subobservation field.

Resulting queryset will contain only observations having answers without any of the specified fields with the specified value either in the observation itself or one of its subobservation.

for_auditor_forms(auditor: Auditor, *forms: AuditForm, readonly: bool = True) CustomObservationQuerySet

Filters CustomObservations for an auditor across one or more forms, applying all ward ringfencing and custom answer filters in a single query.

This method combines the logic for handling single forms, multiple forms, ward-based permissions, and custom field answers into one optimized operation.

  • A global auditor bypasses all filtering.

  • If no auditor is provided, only the base form filter is applied.

  • Custom answer filters are applied on a per-form basis.

  • Ward ringfencing includes:
    1. Ward permissions from AuditorPermissionCache.

    2. Read-only access for forms with advanced ringfencing enabled.

    3. Observations where the auditor or their team is selected in a custom field.

Parameters:
  • auditor – The Auditor to filter observations for.

  • forms – A list of one or more AuditForm objects.

  • readonly – If True, includes observations the auditor has read-only access to via advanced ward ringfencing.

Returns:

A filtered CustomObservationQuerySet.

prefetch_custom_sub_observations(form: AuditForm) CustomObservationQuerySet

Prefetch sub observations under easily accessible named attributes on observations.

Example where subform name is “other”: observation.subform_other_observations.first()

Example when used on a form with “other” and “numbers” subforms with bool and number field each
{% for observation for observations %}
    <div>
    {% if observation.subform_other_observations.0.custom_answers.bool == True or observation.subform_numbers_observations.0.custom_answers.number > 1 %}
        <span>Active</span>
    {% else %}
        <span>Inactive</span>
    {% endif %}
    </div>
{% endfor %}
Parameters:

form – AuditorForm obj

Returns:

CustomObservationQuerySet

Adds a list of related answers to each observation. The annotation for accessing the related answers is related_answers__{ID} where {ID} is the primary key of the related form. If the field isn’t a linkable field, no annotation will be added. For performance reasons, this doesn’t check if the matching field of the annotated observation is linkable.

Parameters:

field – The linked field used to find related observations.

class audit_builder.models.CustomObservation(*args, **kwargs)

Blank observation model used to create new dynamic audits

render_str_repr() str

Renders string representation of this observation based on form config. This is an expensive call as it fetches audit form, config and fields with every call. If you need to use it within the loop, get get_observation_str from audit form instance and call for each observation.

property related_observation_ids: Iterable[int]

Set of primary keys of the CustomObservation instances related to this observation. Both way link relation is included in this set.

Returns:

set of ids

property related_observations: ObservationQueryset

Related observations - observations linked to this observation or linking to this observation Note: This includes all related observations, including:

  • unpublished observations

  • observation whose relation is no longer valid (form relation was removed)

subform_answers

Returns a list of all field answer combinations from sibling sub observations.

subform_answers_dict

Returns a dict of all field (key) answer (value) combinations from sub observations.

In the case of multiple sub observation for one subform, it will use the first sub observations (ordered by ID ascending) custom answers. i.e. there is no merging of values accross sub obs of one subform

last_changed_fields(change_time: datetime | None = None) set[str]

Gets a list of the most recently updated custom fields for this observation, optionally filtered by a specific change time.

exception DoesNotExist
exception MultipleObjectsReturned
class audit_builder.models.CustomSubform(*args, **kwargs)

Defines a sub-observation form for custom audits by grouping audit fields into a named (sub) form

clean_fields(exclude: Collection[str] | None = None) None

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

exception DoesNotExist
exception MultipleObjectsReturned
get_deferred_fields() set[str]

Return a set containing names of deferred fields for this instance.

refresh_from_db(using: str | None = None, fields: Sequence[str] | None = None) None

Reload field values from the database.

By default, the reloading happens from the database this instance was loaded from, or by the read router if this instance wasn’t loaded from any database. The using parameter will override the default.

Fields can be used to specify which fields to reload. The fields should be an iterable of field attnames. If fields is None, then all non-deferred fields are reloaded.

When accessing deferred fields of an instance, the deferred loading of the field will call this method.

class audit_builder.models.CustomSubObservationInstanceQuerySet(model=None, query=None, using=None, hints=None)
get_or_create_for_observation(observation: BaseAuditModel, subform: CustomSubform, save=True) tuple[audit_builder.models.CustomSubObservationInstance, bool]

Creates subobservation instance if required for observation of type subform (custom subform instance). Always creates new subobservation if subform allows it. Otherwise returns existing sub_observation. It will raise Exception in edge case where subform doesnt allow multiple subforms, but multiple subforms exist. An unsaved new sub-observation will be returned if save=False and one does not already exist

Returns:

tuple (sub_observation, created)

with_field(*fields) CustomSubObservationInstanceQuerySet

Filter only observations having answer to the given field. Excludes observations where the field has no value or has an empty value.

for_user(user: User)

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

for_auditor_forms(auditor: Auditor, *forms: AuditForm, readonly: bool = True) CustomSubObservationInstanceQuerySet

Filter CustomSubObservationInstance for this user by custom answer filters

Parameters:
  • forms – list of AuditorForm objs

  • auditor – Auditor

Returns:

CustomSubObservationInstanceQuerySet

order_by_answer(field: CustomField, descending: bool = False) CustomObservationQuerySet

Order subobservations by custom field.

class audit_builder.models.CustomSubObservationInstance(*args, **kwargs)

Groups answers within observation to a specific subform instance Handles case where subform can be submitted multiple times to an observation

get_absolute_url() str

url to the review page of this observation

sibling_subform_answers

Returns a list of all field answer combinations from sibling sub observations.

exception DoesNotExist
exception MultipleObjectsReturned
class audit_builder.models.FormExportPreference(id, order, publish, uid, created, modified, user, form, data, export_type)
exception DoesNotExist
exception MultipleObjectsReturned
class audit_builder.models.CustomFieldGroupQuerySet(model=None, query=None, using=None, hints=None)
for_audit_form(*audit_form, **kwargs)

Filter items related to this audit form.

Parameters:
  • audit_form – one or more audit form instances

  • kwargs – any additional kwargs that sub-classes may accept

Returns:

filtered queryset

class audit_builder.models.CustomFieldGroup(id, order, publish, uid, created, modified, layout_columns, form)
exception DoesNotExist
exception MultipleObjectsReturned
class audit_builder.models.FormRelatedDataQuerySet(model=None, query=None, using=None, hints=None)
class audit_builder.models.FormRelatedData(*args, **kwargs)

Defines which data will be shown to a related form

apply_filtering(observations: CustomObservationQuerySet) CustomObservationQuerySet

Applies order and limit defined in this model

property matching_field_pairs: Iterator[tuple[audit_builder.models.CustomField, audit_builder.models.CustomField]]

yields pair of the matching fields in the source and target audit. Each pair is two custom fields with the same field_name that exists in both forms and defined in matching_fields

clean_fields(exclude=None)

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

exception DoesNotExist
exception MultipleObjectsReturned
class audit_builder.models.FieldUpdateScheduleQuerySet(model=None, query=None, using=None, hints=None)
class audit_builder.models.FieldUpdateSchedule(*args, **kwargs)

Defines fields that should update periodically in all observations

exception DoesNotExist
exception MultipleObjectsReturned

Dashboards

Models used to build custom dashboards

class dashboard_widgets.models.DashboardQuerySet(model=None, query=None, using=None, hints=None)
megdocs()

Dashboards that are restricted to users who have megdocs permissions. These dashboards will be linked to from megdocs.

for_user_perms(user: User) DashboardQuerySet

Filters out dashboards that require permissions the provided users does not have

for_audit_form(*audit_form, **kwargs) DashboardQuerySet

Filter items related to this audit form.

Parameters:
  • audit_form – one or more audit form instances

  • kwargs – any additional kwargs that sub-classes may accept

Returns:

filtered queryset

editable_for_auditor(auditor: Auditor) DashboardQuerySet

Only dashboards that can be edited by given user. Users can access global dashboards, but edit only dashboards linked to their institution or form

for_institutions(institutions: Iterable[Institution]) DashboardQuerySet

Returns dashboards for the selected institutions. If no institutions specified, returns dashboards for all instititutions.

get_dashboards(*, form: AuditForm | None = None, institutions: Iterable[Institution] = (), form_type: FormType | None = None) DashboardQuerySet

Narrows down the queryset for the selected criteria

Parameters:
  • form – when passed, only dashboards for that form will be returned

  • institutions – pass a list of institutions to only return dashboards applicable for all specified institutions. Empty list implies only dashboards with for all institutions

  • form_type – when passed, only dashboards for that form type will be returned

class dashboard_widgets.models.Dashboard(id, order, publish, uid, created, modified, name, description, audit_form, type, dashboard_class, template, global_config_overrides)
last_widget_modified

Last modified datetime of widgets in this dashboard

can_user_edit(auditor: Auditor) bool

tell whether dashboard is user-editable by given user. Only checks institution membership, does not verify user permissions.

create_widgets(**kwargs) Iterable[BaseDashboardWidget]

Instantiates widgets for this dashboard

get_widget_number(widget: WidgetConfig) int

Given custom widget, returns its sequence number in the dashboard. Raises ValueError if not found

clean_fields(exclude: Collection[str] | None = None) None

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

exception DoesNotExist
exception MultipleObjectsReturned
get_deferred_fields() set[str]

Return a set containing names of deferred fields for this instance.

refresh_from_db(using: str | None = None, fields: Sequence[str] | None = None) None

Reload field values from the database.

By default, the reloading happens from the database this instance was loaded from, or by the read router if this instance wasn’t loaded from any database. The using parameter will override the default.

Fields can be used to specify which fields to reload. The fields should be an iterable of field attnames. If fields is None, then all non-deferred fields are reloaded.

When accessing deferred fields of an instance, the deferred loading of the field will call this method.

class dashboard_widgets.models.WidgetConfigQueryset(model=None, query=None, using=None, hints=None)
for_subforms(subforms: Iterable[Subform], include_no_subform=True)

Excludes widgets irrelevant for given set if subuforms using sub_observation configuration field.

NOTE: this method only filters by subform name. This could have unintended consequences when filtering widgets for multiple forms at a time, particularly when subform names are not unique between those forms.

Parameters:
  • subforms – subform instances

  • include_no_subform – whether to include widgets that dont define subform

class dashboard_widgets.models.WidgetConfig(id, order, publish, uid, created, modified, dashboard, title, subtitle, widget, size, config, filters)
property config_schema: SchemaDict | None

if the selected widget supports schema obj, return the schema. returns None if selected widget does not support schema or is not a valid class path.

get_filters(request: HttpRequest | None) dict[str, Union[str, int, bool, list, float, NoneType]]

Gets widget’s filters and populates them with request data

get_field_names(custom_field_queryset_q: ~django.db.models.query_utils.Q | None = <Q: (AND: )>) list[str]

Returns list of valid field names for this widget’s form.

Parameters:

custom_field_queryset_q – Optional Q filter to apply to CustomField queryset

Returns:

List of valid field names (hardcoded observation fields + custom fields)

full_clean(exclude: None | list[str] = None, validate_unique=True)

Call clean_fields(), clean(), validate_unique(), and validate_constraints() on the model. Raise a ValidationError for any errors that occur.

get_widget_display() str

Returns the human-readable display name for the widget.

clean_fields(exclude: Collection[str] | None = None) None

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

exception DoesNotExist
exception MultipleObjectsReturned
get_deferred_fields() set[str]

Return a set containing names of deferred fields for this instance.

refresh_from_db(using: str | None = None, fields: Sequence[str] | None = None) None

Reload field values from the database.

By default, the reloading happens from the database this instance was loaded from, or by the read router if this instance wasn’t loaded from any database. The using parameter will override the default.

Fields can be used to specify which fields to reload. The fields should be an iterable of field attnames. If fields is None, then all non-deferred fields are reloaded.

When accessing deferred fields of an instance, the deferred loading of the field will call this method.

class dashboard_widgets.models.PublicDashboardViewConfig(*args, **kwargs)

A dashboard view available to the public

exception DoesNotExist
exception MultipleObjectsReturned
class dashboard_widgets.models.PublicDashboardWhitelistIPAddress(id, order, publish, uid, created, modified, dashboard, name, ip_address)
exception DoesNotExist
exception MultipleObjectsReturned
class dashboard_widgets.models.FormCounterQueryset(model=None, query=None, using=None, hints=None)
clone(new_form_id: int)

Clones counters in the queryset into a new form. Return list of newly created clones.

class dashboard_widgets.models.FormCounter(*args, **kwargs)

Defines logic to count observations and display them in form of a “badge” next to form. For instance number of observations with status “open”

count(qs: ObservationQuerySet, values: dict[str, Any] | None = None) int

Executes the count on given queryset with given filters and returns number of observations

Parameters:
  • qs – observation queryset

  • values – dictionary containing additional filters applied on top of filters defined in this counter instance. Should contain field names mapped to field values.

Returns:

number of observations from provided queryset having values matching the values dict

exception DoesNotExist
exception MultipleObjectsReturned
class dashboard_widgets.models.BookmarkedFilterQueryset(model=None, query=None, using=None, hints=None)
for_user(user: User) BookmarkedFilter

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

for_audit_form(audit_form: AuditForm, **kwargs) BookmarkedFilter

Filter items related to this audit form.

Parameters:
  • audit_form – one or more audit form instances

  • kwargs – any additional kwargs that sub-classes may accept

Returns:

filtered queryset

class dashboard_widgets.models.BookmarkedFilter(id, order, publish, uid, created, modified, user, audit_form, name, is_default, data, start_date, end_date)
exception DoesNotExist
exception MultipleObjectsReturned

QIP

class qip.models.IssueQueryset(model=None, query=None, using=None, hints=None)
annotate_subform_from_custom_answers(custom_field_name: str, annotated_field_name: str, form: AuditForm) Self

Annotates the queryset with subform names by mapping custom answer IDs to CustomSubform entries. This only supports single choice model. For issues that have a subform ID stored in their custom answers JSON field, this method:

  1. Extracts the subform ID from the specified JSON field

  2. Looks up the corresponding CustomSubform’s display name

  3. Annotates ‘annotated_field_name’ with either: - The found display name from CustomSubform (if ID exists in custom answers) - The existing previously annotated value from anottate_subform_name as fallback

Parameters:
  • custom_field_name – The key in the custom_answers JSON field containing the subform ID

  • annotated_field_name – The field_name in annotate_subform_name method

  • form – Provides subforms for use in the annotation subquery

annotate_subform_name(field_name: str = '_subform_name', default=Value('')) IssueQueryset

Adds _subform_name annotation representing the name of the related subform as a string. (The name ‘_subform_name’ was chosen because ‘subform_name’ is already a property in Issue, but the property will use the annotation if present)

Parameters:
  • field_name – field name to annotate

  • default – The expression to use for issues that dont belong to any subform

get_issue_queryset(q: Q, *querysets: ObservationQuerySet | SubObservationQuerySet) IssueQueryset

Gets issues for observations

Q:

Q objects for additional filtration

Parameters:

args – querysets of observations

Returns:

queryset with issues relating to any of the observations in any of the querysets passed

get_observations_q(queryset: ObservationQuerySet | SubObservationQuerySet) Q

Gets Q object for filtration of issues by observations

Parameters:

args – querysets of observations

Returns:

Q object

for_observation(*observations: Iterable[BaseAuditModel | BaseSubObservation])

Gets queryset of issues for one or multiple observations

Parameters:

observations – observation or sub-observation instances

Returns:

a queryset of issues associated with this observation

for_observations(*args: ObservationQuerySet | SubObservationQuerySet, include_no_observations: bool) IssueQueryset

Gets issues for observations

Parameters:
  • args – querysets of observations

  • include_no_observations – whether to include issues without observations in the result

Returns:

queryset with issues relating to any of the observations in any of the querysets passed

for_observations_and_subobservations(observations: ObservationQuerySet, include_no_observations: bool)

Gets issues for observations

Parameters:
  • observations – queryset of observations

  • include_no_observations – whether to include issues in this queryset that do not belong to any observation

Returns:

queryset with issues relating to any of the observations or its subobservations

for_wards(wards) IssueQueryset

Filter issues related to these wards.

top_level() IssueQueryset

only top level (parent) issues

children() IssueQueryset

only child issues (having a parent)

open()

Excludes closed issues

overdue() IssueQueryset

Issues that are overdue right now.

for_user(user: User, filter_by_wards: bool = True)

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

for_form_auditor(form: AuditForm, auditor: Auditor) IssueQueryset

Filter Issues for this user by related observations custom answer filters

Parameters:
  • form – AuditorForm obj

  • auditor – Auditor

Returns:

Queryset

for_forms_auditor(*forms: AuditForm, auditor: Auditor) IssueQueryset

Filter Issues for this user by related observations custom answer filters

Parameters:
  • forms – list of AuditorForm objs

  • auditor – Auditor

Returns:

Queryset

to_dataframe(fieldnames=(), verbose=True, custom_fields: Iterable[CustomIssueField] | None = None)

Returns a DataFrame from the queryset

Parameters

fieldnames: The model field names(columns) to utilise in creating

the DataFrame. You can span a relationships in the usual Django ORM way by using the foreign key field name separated by double underscores and refer to a field in a related model.

index: specify the field to use for the index. If the index

field is not in fieldnames it will be appended. This is mandatory for timeseries.

verbose: If this is True then populate the DataFrame with the

human readable versions for foreign key fields else use the actual values set in the model

coerce_float: Attempt to convert values to non-string, non-numeric

objects (like decimal.Decimal) to floating point.

datetime_index: specify whether index should be converted to a

DateTimeIndex.

qip()

Only configs having QIP enabled

class qip.models.QipStatusQueryset(model=None, query=None, using=None, hints=None)
for_audit_form(*audit_forms: AuditForm, **kwargs)

Filter items related to this audit form.

Parameters:
  • audit_form – one or more audit form instances

  • kwargs – any additional kwargs that sub-classes may accept

Returns:

filtered queryset

class qip.models.QipStatus(id, order, publish, uid, created, modified, label, color, slug, closed)
exception DoesNotExist
exception MultipleObjectsReturned
clean_fields(exclude: Collection[str] | None = None) None

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

get_deferred_fields() set[str]

Return a set containing names of deferred fields for this instance.

refresh_from_db(using: str | None = None, fields: Sequence[str] | None = None) None

Reload field values from the database.

By default, the reloading happens from the database this instance was loaded from, or by the read router if this instance wasn’t loaded from any database. The using parameter will override the default.

Fields can be used to specify which fields to reload. The fields should be an iterable of field attnames. If fields is None, then all non-deferred fields are reloaded.

When accessing deferred fields of an instance, the deferred loading of the field will call this method.

class qip.models.QipConfigState(*args, **kwargs)

Many-to-Many through model for QIP Config -> QIP States

exception DoesNotExist
exception MultipleObjectsReturned
class qip.models.QipConfigQueryset(model=None, query=None, using=None, hints=None)
class qip.models.QipConfig(*args, **kwargs)

Stores QIP configuration options for a group of form config (AuditFormConfig)

clean_fields(exclude=None)

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

property due_date_duration: timedelta

Due date duration after creation date

institutions

The institutions associated with the current QIPConfig model. If the QIP Config is group level, returns all institutions in the group.

exception DoesNotExist
exception MultipleObjectsReturned
class qip.models.Issue(id, order, publish, uid, created, modified, audit_form, qip_config, parent, content_type, object_id, handler, institution, ward, room, comment, duedate, completed, qipstatus, field_name, risk_level, recommendation, custom_answers, created_by, time)
property subform_name: str

Human-readable name of the subform this issue relates to

Tip

use annotate_subform_name on issue queryset to pre-load subform names

subform

Subform that this issue relates to, or None if issue is associated with the observation instead of sub-observation

observation_url

url of the review page for this issue’s observation. The url will work only for custom observations

observation_id

Id of the related observation. If the issue is related to a subform, follows relation to observation

clean_fields(exclude=None)

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

get_ward() Ward | None

Shorthand method for getting the ward this issue belongs to.

exception DoesNotExist
exception MultipleObjectsReturned
class qip.models.IssueAction(id, order, publish, uid, created, modified, action_taken, action_time, issue, added_by)
exception DoesNotExist
exception MultipleObjectsReturned
class qip.models.IssueFileBaseQueryset(model=None, query=None, using=None, hints=None)
for_user(user: User)

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

class qip.models.IssuePhotoQueryset(model=None, query=None, using=None, hints=None)
class qip.models.IssuePhoto(id, order, publish, uid, created, modified, issue, photo, auditor)
exception DoesNotExist
exception MultipleObjectsReturned
class qip.models.IssueDocumentQueryset(model=None, query=None, using=None, hints=None)
class qip.models.IssueDocument(id, order, publish, uid, created, modified, issue, document, auditor)
exception DoesNotExist
exception MultipleObjectsReturned
class qip.models.IssueAudioQueryset(model=None, query=None, using=None, hints=None)
unrecognized()

Only audio recordings where speech was not recognized

update_duration(only_empty=True) int

Update duration of selected audio recordings Args: only_empty: whether only recording without duration should be updated

sum_duration() int

Total duration of all selected recordings in seconds

quota_usage(period_date=None) int

Number of minutes transcribed in given quota period Args: period_date: date for quota period, leave blank for current date

class qip.models.IssueAudio(id, order, publish, uid, created, modified, issue, audio, duration, text)
recognize_speech(save=True, lazy=False) str

Runs speech recognition on this object and updates it. Note: when running lazy recognition, this object will not be updated, only the database value

Parameters:
  • save – whether to save the object after successful recognition (object will always save when lazy=True)

  • lazy – whether the recognition task be put on async task list

Returns:

recognized text, or result from calling delay() on the task (when lazy)

exception DoesNotExist
exception MultipleObjectsReturned
class qip.models.CommonIssueQuerySet(model=None, query=None, using=None, hints=None)
for_audit_form(audit_form: AuditForm, **kwargs)

Filter items related to this audit form.

Parameters:
  • audit_form – one or more audit form instances

  • kwargs – any additional kwargs that sub-classes may accept

Returns:

filtered queryset

class qip.models.CommonIssueChoice(*args, **kwargs)

Provides drop-down choice values for Issue comment

property subform: 'CustomSubform' | ContentType

returns subform instance depending if this common issue relates to a custom audit (CustomSubObservation) or hardcoed audit (ContentType)

property subform_name: str

Name of the subform or blank (empty string) if this common issue does not specify a subform

clean()

Hook for doing any extra model-wide validation after clean() has been called on every field by self.clean_fields. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field defined by NON_FIELD_ERRORS.

exception DoesNotExist
exception MultipleObjectsReturned
class qip.models.CustomIssueFieldQuerySet(model=None, query=None, using=None, hints=None)
create_quick(audit_form: AuditForm, label: str, widget: Type[Widget] | str, required=False, **kwargs) CustomIssueField

Shorthand to create field

prefetch_validators() CustomIssueFieldQuerySet

Prefetches validators for fields in this queryset while also excluding unpublished validators

qip_form_fields()

Filters for fields that are selected in the qip_fields or qip_child_fields of the form config

subform_custom_issue_fields() Self

Returns issue custom fields that: 1. Have subform as the model 2. Have single choice model as the widget

class qip.models.CustomIssueField(id, order, publish, uid, created, modified, label, help_text, widget, max_length, raw_choices, required, use_for_filtering, field_name, audit_form, qip_config, model, read_only)
get_choices_qs(data_model: BaseAuditModel | BaseSubObservation | Issue | None = None, current_auditor: Auditor | None = None, current_form: AuditForm | None = None) QuerySet

Get choices qs filtered on the current data_model and auditor For auditor model class sort all users by lowercase display_name

Parameters:
  • data_model – Current Custom observation or issue for context

  • current_auditor – current auditor used to filter choices when the field uses Auditor.

  • current_form – current form used to filter choices by form access (QIP fields only). Leave null to not filter choices by form

Returns:

exception DoesNotExist
exception MultipleObjectsReturned
clean_fields(exclude: Collection[str] | None = None) None

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

get_deferred_fields() set[str]

Return a set containing names of deferred fields for this instance.

refresh_from_db(using: str | None = None, fields: Sequence[str] | None = None) None

Reload field values from the database.

By default, the reloading happens from the database this instance was loaded from, or by the read router if this instance wasn’t loaded from any database. The using parameter will override the default.

Fields can be used to specify which fields to reload. The fields should be an iterable of field attnames. If fields is None, then all non-deferred fields are reloaded.

When accessing deferred fields of an instance, the deferred loading of the field will call this method.

class qip.models.CustomIssueFieldValidatorQuerySet(model=None, query=None, using=None, hints=None)
class qip.models.CustomIssueFieldValidator(id, order, publish, uid, created, modified, validator_class, value_from_field, value, error_message, field)
exception DoesNotExist
exception MultipleObjectsReturned

eGuides

class eguides.models.EguideObjectMixin

Mixin for querysets of models that have a fk relation to Eguide.

class eguides.models.EguideQuerySet(model=None, query=None, using=None, hints=None)
for_user(user: User | AnonymousUser) EguideQuerySet

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

class eguides.models.Eguide(id, order, publish, uid, created, modified, name, original_document, introduction, slug, nav_bar_color, nav_bar_icon, app_icon, institution, current_version, access_request_email_address, access_request_email_subject, access_request_email_body, ga_tracking_id, login_required, iconset, home_screen_icon_shape, column_count, home_banner_image, public_app, keywords, display_view, show_view_menu, watermark, mobile_app_section_styles, section_print_enabled)
property sections: SectionQuerySet

Top-level sections in this eGuide

is_push_enabled

Checks whether push messages are configured in this eGuide

exception DoesNotExist
exception MultipleObjectsReturned
class eguides.models.EGuideVersionQuerySet(model=None, query=None, using=None, hints=None)
create_version(eguide: Eguide, make_current=True, **kwargs) EGuideVersion

Creates a new release of eGuide. make_current - makes the new version the current version of the eGuide and saves the eGuide kwargs - EGuideVersion kwargs

class eguides.models.EGuideVersion(id, order, publish, uid, created, modified, version_number, eguide, json_file, changelog, published_by)
exception DoesNotExist
exception MultipleObjectsReturned
class eguides.models.EguideUrlSlugQuerySet(model=None, query=None, using=None, hints=None)
for_user(user: User | AnonymousUser) EguideUrlSlugQuerySet

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

class eguides.models.EguideUrlSlug(id, order, publish, uid, created, modified, display_name, slug, eguide, login_required)
exception DoesNotExist
exception MultipleObjectsReturned
class eguides.models.EguideIpAddress(id, order, publish, uid, created, modified, eguide, name, ip_address)
exception DoesNotExist
exception MultipleObjectsReturned
class eguides.models.SectionIcon(id, order, publish, uid, created, modified, name, iconset, icon)
exception DoesNotExist
exception MultipleObjectsReturned
class eguides.models.SectionQuerySet(model=None, query=None, using=None, hints=None)
for_user(user: User | AnonymousUser) SectionQuerySet

eGuide sections accessible for specified user.

class eguides.models.Section(id, order, publish, uid, created, modified, name, slug, eguide, original_document, text, color, text_color, parent, icon, required_level, require_login)
exception DoesNotExist
exception MultipleObjectsReturned
class eguides.models.InformationQuerySet(model=None, query=None, using=None, hints=None)
for_user(user: User | AnonymousUser) InformationQuerySet

eGuide information objects accessible for specified user.

class eguides.models.Information(id, order, publish, uid, created, modified, name, slug, eguide, text)
exception DoesNotExist
exception MultipleObjectsReturned
class eguides.models.SectionImage(id, order, publish, uid, created, modified, image, eguide)
exception DoesNotExist
exception MultipleObjectsReturned
class eguides.models.Platform(id, order, publish, uid, created, modified, name, slug)
exception DoesNotExist
exception MultipleObjectsReturned
class eguides.models.DisclaimerQuerySet(model=None, query=None, using=None, hints=None)
for_user(user: User | AnonymousUser) DisclaimerQuerySet

eGuide disclaimer objects accessible for specified user.

class eguides.models.Disclaimer(id, order, publish, uid, created, modified, name, slug, text, eguide, platform)
exception DoesNotExist
exception MultipleObjectsReturned
class eguides.models.ValidUserQuerySet(model=None, query=None, using=None, hints=None)
is_admin(user: User, entity: Eguide | Section | Institution | InstitutionGroup) bool

Checks whether selected user is an admin of given entity (eGuide, Section, institution or group)

get_eguides() EguideQuerySet

Queryset of eGuides valid for selected users

get_eguide_ids() set[int]

Queryset of eGuides valid for selected users

eguide_admins() ValidUserQuerySet

validusers who are admins on eGuide level or higher

for_user(user: User) ValidUserQuerySet

valid users accessible for specified user.

class eguides.models.ValidUser(*args, **kwargs)

Defines what access the user has for the selected eGuides

exception DoesNotExist
exception MultipleObjectsReturned
class eguides.models.EguideDocumentQuerySet(model=None, query=None, using=None, hints=None)
for_user(user: User) Self

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

annotate_usage_count() Self

Annotates the number of sections each document is used in.

class eguides.models.EguideDocument(*args, **kwargs)

Allows upload of document which can be linked to from any eGuide

exception DoesNotExist
exception MultipleObjectsReturned
class eguides.models.LegacyEguideImportState(id, order, publish, uid, created, modified, name, institution, import_file, import_completed, state)
exception DoesNotExist
exception MultipleObjectsReturned

MEG Docs

class megdocs.models.MegDocsConfigQuerySet(model=None, query=None, using=None, hints=None)
get_or_default() MegDocsConfig

Gets the first config from the queryset or returns a default config. If an institution level and group level config exists, the institution level config will be returned.

for_institutions(institutions: Iterable[Institution]) Self

Returns MegDocsConfig for given institutions. Includes both institution-level and group-level configs.

for_institution(institution: Institution) Self

Returns MegDocsConfig for a single institution. Includes both institution-level and group-level configs. Institution-level configs are returned first.

class megdocs.models.MegDocsConfig(*args, **kwargs)

Stores configuration options and policies for MegDocs functionality per institution/group. This model replaces individual megdocs_* fields from the Institution model with a flexible JSON configuration field that can store any MegDocs-related settings.

property enabled: bool

Whether MegDocs is enabled for this institution/group (replaces megdocs_enabled)

property use_owner_field: bool

Whether to use owner field functionality

property editor_enabled: bool

Whether built-in document editor is enabled (replaces megdocs_editor)

property email_notifications: bool

Whether email notifications are enabled (replaces megdocs_emails)

property change_requests: bool

Change requests configuration setting (replaces megdocs_change_requests)

property change_requests_enabled: bool

Whether change requests are enabled (replaces megdocs_change_requests_enabled)

property allow_ai_chat: bool

Whether document AI chat is enabled for megdocs

exception DoesNotExist
exception MultipleObjectsReturned
class megdocs.models.DocumentQuerySet(model=None, query=None, using=None, hints=None)
search(value: str, search_in: list[str] | None = None, include_related: bool = False)

Search document by string

Parameters:
  • value – string to search by

  • search_in – fields to search in, options: “title”, “content”, “tags”, “document_code” by default it will search on all

  • include_related – also filter by contents of document’s current version

Returns:

filtered queryset, or self if search does not apply to this model

for_status(status: str) Self

Filter documents by status

Parameters:

status – a choice from megdocs.constants.DOCUMENT_STATUS_CHOICES

Returns:

annotate_display_name(**kwargs) Self

Adds annotated_display_name annotation to the queryset containing str representation of each object. Sub-classes should implement this to build querysets containing full object name with its relations. Model’s __str__() implementation should use this annotation to return a display name without making additional queries to related objects.

Parameters:

kwargs – pass custom arguments depending on implementation

for_folder(folder: Folder)

Returns all documents in the given folder and its descendants

Parameters:

folder – The Folder to get documents from

due_review(exact=True, overdue=False, for_date: date | None = None, days_window: timedelta | None = None)

Documents that are due for review :arg exact whether to only return versions due today. Pass False to also show versions due for review in the past :arg overdue whether to only return documents overdue (past their review date), not including documents due today :arg for_date today’s date :arg days_window when set, returns documents within this many days before the review date

review_range(from_date: date, to_date: date) DocumentQuerySet

Documents that are due for review in given date range

upcoming_due_review(for_date: date | None = None) DocumentQuerySet

Documents with upcoming review dates

Parameters:

for_date – today’s date

review_map() dict[datetime.date, Sequence[megdocs.models.Document]]

Creates a dict mapping dates to documents due for review on that date

declined() DocumentQuerySet

Only documents who’s latest version is declined

pending_review() Self

Only document newer than current version, that are not yet approved

pending_publishing() DocumentQuerySet

Only documents that have a an approved but not yet published version

for_user(user: User, permissions: list[str] | None = None) DocumentQuerySet

Return documents accessible by the user

Parameters:
  • user – User

  • permissions – Filters folder permission rules by list of permissions.

Returns:

Document Queryset

prefetch_latest_versions(to_attr: str = 'latest_versions') Self

Prefetch latest versions into an object attribute, by default it is ‘latest_versions’

Parameters:

to_attr – Attribute to save prefetched versions

annotate_review_date() Self

Adds next_review_date field to the queryset representing the date the document is due for review next.

annotate_has_public_url() Self

Adds has_public_url annotation to the queryset representing whether the document has a public url.

annotate_checkbox_status(auditor: Auditor) Self

Annotates the queryset with properties denote the status of the checkbox for an auditor: has_checkbox and is_acknowledged

Parameters:

auditor – the auditor to filter the checkbox and states for

annotate_can_edit_archived_document_permission_rule(auditor: Auditor) Self

Annotate documents with whether the auditor can edit archived documents based on folder permission rules. For folder permission rule managers, checks global permission since they can edit folder rules. For regular users, uses the folder permission cache for performance.

Parameters:

auditor – The auditor to check permissions for

Returns:

Queryset annotated with ‘can_edit_archived_document’ boolean field

annotate_version_review_status() Self

Annotates review status properties on the queryset: - is_pending_review: Boolean indicating if a version is pending review/publish (has revision > current version)

class megdocs.models.DocumentRelationQuerySet(model=None, query=None, using=None, hints=None)

Queryset for models which have a foreign key relation to Document

for_user(user: User)

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

class megdocs.models.Document(id, order, publish, uid, created, modified, name, description, owner, institution, level, current_version, review_interval, required_approvals, archived, archive_notes, archived_date, archived_by, folder, category, document_code, allow_export)
public_url

Returns the absolute public URL for the document if a published public slug exists

Returns the Document’s public slug if it is published

get_new_revision_number() int

Generates a new unused revision number for this document

property is_due_review: bool

Whether this document is due for a review now

review_date

Returns date when this document is due for review based on the current version date and review frequency

get_manage_url() str

Url to document’s management page where its properties can be modified

get_version_create_url() str

Url to create a new version for the document

get_version_review_url() str

Url to get the version review view for the documents current version

get_draft_edit_content_url() str

Url to get the draft edit content view for the document

property has_current_change_request: bool

Returns true if there is an approved change request for this document. Used to prevent new versions from being while there are checked out change requests

property current_change_request: DocumentChangeRequest | None

Get current change request approved for document

property suggestions_enabled: bool

Returns True if suggestions are allowed to be added for this document from current change request and version states

get_user_change_request(auditor: Auditor) DocumentChangeRequest | None

Get user created change request if exists

property export_url: str | None

Returns export url if valid

all_acknowledgement_auditors

All users who can check this document

archive(by: Auditor) None

Archive this document

Parameters:

by – The auditor who archived the document

restore(by: Auditor) None

Restore this archived document

Parameters:

by – The auditor who archived the document

clean()

Hook for doing any extra model-wide validation after clean() has been called on every field by self.clean_fields. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field defined by NON_FIELD_ERRORS.

exception DoesNotExist
exception MultipleObjectsReturned
class megdocs.models.PublicDocumentSlug(id, order, publish, uid, created, modified, slug, document)
exception DoesNotExist
exception MultipleObjectsReturned
class megdocs.models.DocumentDraftQueryset(model=None, query=None, using=None, hints=None)
for_user(user: User) Self

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

class megdocs.models.DocumentDraft(*args, **kwargs)

Live / editable version of the document. Contains latest changes that will later become a new Version of the document. Draft stores document contents in HTML format

exception DoesNotExist
exception MultipleObjectsReturned
class megdocs.models.DocumentTemplateQuerySet(model=None, query=None, using=None, hints=None)
for_user(user: User) Self

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

class megdocs.models.DocumentTemplate(*args, **kwargs)

Represents a template that can be used to create a new DocumentDraft

exception DoesNotExist
exception MultipleObjectsReturned
class megdocs.models.VersionQuerySet(model=None, query=None, using=None, hints=None)
search(value: str, search_in: list[str] | None = None, include_related: bool = False) Self

Search document version by string

Parameters:
  • value – string to search by

  • search_in – fields to search in, options: “title”, “content”, “tags”, “document_code” by default it will search on all

  • include_related – whether to also include search results based on document fields

Returns:

filtered queryset

for_status(status: str) Self

Filter versions by status

Parameters:

status – a choice from megdocs.constants.DOCUMENT_STATUS_CHOICES

Returns:

get_new_revision_number() int

Generates a new unused revision number by querying for the highest revision number among published versions and incrementing it. This also allows deleted version numbers to be recycled.

annotate_previous_revision()

Annotates each object in the queryset with the revision number of the document’s previous version

pending_review() VersionQuerySet

Only documents that have newer version in review (not yet approved)

pending_publishing() VersionQuerySet

Only document newer than current version, that are not yet published

declined() DocumentQuerySet

Only versions that are declined

scheduled_publish_date() Self

Annotates the queryset with a boolean variable is_scheduled to denote the existense of a periodic task that will publish this version Also with the publish_date from that periodic task

for_user(user: User, force_ringfencing: bool = False) VersionQuerySet

Return versions accessible by user

Parameters:
  • user – User

  • force_ringfencing – whether to force ringfencing even if user has megdocs.approve_institution_versions permission

Returns:

pending_approval_of(user: User) Iterable[Version]

Return versions that are pending approval of the provided user

Parameters:

user

Returns:

annotate_approval_config_id() VersionQuerySet

Annotates annotated_approval_config_id on queryset

Returns:

annotate_approval_config_auditors() VersionQuerySet

Annotates approval_config_auditors on queryset :return: annotated qs with approval_config_auditors field of type List[str] representing a list of auditor slugs/usernames

annotate_review_date() Self

Adds next_review_date field to the queryset representing the date the document is due for review next.

waiting_for_user_approval(user: User) VersionQuerySet

Get a queryset of those versions that the user can see in the My Review tab.

without_approval_config() Self

returns only those version that are not part of a publication rule

for_approval_config(approval_config: ApprovalConfig) Self

Filters version by an approval config based on the rule type

Parameters:

approval_config – the approval config object to filter for

documents() VersionQuerySet

Get document queryset related to this versions queryset

class megdocs.models.Version(id, order, publish, uid, created, modified, creation_date, version_name, document, revision, creator, reviewer, file, source, approved, content, summary, resets_checkbox, review_date_extension, published_by, published_on, is_auto_published)
property version: str

Property holding the proper version. It returns the version name if set otherwise it returns revision

clean_fields(exclude=None)

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

is_creator_or_reviewer(auditor: Auditor) bool

Whether the given auditor is the creator of this version, or its reviewer

populate_content(save=True, **kwargs)

Read file contents into content field. Replace null (0x00) characters which are not accepted by db. Encode to utf-8 to handle ascii characters and convert back to string.

property review_date: date | None

Returns date when this document version is due for review based on the current version date and review frequency

can_show_diff

Whether diff fo this version can be shown (version has content)

property published: bool

Tells whether this is the current published version of the document

property is_excel_source: bool

Whether the optional source file is an Excel document.

Returns:

True if the version has a source file and its extension is xlsx; otherwise False.

exception DoesNotExist
exception MultipleObjectsReturned
class megdocs.models.FolderQuerySet(model=None, query=None, using=None, hints=None)
class megdocs.models.Folder(id, order, publish, uid, created, modified, name, description, owner, parent, institution, institution_level)
clean()

Hook for doing any extra model-wide validation after clean() has been called on every field by self.clean_fields. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field defined by NON_FIELD_ERRORS.

after_update()

Trigger celery task to update folder permission rules for specified users, this method fetches old and newly referenced users and updates folder permission for all of them

exception DoesNotExist
exception MultipleObjectsReturned
class megdocs.models.Bookmark(id, order, publish, uid, created, modified, user, document)
exception DoesNotExist
exception MultipleObjectsReturned
class megdocs.models.FolderPermissionRuleQueryset(model=None, query=None, using=None, hints=None)
folders(user: User = None, folder: Folder = None)

Returns all folders related to the rule. If rule folders are None, returns all folders within the institution.

for_document(document: Document) Self

Rules for a given document. Returns all rules applied to all parent folders of the document. If the document doesn’t have a folder, then an empty queryset is returned.

Parameters:

document – The document.

Returns:

A queryset of folder permission rules.

for_folder(folder: Folder) Self

Rules for a given folder: inherited from parent folder

class megdocs.models.FolderPermissionRule(id, order, publish, uid, created, modified, name, owner, institution)
after_update()

Trigger celery task to update folder permission rules for specified users, this method fetches old and newly referenced users and updates folder permission for all of them

exception DoesNotExist
exception MultipleObjectsReturned
class megdocs.models.FolderPermissionCacheQuerySet(model=None, query=None, using=None, hints=None)
published()

Excludes unpublished items

global_perms() FolderPermissionCacheQuerySet

Only global permissions, without a specific folder

get_documents(institutions: Iterable[Institution]) DocumentQuerySet

Gets documents included in the folders in this queryset

Parameters:

institutions – institutions to filter the documents by. Necessary to ring-fence documents not belonging to any folder

Returns:

documents in the folders in this cache queryset, including documents not belonging to any folder (if cache entry without folder is included in the QS)

for_perms(permissions: list[str] | None = None) Self

Filter by cache by permissions, if no permissions were passed, all records withing queryset will be returned if multiple permissions were passed queryset will fetch records with any permission that was specified

for_user(user: User, permissions: list[str] | None = None) FolderPermissionCacheQuerySet

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

for_folder(folder: Folder | None, permissions: list[str] | None = None) FolderPermissionCacheQuerySet

Return all auditors with permission to access folder

annotate_codenames()

Annotates all permission codenames as an array field called codenames on queryset

class megdocs.models.FolderPermissionCache(*args, **kwargs)

This model is auto-populated and not meant for manual editing.

exception DoesNotExist
exception MultipleObjectsReturned
exception DoesNotExist
exception MultipleObjectsReturned
class megdocs.models.VersionApprovalQuerySet(model=None, query=None, using=None, hints=None)
class megdocs.models.VersionApproval(id, order, publish, uid, created, modified, version, reviewer, status, reason, step)
exception DoesNotExist
exception MultipleObjectsReturned
class megdocs.models.DocumentCheckboxQuerySet(model=None, query=None, using=None, hints=None)

Provides query set functionalities for DocumentCheckbox model

for_auditor_review(auditor: Auditor) Self

Any outstanding attestation that have not yet been approved relevant to the given auditor

with_user_percentage(version: Version | None = None)

Annotates each DocumentCheckbox with the percentage of relevant auditors who can view the document and have checked the attestation.

Parameters:

version – Optional, A document version to check attestations against.

Returns:

Queryset with the following annotations: - relevant_accessible_auditors_count (int) – Count of relevant auditors who can view the document - checked_auditors_count (int) – Count of relevant auditors who have checked the checkbox and can view the document - user_percentage (float) – Percentage of accessible relevant auditors who have checked the checkbox (0-100) - checked_auditors (list[str]) – Array of display names of relevant auditors who have checked the checkbox and can view the document - unchecked_auditors (list[str]) – Array of display names of relevant auditors who can view the document but haven’t checked the checkbox - auditors_without_permission (list[str]) – Array of display names of relevant auditors who cannot view the document

with_checked_percentage(version: Version | None = None)

Annotates each DocumentCheckbox with the percentage of relevant users who can view the document and have checked the attestation.

Parameters:

version – Optional, A document version to check attestations against.

Returns:

Queryset with checked_percentage annotation (0-1 decimal)

class megdocs.models.DocumentCheckbox(*args, **kwargs)

Defines per-user checkbox to be displayed on document page to record understanding / having read the document As per Task #25521

all_acknowledgement_auditors

All users who can check this attestation

unchecked_users

Users who can view the current version of the document but haven’t ticked the attestation. If relevant teams are specified, filter users to those teams.

exception DoesNotExist
exception MultipleObjectsReturned
class megdocs.models.DocumentCheckboxStateQuerySet(model=None, query=None, using=None, hints=None)

Provides query utility for document checkbox states.

for_user_permissions(document: Document) Self

Filters checkbox states by users who have permission to view the document

for_relevant_users() Self

Filters checkbox states for users who are either in the checkbox’s relevant_auditors or are members of the checkbox’s relevant_teams

with_attestation_version() Self

Annotate with details of the Version at which the User manually clicked the checkbox. For each State, find the oldest State with a matching Document, Checkbox, User, and attestation_date. When a new Version of a Document is published, and checkboxes are not reset, the attestation_date is copied from the old Version’s DocumentCheckboxState to the new Version’s newly created DocumentCheckboxState. Therefore the oldest State in the database for the matching Document, Checkbox, User, and attestation_date is most likely to be the DocumentCheckboxState that originally set that attestation_date. Thus, that DocumentCheckboxState is most likely to be the one where the User manually clicked the checkbox.

Annotates with attestation_version_string, the User-facing string for the Version. For the purpose of accurately building this string per the logic in the Version model, this annotation also adds: - attestation_version_name, the version_name property of the Version, - and document_code, the document_code property of the related Document.

with_user_states() Self

Annotates properties on the queryset to denote whether or not a checkbox state is from an relevant auditor or relevant team auditor and if so the team name

Returns:

Queryset with the following annotations: - is_individual (bool) – Boolean indicating if the checkbox is from a relevant individual auditor - is_team (bool) – Boolean indicating if the checkbox is from a relevant team auditor - team_name (str) – String containing the name of the relevant team (if applicable)

class megdocs.models.DocumentCheckboxState(*args, **kwargs)

Marks that user has checked the DocumentCheckbox for a given document version

clean_fields(exclude=None)

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

copy_to(version: Version) DocumentCheckboxState

clears pk and updates version in this object and returns it. Note that the instance is mutated rather than a new one being returned.

exception DoesNotExist
exception MultipleObjectsReturned
class megdocs.models.DocumentCategoryQuerySet(model=None, query=None, using=None, hints=None)
for_institution(institution)

Returns audit forms of the selected institutions

class megdocs.models.DocumentCategory(id, order, publish, uid, created, modified, name, institution, level)
exception DoesNotExist
exception MultipleObjectsReturned
class megdocs.models.DocumentChangeRequestQuerySet(model=None, query=None, using=None, hints=None)
search(value: str, search_in: list[str] | None = None, include_related: bool = False) Self

Search document-related model by string

Parameters:
  • value – string to search by

  • search_in – fields to search in, options: “title”, “content”, “tags”, “document_code” by default it will search on all

  • include_related – whether to also search related objects (e.g. document search will include versions containing search query, and vice versa). This is used to implement OR joined for search results. IF true, the implementation should call into related models’ search() function with include_related=False to avoid circular calls.

Returns:

filtered queryset containing the search string

for_status(status: str) Self

Filter document change requests by status

Parameters:

status – a choice from megdocs.constants.DOCUMENT_STATUS_CHOICES

Returns:

for_user(user: User)

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

class megdocs.models.DocumentChangeRequest(id, order, publish, uid, created, modified, institution, document, description, reason, auditor, status, owner, version, type)
property is_new: bool

Whether this Request is for New Documents

property is_edit: bool

Whether this Request is for Document Updates

property is_archive: bool

Whether this Request is for Document Archival

can_approve_or_decline(auditor: Auditor) bool

If user can approve or reject this change request, the users that can approve or decline are as follows:

New request: Owner Edit Request: Document owner or document controller

can_submit(auditor: Auditor) bool

If the user can submit new version via this change request

archive(by: Auditor)

Archive current document change

exception DoesNotExist
exception MultipleObjectsReturned
class megdocs.models.DocumentUploadMetadataQuerySet(model=None, query=None, using=None, hints=None)
for_user(user: User)

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

class megdocs.models.DocumentUploadMetadata(id, order, publish, uid, created, modified, data, institution)
exception DoesNotExist
exception MultipleObjectsReturned
class megdocs.models.AIChatQuerySet(model=None, query=None, using=None, hints=None)
for_matching_opening_question(search_term: str) AIChatQuerySet

Finds chats whos opening message matches the search_term. So it finds if this question was previously asked by the auditor on this document.

It uses a subquery to annotate each chat with the content of its “opening question” (defined as the first chronological message from an ‘auditor’ sender) and then filters the chats based on that annotated content.

Parameters:
  • search_term – The exact text to match against the opening question’s content (case-insensitive).

  • version – The document Version which the question is for.

  • auditor – The user asking the question.

  • institution – The institution where the question was asked.

Returns:

A QuerySet of AIChat instances where this question was previously asked by the auditor for this document.

class megdocs.models.AIChat(*args, **kwargs)

Represents an AI document chat session

property opening_question: AIChatMessage | None

Returns the first message sent by the auditor, which is the opening question. Returns None if no such message exists.

exception DoesNotExist
exception MultipleObjectsReturned
class megdocs.models.AIChatMessage(*args, **kwargs)

Represents a single message within a chat.

exception DoesNotExist
exception MultipleObjectsReturned

Accounts

class accounts.models.PasswordPolicyQuerySet(model=None, query=None, using=None, hints=None)
for_institution(institution: Institution | None) PasswordPolicyQuerySet

Policies applicable to given institution Policies are restricted by the institution or the institutions group, if it has one.

If no institution provided returns an empty qs

for_user(user: User) PasswordPolicyQuerySet

Policies applicable to given user Policies can be restricted to specific users with patient data access, or by user permission groups, or a combination of both.

get_or_default() PasswordPolicy

Gets the first password policy from the queryset or returns default policy

with_ip_addresses() Self

Prefetches the ip addresses to the queryset.

class accounts.models.PasswordPolicy(*args, **kwargs)

Per-institution password requirements. an institution can have multiple policies and all of published policies will be enforced, but the practical application is to have one policy and mayve few unpublished “draft” policies. This opens the possibility for having more tailored policies in the future, like per-group or per-team.

clean()

Hook for doing any extra model-wide validation after clean() has been called on every field by self.clean_fields. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field defined by NON_FIELD_ERRORS.

exception DoesNotExist
exception MultipleObjectsReturned
class accounts.models.PasswordLogEntryQuerySet(model=None, query=None, using=None, hints=None)
class accounts.models.PasswordLogEntry(id, order, publish, uid, created, modified, user, password)
exception DoesNotExist
exception MultipleObjectsReturned
class accounts.models.PasswordPolicyIpAddress(id, order, publish, uid, created, modified, policy, name, ip_address)
exception DoesNotExist
exception MultipleObjectsReturned
accounts.models.build_default_favorite_fields() dict[str, list]

Createst a preset dictionary for user’s convenience that includes all models and maps them to empty list that can be populated by user.

accounts.models.validate_model_fieldnames(val: dict[str, list[str]])

Validates favourite field mapping structure that it maps valid model names to valid set of fields within.

class accounts.models.AdminPreference(*args, **kwargs)

Django admin preferences

exception DoesNotExist
exception MultipleObjectsReturned
class accounts.models.AuditorPermissionCacheQuerySet(model=None, query=None, using=None, hints=None)
published()

Excludes unpublished items

for_audit_form(*audit_form, **kwargs)

Filter items related to this audit form.

Parameters:
  • audit_form – one or more audit form instances

  • kwargs – any additional kwargs that sub-classes may accept

Returns:

filtered queryset

global_perms() AuditorPermissionCacheQuerySet

Only global permissions, without a specific audit form

for_user(user: User) Self

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

with_permissions(*perms: str) AuditorPermissionCacheQuerySet

only objects containing all of the provided permissions

institution_ids() QuerySet

Distinct set of institution ids in this queryset

auditor_ids() QuerySet

IDs of Auditor objects referenced by objects in this queryset

class accounts.models.AuditorPermissionCache(*args, **kwargs)

Stores user’s per-form permissions compiled from user’s global permissions (and group memberships), and per-form permissions set in AuditorFormPermissions.

This model is auto-populated and not meant for manual editing.

exception DoesNotExist
exception MultipleObjectsReturned
class accounts.models.AuditorSignatureQueryset(model=None, query=None, using=None, hints=None)
for_user(user: User)

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

class accounts.models.AuditorSignature(id, order, publish, uid, created, modified, auditor, image)
exception DoesNotExist
exception MultipleObjectsReturned
class accounts.models.LoginLogEntryQueryset(model=None, query=None, using=None, hints=None)
class accounts.models.LoginLogEntry(id, order, publish, uid, created, modified, user, ip, username, login_successful)
exception DoesNotExist
exception MultipleObjectsReturned

Calendar

class megforms.calendar.models.BaseScheduleQueryset(model=None, query=None, using=None, hints=None)

Queryset for BaseSchedule model

for_dates(start: date, end: date) dict[datetime.date, megforms.calendar.models.BaseSchedule]

gets dict mapping every date between start and end (inclusive) to a list of schedules falling on that day

for_date(date: date)

generates schedule objects happening on selected date

upcoming_event() date | None

Returns the upcoming event of schedules in the queryset among all those schedules

class megforms.calendar.models.BaseSchedule(*args, **kwargs)
property calendar_title: str
Returns:

a short string that provides title for a calendar event

property frequency: timedelta | relativedelta

Return the repeat of the schedule as a timedelta. However, if the repeat is monthly, return a relativedelta with 1 month to guarantee that event repeats on same day every month. Relativedelta is only used here for monthly repeats when the day of month is less than 29 as the scope covers only days 1-28 (ref #27105)

property once_off: bool

whether this is a once-off schedule

property repeatable: bool

Whether this schedule repeats

instances(start: date | None = None, end: date | None = None) Iterator[date]

Iterates dates in which this calendar event occurs

clean()

Hook for doing any extra model-wide validation after clean() has been called on every field by self.clean_fields. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field defined by NON_FIELD_ERRORS.

property start_date_passed: bool

Whether the schedule starts today or in the past. Returns False only if event is scheduled to start in the future from now.

property last_event: date | None

Last passed date for this event. None only if event does not repeat and has not yet passed.

property next_event: date | None

Date of the next instance of this schedule based on current date.

class megforms.calendar.models.AuditScheduleQueryset(model=None, query=None, using=None, hints=None)
unfulfilled(date: date) AuditScheduleQueryset

excludes schedules that have been completed for given date

for_user(user: User)

filter objects by user. Implementing classes should filter down the queryset and only return objects accessible to the user. The default is to return no objects.

class megforms.calendar.models.AuditSchedule(id, order, publish, uid, created, modified, end_date, repeat, send_reminder, note, audit_form, ward, start_date)
property calendar_title: str
Returns:

a short string that provides title for audit schedule calendar event

timezone

Timezone of this schedule. Depends on institution.

clean()

Hook for doing any extra model-wide validation after clean() has been called on every field by self.clean_fields. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field defined by NON_FIELD_ERRORS.

exception DoesNotExist
exception MultipleObjectsReturned
class megforms.calendar.models.AuditScheduleReminderQuerySet(model=None, query=None, using=None, hints=None)
active() AuditScheduleReminderQuerySet

Filters out inactive reminders. An active reminder is one that belongs to a schedule that did not opt out from sending reminders.

in_date() AuditScheduleReminderQuerySet

Filters out reminders that belong to a schedule that has ended

sync_celery_jobs()

Update Celery schedules with the updated frequency/time settings. Creates new schedules if needed and handles unpublishing of schedules.

class megforms.calendar.models.AuditScheduleReminder(id, order, publish, uid, created, modified, schedule, reminder_timedelta, time)
get_reminder_datetime(for_date: date, tz: tzinfo) datetime

Given a date and timezone, returns datetime when the reminder should be triggered

get_next_reminder_datetime() datetime | None

Next instance of the reminder given current date/time

celery_task_name

Unique name for celery task

property periodic_task: PeriodicTask | None

Periodic task triggering this reminder. None will be returned if: * The reminder/schedule is no longer active * there are no future instances of this schedule * reminder was created but task was not scheduled for some reason (i.e. reminder was bulk-created and thus did not trigger signal)

update_celery_schedule() PeriodicTask | None

Schedules repeating celery job for this reminder

full_clean(exclude=None, validate_unique=True)

Call clean_fields(), clean(), validate_unique(), and validate_constraints() on the model. Raise a ValidationError for any errors that occur.

exception DoesNotExist
exception MultipleObjectsReturned
class megforms.calendar.models.TimelineEvent(*args, **kwargs)

Represents events to be plotted on chart widgets

exception DoesNotExist
exception MultipleObjectsReturned
class megforms.calendar.models.ReviewScheduleQueryset(model=None, query=None, using=None, hints=None)

Queryset for ReviewSchedule model

for_audit_form(*audit_forms, **kwargs)

Filter items related to this audit form.

Parameters:
  • audit_form – one or more audit form instances

  • kwargs – any additional kwargs that sub-classes may accept

Returns:

filtered queryset

class megforms.calendar.models.ReviewSchedule(id, order, publish, uid, created, modified, start_date, end_date, repeat, send_reminder, note, observation)
exception DoesNotExist
exception MultipleObjectsReturned
class megforms.calendar.models.GenericSchedule(*args, **kwargs)

General purpose scheduling model. Relate to this model to schedule specific tasks.

exception DoesNotExist
exception MultipleObjectsReturned

HL7 Integration

class hl7_integration.models.HL7ConfigQuerySet(model=None, query=None, using=None, hints=None)
for_audit_form(*audit_form, **kwargs)

Filter items related to this audit form.

Parameters:
  • audit_form – one or more audit form instances

  • kwargs – any additional kwargs that sub-classes may accept

Returns:

filtered queryset

class hl7_integration.models.HL7Config(id, order, publish, uid, created, modified, name, form, auditor, ward, comment, auth_token, config, accepted_message_types, message_type_hl7_accessor, entrypoint)
clean()

Hook for doing any extra model-wide validation after clean() has been called on every field by self.clean_fields. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field defined by NON_FIELD_ERRORS.

clean_fields(exclude=None)

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

exception DoesNotExist
exception MultipleObjectsReturned
class hl7_integration.models.HL7FieldMappingQuerySet(model=None, query=None, using=None, hints=None)
class hl7_integration.models.HL7FieldMapping(id, order, publish, uid, created, modified, config, form_field, hl7_accessor, unique)
clean_fields(exclude=None)

Clean all fields and raise a ValidationError containing a dict of all validation errors if any occur.

exception DoesNotExist
exception MultipleObjectsReturned
class hl7_integration.models.HL7EntryPoint(id, order, publish, uid, created, modified, name, slug, institution, auth_token, message_type_hl7_accessor)
exception DoesNotExist
exception MultipleObjectsReturned