1 from __future__ import absolute_import, print_function, unicode_literals
3 from itertools import chain
5 from django.contrib import admin
6 from django.forms import ModelForm
7 from django.forms.fields import CharField
8 from django.forms.widgets import TextInput, Select
9 from django.utils.encoding import force_text
10 from django.utils.html import escape, conditional_escape
23 class DataFileForm(ModelForm):
26 fields = ('random_key', 'sequencing_run', 'library',
27 'file_type', 'relative_pathname')
30 class DataFileInline(admin.TabularInline):
33 raw_id_fields = ('library',)
37 class SequencingRunOptions(admin.ModelAdmin):
51 ('flowcell', 'run_status'),
52 ('runfolder_name', 'cycle_start', 'cycle_stop'),
55 ('image_software', 'image_version'),
56 ('basecall_software', 'basecall_version'),
57 ('alignment_software', 'alignment_version'),
61 inlines = [DataFileInline]
62 # list_filter = ('run_status', 'run_start_time')
63 admin.site.register(SequencingRun, SequencingRunOptions)
66 class FileTypeAdmin(admin.ModelAdmin):
67 list_display = ('name', 'mimetype', 'regex')
68 admin.site.register(FileType, FileTypeAdmin)
71 # lane form setup needs to come before Flowcell form config
72 # as flowcell refers to the LaneInline class
73 class LaneForm(ModelForm):
75 widget=TextInput(attrs={'size': '80'}),
80 fields = ('flowcell', 'lane_number', 'library',
81 'pM', 'cluster_estimate',
85 class LaneInline(admin.StackedInline):
86 """Controls display of Lanes on the Flowcell form.
91 raw_id_fields = ('library',)
94 'fields': ('lane_number', 'flowcell',
96 ('pM', 'cluster_estimate', 'status'),
102 class LaneOptions(admin.ModelAdmin):
103 """Controls display of Lane browser
106 '=flowcell__flowcell_id',
108 'library__library_name')
109 list_display = ('flowcell', 'lane_number', 'library', 'comment')
112 'fields': ('lane_number', 'flowcell',
114 ('pM', 'cluster_estimate'))
117 'classes': ('collapse', ),
118 'fields': ('comment', )
121 admin.site.register(Lane, LaneOptions)
124 class FlowCellOptions(admin.ModelAdmin):
126 css = {'all': ('css/admin_flowcell.css',)}
127 date_hierarchy = "run_date"
132 'cluster_station__name',
133 '=lane__library__id',
134 'lane__library__library_name')
135 list_display = ('flowcell_id', 'run_date', 'Lanes')
136 list_filter = ('sequencer', 'cluster_station', 'paired_end')
139 'fields': ('run_date',
140 ('flowcell_id', 'cluster_station', 'sequencer'),
141 ('read_length', 'control_lane', 'paired_end'),)
143 ('Notes:', {'fields': ('notes',), }),
149 def formfield_for_dbfield(self, db_field, **kwargs):
150 field = super(FlowCellOptions, self).formfield_for_dbfield(db_field,
153 # Override field attributes
154 if db_field.name == 'sequencer':
155 # seems kind of clunky.
156 # the goal is to replace the default select/combo box with one
157 # that can strike out disabled options.
158 attrs = field.widget.widget.attrs
159 field.widget.widget = SequencerSelect(
161 queryset=field.queryset)
162 elif db_field.name == "notes":
163 field.widget.attrs["rows"] = "3"
165 admin.site.register(FlowCell, FlowCellOptions)
168 class ClusterStationOptions(admin.ModelAdmin):
169 list_display = ('name', 'isdefault',)
170 fieldsets = ((None, {'fields': ('name', 'isdefault')}),)
171 admin.site.register(ClusterStation, ClusterStationOptions)
174 class SequencerSelect(Select):
175 def __init__(self, queryset=None, *args, **kwargs):
176 super(SequencerSelect, self).__init__(*args, **kwargs)
177 self.queryset = queryset
179 def render_options(self, choices, selected_choices):
180 # Normalize to strings.
181 selected_choices = set([force_text(v) for v in selected_choices])
183 for option_value, option_label in chain(self.choices, choices):
184 if isinstance(option_label, (list, tuple)):
185 output.append(u'<optgroup label="%s">' %
186 escape(force_text(option_value)))
187 for option in option_label:
189 self.render_option(selected_choices,
191 output.append(u'</optgroup>')
194 self.render_option(selected_choices,
197 return u'\n'.join(output)
199 def render_option(self, selected_choices, option_value, option_label):
200 disabled_sequencers = [str(s.id) for s in
201 self.queryset.filter(active=False)]
202 option_value = str(option_value)
203 selected_html = (option_value in selected_choices) and \
204 u' selected="selected"' or ''
205 cssclass = "strikeout" if option_value in disabled_sequencers else ''
206 return u'<option class="%s" value="%s"%s>%s</option>' % (
207 cssclass, escape(option_value), selected_html,
208 conditional_escape(force_text(option_label)))
211 class SequencerOptions(admin.ModelAdmin):
212 list_display = ('name', 'active', 'isdefault', 'instrument_name', 'model')
216 ('active', 'isdefault'),
219 'model', 'comment')}), )
221 admin.site.register(Sequencer, SequencerOptions)