From 1b018ab3bed778adbe9f282a51315b26cde37427 Mon Sep 17 00:00:00 2001 From: Robert Ernst Date: Fri, 9 Jul 2021 13:29:07 +0200 Subject: [PATCH] Add gene search form to sample page. --- ExonCov/forms.py | 23 +++++++++++++++++++ ExonCov/static/css/exoncov.css | 4 ++++ ExonCov/templates/macros/forms.html | 2 +- ExonCov/templates/sample.html | 15 ++++++++++++- ExonCov/views.py | 34 ++++++++++++++++++++++++----- 5 files changed, 71 insertions(+), 7 deletions(-) diff --git a/ExonCov/forms.py b/ExonCov/forms.py index daf07db..0faecaa 100644 --- a/ExonCov/forms.py +++ b/ExonCov/forms.py @@ -368,3 +368,26 @@ def validate(self): self.gene_id = gene.id return valid_form + + +class SampleGeneForm(FlaskForm): + """Sample Form to query a specific gene.""" + gene = StringField('Gene', validators=[validators.InputRequired()]) + gene_id = '' + + def validate(self): + """Extra validation to parse panel / gene selection""" + self.gene_id = '' + valid_form = True + + if not FlaskForm.validate(self): + valid_form = False + + if self.gene.data: + gene, error = get_gene(self.gene.data) + if error: + self.gene.errors.append(error) + else: + self.gene_id = gene.id + + return valid_form diff --git a/ExonCov/static/css/exoncov.css b/ExonCov/static/css/exoncov.css index dfa3025..59f08e1 100644 --- a/ExonCov/static/css/exoncov.css +++ b/ExonCov/static/css/exoncov.css @@ -11,3 +11,7 @@ body { float: left; text-align: left; } + +.help-block-inline { + display: inline; +} \ No newline at end of file diff --git a/ExonCov/templates/macros/forms.html b/ExonCov/templates/macros/forms.html index 90b8d96..0142188 100644 --- a/ExonCov/templates/macros/forms.html +++ b/ExonCov/templates/macros/forms.html @@ -61,7 +61,7 @@ {{ field.label(class_='control-label') }} {{ field(class_='form-control', size=40, **kwargs) }} {% for error in field.errors %} - {{error}} + {{error}} {% endfor %} {% else %} diff --git a/ExonCov/templates/sample.html b/ExonCov/templates/sample.html index 42519e7..6e686dd 100644 --- a/ExonCov/templates/sample.html +++ b/ExonCov/templates/sample.html @@ -1,5 +1,5 @@ {% from "macros/tables.html" import render_panel_measurement_td %} -{% from "macros/forms.html" import render_sample_datatable_form %} +{% from "macros/forms.html" import render_sample_datatable_form, render_inline_field %} {% extends 'base.html' %} {% block header %}{{ sample.name }}{% endblock %} @@ -14,6 +14,19 @@ + +
+
+ {{ form.csrf_token }} + {{ render_inline_field(form.gene) }} +
+
+ +
+
+
+
+ {% if sample.custom_panels %} diff --git a/ExonCov/views.py b/ExonCov/views.py index 1ca9ab9..d3b323e 100644 --- a/ExonCov/views.py +++ b/ExonCov/views.py @@ -17,7 +17,7 @@ ) from .forms import ( MeasurementTypeForm, CustomPanelForm, CustomPanelNewForm, CustomPanelValidateForm, SampleForm, - CreatePanelForm, PanelNewVersionForm, PanelEditForm, PanelVersionEditForm, SampleSetPanelGeneForm + CreatePanelForm, PanelNewVersionForm, PanelEditForm, PanelVersionEditForm, SampleSetPanelGeneForm, SampleGeneForm ) from .utils import weighted_average @@ -54,18 +54,42 @@ def samples(): return render_template('samples.html', form=sample_form, samples=samples) -@app.route('/sample/') +@app.route('/sample/', methods=['GET', 'POST']) @login_required def sample(id): """Sample page.""" - sample = Sample.query.options(joinedload('sequencing_runs')).options(joinedload('project')).options(joinedload('custom_panels')).get_or_404(id) + + # Setup gene form and validate + gene_form = SampleGeneForm() + + if gene_form.validate_on_submit(): + if gene_form.gene_id: + return redirect(url_for('sample_gene', sample_id=id, gene_id=gene_form.gene_id)) + + # Query Sample and panels + sample = ( + Sample.query + .options(joinedload('sequencing_runs')) + .options(joinedload('project')) + .options(joinedload('custom_panels')) + .get_or_404(id) + ) + query = ( + db.session.query(PanelVersion, TranscriptMeasurement) + .filter_by(active=True) + .filter_by(validated=True) + .join(Transcript, PanelVersion.transcripts) + .join(TranscriptMeasurement) + .filter_by(sample_id=sample.id) + .order_by(PanelVersion.panel_name) + .all() + ) measurement_types = { 'measurement_mean_coverage': 'Mean coverage', 'measurement_percentage10': '>10', 'measurement_percentage15': '>15', 'measurement_percentage30': '>30' } - query = db.session.query(PanelVersion, TranscriptMeasurement).filter_by(active=True).filter_by(validated=True).join(Transcript, PanelVersion.transcripts).join(TranscriptMeasurement).filter_by(sample_id=sample.id).order_by(PanelVersion.panel_name).all() panels = {} for panel, transcript_measurement in query: @@ -84,7 +108,7 @@ def sample(id): [panels[panel.id]['len'], transcript_measurement.len] ) panels[panel.id]['len'] += transcript_measurement.len - return render_template('sample.html', sample=sample, panels=panels, measurement_types=measurement_types) + return render_template('sample.html', sample=sample, panels=panels, measurement_types=measurement_types, form=gene_form) @app.route('/sample//inactive_panels')