initial attempt to use django restframework rest_framework
authorDiane Trout <diane@ghic.org>
Tue, 12 May 2015 19:14:05 +0000 (12:14 -0700)
committerDiane Trout <diane@ghic.org>
Tue, 12 May 2015 19:14:05 +0000 (12:14 -0700)
experiments/serializers.py [new file with mode: 0644]
experiments/templates/experiments/flowcell_detail.html
experiments/templates/experiments/flowcell_header.html
experiments/urls.py
experiments/views.py
htsworkflow/settings/base.py
htsworkflow/templates/samples/species_list.html [new file with mode: 0644]
htsworkflow/urls.py
samples/serializers.py [new file with mode: 0644]
samples/urls.py
samples/views.py

diff --git a/experiments/serializers.py b/experiments/serializers.py
new file mode 100644 (file)
index 0000000..6166640
--- /dev/null
@@ -0,0 +1,61 @@
+from rest_framework import serializers
+
+from .models import (
+    ClusterStation,
+    Lane,
+    FlowCell,
+    Sequencer,    
+)
+
+
+class ClusterStationSerializer(serializers.HyperlinkedModelSerializer):
+    class Meta:
+        model = ClusterStation
+
+
+class LaneSerializer(serializers.HyperlinkedModelSerializer):
+    flowcell = serializers.HyperlinkedRelatedField(
+        lookup_field='flowcell_id',
+        view_name='flowcell-detail')
+
+    library = serializers.HyperlinkedRelatedField(
+        view_name='library-detail')
+
+    class Meta:
+        model = Lane
+        fields = (
+            'url',
+            'lane_number',
+            'library',
+            'pM',
+            'cluster_estimate',
+            'status',
+            'comment')
+
+
+class FlowCellSerializer(serializers.HyperlinkedModelSerializer):
+    url = serializers.HyperlinkedIdentityField(
+        lookup_field='flowcell_id',
+        view_name='flowcell-detail')
+
+    class Meta:
+        model = FlowCell
+        depth = 2
+        fields = (
+            'url',
+            'flowcell_id',
+            'run_date',
+            'paired_end',
+#            'flowcell_type',
+            'read_length',
+            'control_lane',
+            'cluster_station',
+            'sequencer',
+            'notes',
+            'lane_set',
+        )
+
+class SequencerSerializer(serializers.HyperlinkedModelSerializer):
+    class Meta:
+        model = Sequencer
+        fields = ('url', 'name', 'instrument_name', 'serial_number', 'model')
index 64da7e2886881d3609e4344353a0da75aceb00d5..f2317bdd9f78b97383b3e202022cc96d0ac6dd22 100644 (file)
        </tr>
       </thead>
       <tbody>
-      {% for lane in lanes %}
+      {% for lane in lane_set %}
         <tr>
           <td rel="libns:has_lane">
-            <a href="{{lane.get_absolute_url}}" typeof="libns:IlluminaLane">
+            <a href="{{lane.url}}" typeof="libns:IlluminaLane">
               <span property="libns:lane_number">{{lane.lane_number}}</span>
             </a>
           </td>
index f0cb470102ce3932bbfbe17fbec315a51f152202..3964192f148ca6d754b510f23377f60c2af1a93d 100644 (file)
@@ -2,23 +2,23 @@
 <div class="flowcell_identity" typeof="libns:IlluminaFlowcell" resource="{{flowcell.get_absolute_url}}">
   <h2>About this Flowcell</h2>
   <b>Flowcell</b>:
-    <a href="{{flowcell.get_absolute_url}}"><span property="libns:flowcell_id">{{flowcell.flowcell_id}}</span></a>{% if user.is_staff %}<a href="{{flowcell.get_admin_url}}"><img class="icon_button" src="{% static "admin/img/icon_changelink.gif" %}" alt="Edit"/></a>{% endif%}
+    <a href="{{url}}"><span property="libns:flowcell_id">{{flowcell_id}}</span></a>{% if user.is_staff %}<a href="{{flowcell.get_admin_url}}"><img class="icon_button" src="{% static "admin/img/icon_changelink.gif" %}" alt="Edit"/></a>{% endif%}
   <br/>
   <div rel="libns:sequenced_by">
   <div typeof="libns:Sequencer"
