Package: edc-form-runners
edc-form-runnersClasses to manually run modelform validation for clinicedc/edc projects.TheFormRunnerclassYou can use theFormRunnerto rerun modelform validation on all instances of a model.For example:runner=FormRunner("intecomm_subject.vitals")runner.run_all()This re-runsform.is_valid()for all instances ofintecomm_subject.vitals.
If the VitalsModelFormdoes not validate, theFormRunnerstores each error
of theform.errorsdictionary in modelIssuewhere
one instance ofIssueis created per field_name:error_message pair.Note: Your model must be registered with Admin.run_form_runnersYou can run aFormRunnerfor every CRF/Requisition model in a module:fromdjango.appsimportappsasdjango_appsfromedc_form_runners.run_form_runnersimportrun_form_runnersrun_form_runners(app_labels=["intecomm_subject"])or just list a few models explicitly:fromdjango.appsimportappsasdjango_appsfromedc_form_runners.run_form_runnersimportrun_form_runnersrun_form_runners(model_names=["intecomm_subject.vitals","intecomm_subject.medications"])Custom FormRunnersYou may wish to ignore some errors; that is, preventFormRunnerfrom creating anIssueinstance
for specific fields that do not validate. To do this create a customFormRunnerfor your model
and list the field names to exclude:classHtnMedicationAdherenceFormRunner(FormRunner):model_name="intecomm_subject.htnmedicationadherence"exclude_formfields=["pill_count"]Now you can use the customFormRunner:runner=HtnMedicationAdherenceFormRunner()runner.run_all()if fieldpill_countdoes not validate, the error message will not be written to theIssuestable.Registering Custom FormRunnersA customFormRunnermust be registered to be used byedc_form_runners.Declare your customFormRunnnersin moduleform_runners.pyin the root of your app:# form_runners.pyfromedc_form_runners.decoratorsimportregisterfromedc_form_runners.form_runnerimportFormRunner@registerclassHtnMedicationAdherenceFormRunner(FormRunner):model_name="intecomm_subject.htnmedicationadherence"exclude_formfields=["pill_count"]@registerclassDmMedicationAdherenceFormRunner(FormRunner):model_name="intecomm_subject.dmmedicationadherence"exclude_formfields=["pill_count"]Theregisterdecorator registers the custom classes withsite_form_runners.get_form_runneredc_form_runnersgetsFormRunnersusingget_form_runner.
Given a model name inlabel_lowerformat,get_form_runnerchecks the site global (site_form_runners) and returns
a customFormRunner, if it exists, otherwise returns the defaultFormRunner.In your code you should useget_form_runner:# good, returned DmMedicationAdherenceFormRunner instead of the default FormRunnerrunner=get_form_runner("intecomm_subject.dmmedicationadherence")runner.run()# works but does not use your custom form runnerrunner=FormRunner("intecomm_subject.dmmedicationadherence")runner.run_all()Management Commandrun_form_runnersYou can use the management commandrun_form_runnersto run form runners for some or
all CRF/Requisitions. Run this command to initially populateIssuetable and whenever you
change validation logic for a form.Pass the management command one or more app_labels separated by comma:>>>pythonmanage.pyrun_form_runners-aintecomm_subjector pass one or more model names (label_lower format) separated by comma:>>>pythonmanage.pyrun_form_runners-mintecomm_subject.vitals,intecomm_subject.dmmedicationadherenceYou can skip a model as well:>>>pythonmanage.pyrun_form_runners-aintecomm_subject-sintecomm_subject.medicationadherenceIssueChangeListTheChangeListfor theIssue modelis available inedc_data_managerandedc_form_runners.
You would typically use the one inedc_data_manager.From the change list you can:search, filter and re-orderrefresh selectedIssueinstances from the action menu.navigate to a subject`s dashboardIntegrated with the Subject DashboardThe subject dashboard shows an “Issues” badge next to a CRF or Requisition if one exists. You can
hover over the badge to see some of the error messages detected when theFormRunnerlast ran.If a user edits a CRF with a detected issue and the corrected form validates withour error, theIssueinstance is deleted and the badge is no longer displayed.
(See alsosignals.py)FormRunnerisclinicedcspecificAt the moment, theFormRunnerclass is currentlyclinicedcspecific in that it only works for models with asubject_identifieror related_visit FK (e.g.subject_visit).Thepost_savesignal that updates Issues listens forclinicedcCRFs and Requisitions by testing if the model instance
is an instance ofCrfModelMixin,CrfNoManagerModelMixinorRequisitionModelMixin.