-       about="{{flowcell.sequencer.get_absolute_url}}">
+       about="{{ sequencer.url }}">
   <b>Instrument</b>:
-    <span property="libns:sequencer_name">{{ flowcell.sequencer.name }}</span>
-    {% if flowcell.sequencer.instrument_name %}
-    (<span property="libns:sequencer_instrument">{{ flowcell.sequencer.instrument_name}}</span>)
+    <span property="libns:sequencer_name">{{ sequencer.name }}</span>
+    {% if sequencer.instrument_name %}
+    (<span property="libns:sequencer_instrument">{{ sequencer.instrument_name}}</span>)
     {% endif %}
     <br/>
   <b>Instrument Model</b>:
-    <span property="libns:sequencer_model">{{flowcell.sequencer.model}}</span>
+    <span property="libns:sequencer_model">{{sequencer.model}}</span>
     <br/>
   </div>
   </div>
-  {% for datarun in flowcell.datarun_set.all %}
+  {% for datarun in datarun_set.all %}
   <b>Image Analysis</b>:
     <span property="libns:image_software">{{datarun.image_software}}</span>
     <span property="libns:image_version">{{datarun.image_version}}</span><br/>
     <span property="libns:alignment_version">{{datarun.alignment_version}}</span><br/>
   {% endfor %}
   <b>Run Date</b>:
-    <span property="libns:date" content="{{flowcell.run_date|date:'Y-m-d\TH:i:s'}}" datatype="xsd:dateTime">{{ flowcell.run_date }}</span><br/>
+    <span property="libns:date" content="{{flowcell.run_date|date:'Y-m-d\TH:i:s'}}" datatype="xsd:dateTime">{{ run_date }}</span><br/>
   <b>Type</b>:
-    <span property="libns:flowcell_type">{{flowcell.flowcell_type}}</span><br/>
+    <span property="libns:flowcell_type">{{flowcell_type}}</span><br/>
   <b>Read Length</b>:
-    <span property="libns:read_length" datatype="xsd:integer">{{flowcell.read_length}}</span><br/>
+    <span property="libns:read_length" datatype="xsd:integer">{{read_length}}</span><br/>
   <b>Control Lane</b>:
-    <span property="libns:control_lane">{{flowcell.control_lane}}</span><br/>
+    <span property="libns:control_lane">{{control_lane}}</span><br/>
 
   <b>Notes</b>:
-    <pre property="libns:flowcell_notes">{{flowcell.notes}}</pre>
+    <pre property="libns:flowcell_notes">{{notes}}</pre>
  </div>
index 0b1722ec1a43df24d2b1626885867b161ab508a6..44929092b953d4823da33b78d0a3ef464b53d082 100644 (file)
@@ -2,13 +2,29 @@ from __future__ import unicode_literals
 
 from django.conf.urls import patterns
 
-urlpatterns = patterns('',
-    (r'^$', 'experiments.views.index'),
-    #(r'^liblist$', 'htsworkflow.frontend.experiments.views.test_Libs'),
-    #(r'^(?P<run_folder>.+)/$', 'gaworkflow.frontend.experiments.views.detail'),
-    (r'^config/(?P<fc_id>.+)/json$', 'experiments.experiments.flowcell_json'),
-    (r'^lanes_for/(?P<username>.+)/json$', 'experiments.experiments.lanes_for_json'),
-    (r'^file/(?P<key>.+)/?$', 'experiments.views.read_result_file'),
-    (r'^started/(?P<pk>.+)/$', 'experiments.views.startedEmail'),
-    (r'^finished/(?P<pk>.+)/$', 'experiments.views.finishedEmail'),
-)
+from rest_framework import routers
+
+from .views import (
+    ClusterStationViewSet,
+    LaneViewSet,
+    FlowCellViewSet,
+    SequencerViewSet,
+    )
+
+#urlpatterns = patterns('',
+#    (r'^$', 'experiments.views.index'),
+#    #(r'^liblist$', 'htsworkflow.frontend.experiments.views.test_Libs'),
+#    #(r'^(?P<run_folder>.+)/$', 'gaworkflow.frontend.experiments.views.detail'),
+#    (r'^config/(?P<fc_id>.+)/json$', 'experiments.experiments.flowcell_json'),
+#    (r'^lanes_for/(?P<username>.+)/json$', 'experiments.experiments.lanes_for_json'),
+#    (r'^file/(?P<key>.+)/?$', 'experiments.views.read_result_file'),
+#    (r'^started/(?P<pk>.+)/$', 'experiments.views.startedEmail'),
+#    (r'^finished/(?P<pk>.+)/$', 'experiments.views.finishedEmail'),
+#)
+
+router = routers.DefaultRouter()
+router.register(r'cluster_station', ClusterStationViewSet)
+router.register(r'lane', LaneViewSet)
+router.register(r'flowcell', FlowCellViewSet)
+router.register(r'sequencer', SequencerViewSet)
+urlpatterns = router.urls
index 521e89f4852e9480376425382375dc844e375272..9b1c8a196e4f6171be1881c27b11c0ff8bed9b27 100644 (file)
@@ -16,10 +16,21 @@ from django.template import RequestContext
 from django.template.loader import get_template
 
 from .models import DataRun, DataFile, FlowCell, Lane, Sequencer
+from rest_framework import viewsets
+from rest_framework.response import Response
+from rest_framework.renderers import (TemplateHTMLRenderer,
+                                      JSONRenderer,
+                                      BrowsableAPIRenderer)
+
 from .admin import LaneOptions
 from .experiments import estimateFlowcellDuration, estimateFlowcellTimeRemaining, roundToDays, \
      getUsersForFlowcell, \
      makeEmailLaneMap
+from .serializers import (
+    ClusterStationSerializer,
+    SequencerSerializer,
+    LaneSerializer,
+    FlowCellSerializer)
 from samples.changelist import HTSChangeList
 from samples.models import HTSUser
 
@@ -132,6 +143,72 @@ def finishedEmail(request, pk):
     return HttpResponse("I've got nothing.")
 
 
+
+class ClusterStationViewSet(viewsets.ReadOnlyModelViewSet):
+    renderer_classes = (TemplateHTMLRenderer,
+                        BrowsableAPIRenderer,
+                        JSONRenderer)
+    queryset = ClusterStation.objects.all()
+    serializer_class = ClusterStationSerializer
+    # template_name = 'experiments/cluster_station.html'
+
+from pprint import pprint
+class FlowCellViewSet(viewsets.ReadOnlyModelViewSet):
+    renderer_classes = (TemplateHTMLRenderer,
+                        BrowsableAPIRenderer,
+                        JSONRenderer)
+    queryset = FlowCell.objects.all()
+    lookup_field = 'flowcell_id'
+    serializer_class = FlowCellSerializer
+    template_name = 'experiments/flowcell_detail.html'
+
+    def retrieve(self, request, *args, **kwargs):
+        fc = get_object_or_404(self.queryset, flowcell_id = kwargs['flowcell_id'])
+        context = kwargs.copy()
+        context['request'] = request
+        serializer = FlowCellSerializer(
+            fc,
+            context=context,
+            )
+        pprint(serializer.data)
+        return Response(serializer.data)
+
+    #def retrieve(self, request, flowcell_id=None, format=None):
+    #    queryset = FlowCell.objects.all()
+    #    fc = get_object_or_404(queryset, flowcell_id=flowcell_id)
+    #    serializer = FlowCellSerializer(
+    #        fc,
+    #        context={
+    #            'request': request,
+    #            'format': format,
+    #        }
+    #    )
+    #    return Response(
+    #        serializer.data,
+    #    )
+
+    #def list(self, *args, **kwargs):
+    #    template_name = 'experiments/flowcell_index.html'
+    #    return super(FlowCellViewSet, self).list(*args, **kwargs)
+
+class LaneViewSet(viewsets.ReadOnlyModelViewSet):
+    renderer_classes = (TemplateHTMLRenderer,
+                        BrowsableAPIRenderer,
+                        JSONRenderer)
+    queryset = Lane.objects.all()
+    serializer_class = LaneSerializer
+    template_name = 'experiments/flowcell_lane_detail.html'
+
+
+
+class SequencerViewSet(viewsets.ReadOnlyModelViewSet):
+    renderer_classes = (TemplateHTMLRenderer,
+                        BrowsableAPIRenderer,
+                        JSONRenderer)
+    queryset = Sequencer.objects.all()
+    serializer_class = SequencerSerializer
+    template_name = 'experiments/sequencer.html'
+
 def flowcell_detail(request, flowcell_id, lane_number=None):
     fc = get_object_or_404(FlowCell, flowcell_id__startswith=flowcell_id)
     fc.update_data_runs()
@@ -186,13 +263,6 @@ def read_result_file(self, key):
     raise Http404
 
 
-def sequencer(request, sequencer_id):
-    sequencer = get_object_or_404(Sequencer, id=sequencer_id)
-    context = RequestContext(request,
-                             {'sequencer': sequencer})
-    return render_to_response('experiments/sequencer.html', context)
-
-
 def lanes_for(request, username=None):
     """
     Generate a report of recent activity for a user
index 97518e0b44780d1a5ead1440c29649d6ccc0419f..dba1ab21b261a9400ebb16794037f5f24709431a 100644 (file)
@@ -42,6 +42,7 @@ INSTALLED_APPS = [
     'django.contrib.messages',
     'django.contrib.staticfiles',
     'django.contrib.humanize',
+    'rest_framework',
 
     'eland_config',
     'samples',
@@ -106,3 +107,9 @@ NOTIFICATION_BCC=[]
 
 # Update this in settings_local to point to your flowcell result directory
 RESULT_HOME_DIR = join(PROJECT_ROOT, 'test', 'result', 'flowcells')
+
+
+REST_FRAMEWORK = {
+    'DEFAULT_PAGINATION_SERIALIZER_CLASS': 'rest_framework.pagination.PaginationSerializer',
+    'PAGINATE_BY' : 25,
+}
diff --git a/htsworkflow/templates/samples/species_list.html b/htsworkflow/templates/samples/species_list.html
new file mode 100644 (file)
index 0000000..58727b5
--- /dev/null
@@ -0,0 +1,30 @@
+{% extends "base_site.html" %}
+{% load admin_list i18n %}
+{% load staticfiles %}
+{% block bodyclass %}change-list{% endblock %}
+{% block coltype %}flex{% endblock %}
+
+{% block content %}
+<div id="species-index-div" >
+  <div class="module{% if cl.has_filters %} filtered{% endif %}" id="changelist">
+  {% block summary_stats %}
+  <table class="{% if cl.has_filters %} filtered{% endif %}">
+    <thead >
+      <tr >
+        <td >Species</td>
+        <td >Common Name</td>
+      </tr>
+    </thead>
+    <tbody >
+      {% for s in species %}
+      <tr>
+        <td><a href="{{s.url}}">{{ s.scientific_name }}</a></td>
+        <td>{{ s.common_name }}</td>
+      </tr>
+      {% endfor %}
+    </tbody>
+  </table>
+  </div>
+  {% endblock %}
+</div>
+{% endblock %}
index bb8364280e69f5ad649b41081b613a62c4389263..1f258ebffdfaa3b232fce2d00de55862018d24b1 100644 (file)
@@ -3,29 +3,32 @@ from django.contrib import admin
 import django
 admin.autodiscover()
 
-from django.conf import settings
+from experiments.urls import urlpatterns as experiment_urls
 
-urlpatterns = patterns('',
+urlpatterns = experiment_urls
+
+urlpatterns += patterns(
+    '',
     url('^accounts/', include('django.contrib.auth.urls')),
     # Base:
     url(r'^eland_config/', include('eland_config.urls')),
     # Experiments:
-    url(r'^experiments/', include('experiments.urls')),
-    url(r'^lane/(?P<lane_pk>\w+)',
-        'experiments.views.flowcell_lane_detail'),
-    url(r'^flowcell/(?P<flowcell_id>\w+)/((?P<lane_number>\w+)/)?$',
-        'experiments.views.flowcell_detail'),
+    url(r'^experiments/', include('experiments.urls')),
+    url(r'^lane/(?P<lane_pk>\w+)',
+    #    'experiments.views.flowcell_lane_detail'),
+    url(r'^flowcell/(?P<flowcell_id>\w+)/((?P<lane_number>\w+)/)?$',
+    #    'experiments.views.flowcell_detail'),
     url(r'^inventory/', include('inventory.urls')),
     url(r'^library/', include('samples.urls')),
-    url(r'^lanes_for/$', 'experiments.views.lanes_for'),
-    url(r'^lanes_for/(?P<username>[-_ \w]+)', 'experiments.views.lanes_for'),
-    ### library id to admin url
-    url(r'^library_id_to_admin_url/(?P<lib_id>\w+)/$',
-        'samples.views.library_id_to_admin_url'),
-    ### sample / library information
+    url(r'^lanes_for/$', 'experiments.views.lanes_for'),
+    url(r'^lanes_for/(?P<username>[-_ \w]+)', 'experiments.views.lanes_for'),
+    # library id to admin url
+    url(r'^library_id_to_admin_url/(?P<lib_id>\w+)/$',
+        'samples.views.library_id_to_admin_url'),
+    # sample / library information
     url(r'^samples/', include('samples.urls')),
-    url(r'^sequencer/(?P<sequencer_id>\w+)',
-        'experiments.views.sequencer'),
+    url(r'^sequencer/(?P<sequencer_id>\w+)',
+    #    'experiments.views.sequencer'),
 
     url(r'^admin/', include(admin.site.urls)),
 )
diff --git a/samples/serializers.py b/samples/serializers.py
new file mode 100644 (file)
index 0000000..766d988
--- /dev/null
@@ -0,0 +1,30 @@
+from rest_framework import serializers
+
+from .models import (Antibody,
+                     Cellline,
+                     ExperimentType,
+                     Species,
+                     Affiliation,
+                     Library,
+                     HTSUser)
+
+
+class ExperimentTypeSerializer(serializers.HyperlinkedModelSerializer):
+    class Meta:
+        model = ExperimentType
+        fields = ('url', 'name')
+
+
+class SpeciesSerializer(serializers.HyperlinkedModelSerializer):
+    class Meta:
+        model = Species
+        fields = ('url', 'common_name', 'scientific_name')
+
+
+class LibrarySerializer(serializers.HyperlinkedModelSerializer):
+    class Meta:
+        model = Library
+        fields = ('url', 'library_name', 'library_species', 'replicate',
+                  'experiment_type',
+                  'made_for', 'made_by', 'stopping_point',
+                  'undiluted_concentration', 'gel_cut_size', 'notes')
index 1bda463ed3c6a965d61ee287e464e13e984a3277..e4c40737d7be81d069087aca0526010e7b6ff338 100644 (file)
@@ -2,15 +2,26 @@ from __future__ import unicode_literals
 
 from django.conf.urls import patterns, url
 
-urlpatterns = patterns('samples.views',
-    # View livrary list
-    url(r'^$', 'library'),
-    url(r'^not_run/$', 'library_not_run'),
-    url(r'^(?P<lib_id>\w+)/$',
-        'library_to_flowcells'),
+from rest_framework import routers
 
-    url(r"^library/(?P<library_id>\w+)/json$", 'library_json'),
-    url(r"^species/(?P<species_id>\w+)/json$", 'species_json'),
-    url(r"^species/(?P<species_id>\w+)$", 'species'),
-    url(r"^antibody/$", 'antibodies'),
+from .views import ExperimentTypeViewSet, LibraryViewSet, SpeciesViewSet
+
+urlpatterns = patterns(
+    'samples.views',
+    # View library list
+    # url(r'^$', 'library'),
+    # url(r'^not_run/$', 'library_not_run'),
+    # url(r'^(?P<lib_id>\w+)/$',
+    #    'library_to_flowcells'),
+
+    # url(r"^library/(?P<library_id>\w+)/json$", 'library_json'),
+    # url(r"^species/(?P<species_id>\w+)/json$", 'species_json'),
+    # url(r"^species/(?P<species_id>\w+)$", 'species'),
+    # url(r"^antibody/$", 'antibodies'),
 )
+
+router = routers.DefaultRouter()
+router.register(r'species', SpeciesViewSet)
+router.register(r'libraries', LibraryViewSet)
+router.register(r'experiment_type', ExperimentTypeViewSet)
+urlpatterns += router.urls
index 3b5ea350e2289e16d7474bec221580d8175311b4..78cd0ba0c6f5d838cc46fae8d243274cb2ac9c53 100644 (file)
@@ -12,12 +12,22 @@ from django.template import RequestContext
 from django.template.loader import get_template
 from django.contrib.auth.decorators import login_required
 
+from rest_framework import viewsets
+from rest_framework.response import Response
+from rest_framework.renderers import (TemplateHTMLRenderer,
+                                      JSONRenderer,
+                                      BrowsableAPIRenderer)
+
 from htsworkflow.auth import require_api_key
 from experiments.models import FlowCell, LANE_STATUS_MAP
 from .changelist import HTSChangeList
 from .models import Antibody, Library, Species
 from .admin import LibraryOptions
 from .results import get_flowcell_result_dict
+from .serializers import (ExperimentTypeSerializer,
+                          LibrarySerializer,
+                          SpeciesSerializer)
+
 from bcmagic.forms import BarcodeMagicForm
 from htsworkflow.pipelines import runfolder
 from htsworkflow.pipelines.samplekey import SampleKey
@@ -451,26 +461,62 @@ def library_json(request, library_id):
     return HttpResponse(lib_json, content_type='application/json')
 
 
-@csrf_exempt
-def species_json(request, species_id):
-    """
-    Return information about a species.
-    """
-    raise Http404
-
-
-def species(request, species_id):
-    species = get_object_or_404(Species, id=species_id)
-
-    context = RequestContext(request,
-                             {'species': species})
-
-    return render_to_response("samples/species_detail.html", context)
+class LibraryViewSet(viewsets.ReadOnlyModelViewSet):
+    renderer_classes = (TemplateHTMLRenderer,
+                        BrowsableAPIRenderer,
+                        JSONRenderer)
+    queryset = Library.objects.all()
+    serializer_class = LibrarySerializer
+    pagination_class = 'rest_framework.pagination.LimitOffsetPagination'
+    default_limit = 50
+    template_name = 'samples/library_detail.html'
+
+
+class ExperimentTypeViewSet(viewsets.ReadOnlyModelViewSet):
+    renderer_classes = (BrowsableAPIRenderer,
+                        JSONRenderer)
+    queryset = ExperimentType.objects.all()
+    serializer_class = ExperimentTypeSerializer
+
+#@csrf_exempt
+#def species_json(request, species_id):
+#    """
+#    Return information about a species.
+#    """
+#    raise Http404
+#
+#
+#def species(request, species_id):
+#    species = get_object_or_404(Species, id=species_id)
+#
+#    context = RequestContext(request,
+#                             {'species': species})
+#
+#    return render_to_response("samples/species_detail.html", context)
+#
+
+class SpeciesViewSet(viewsets.ReadOnlyModelViewSet):
+    renderer_classes = (TemplateHTMLRenderer,
+                        BrowsableAPIRenderer,
+                        JSONRenderer)
+    queryset = Species.objects.all()
+    serializer_class = SpeciesSerializer
+    template_name = 'samples/species_detail.html'
+
+    def list(self, request, format=format):
+        queryset = Species.objects.all()
+        serializer = self.serializer_class(
+            queryset,
+            many=True,
+            context={'request': request})
+        return Response({'species': serializer.data},
+                        template_name='samples/species_list.html')
 
 
 def antibodies(request):
-    context = RequestContext(request,
-                             {'antibodies': Antibody.objects.order_by('antigene')})
+    context = RequestContext(
+        request,
+        {'antibodies': Antibody.objects.order_by('antigene')})
     return render_to_response("samples/antibody_index.html", context)