For all your library accessioning needs.
</li>
{% endfor %}
</ul>
- </div>
+ {% if lib.libraryaccession_set %}
+ <b>Accessions</b>:
+ <ul rel="libns:accession">
+ <li>
+ {% for accession in lib.libraryaccession_set.all %}
+ <a href="{{ accession.url }}">{{ accession }}</a>
+ {% endfor %}
+ </li>
+ </ul>
+ {% endif %}
+ </div>
<div class="library_sample_detail">
<h2>Sample Details</h2>
<b>Species</b>:
from django.template import Context, Template
from .models import (
+ AccessionAgency,
+ LibraryAccession,
Antibody,
Cellline,
Condition,
admin.site.disable_action('delete_selected')
+class AccessionAgencyOptions(admin.ModelAdmin):
+ model = AccessionAgency
+
+
+class LibraryAccessionOptions(admin.ModelAdmin):
+ model = LibraryAccession
+ search_fields = ('accession', 'library')
+ list_filter = ('agency', 'created',)
+ list_display = ('accession', 'library', 'created')
+
+
+class LibraryAccessionInline(admin.TabularInline):
+ model = LibraryAccession
+ fieldsets = (
+ (None, {
+ 'fields': ('agency', 'accession', 'accession_url')
+ }),
+ )
+
+
class AffiliationOptions(admin.ModelAdmin):
list_display = ('name', 'contact', 'email')
fieldsets = (
'cell_line__cellline_name',
'library_species__scientific_name',
'library_species__common_name',
+ 'libraryaccession__accession',
)
list_display = (
'id',
)
inlines = [
LaneLibraryInline,
+ LibraryAccessionInline,
]
actions = ['action_print_library_labels']
}),
)
+admin.site.register(AccessionAgency, AccessionAgencyOptions)
+admin.site.register(LibraryAccession, LibraryAccessionOptions)
admin.site.register(Library, LibraryOptions)
admin.site.register(Affiliation, AffiliationOptions)
admin.site.register(Antibody, AntibodyOptions)
--- /dev/null
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+import django.core.validators
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('samples', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='AccessionAgency',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', auto_created=True, serialize=False, primary_key=True)),
+ ('name', models.CharField(max_length=255)),
+ ('homepage', models.URLField(blank=True)),
+ ('library_template', models.URLField(blank=True)),
+ ],
+ options={
+ 'verbose_name_plural': 'Accession Agencies',
+ },
+ bases=(models.Model,),
+ ),
+ migrations.CreateModel(
+ name='LibraryAccession',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', auto_created=True, serialize=False, primary_key=True)),
+ ('accession', models.CharField(db_index=True, validators=[django.core.validators.RegexValidator('^[-A-Za-z0-9:.]*$', message='Please only use letters, digits, and :.-')], max_length=255)),
+ ('url', models.URLField(blank=True, null=True)),
+ ('created', models.DateTimeField()),
+ ('agency', models.ForeignKey(to='samples.AccessionAgency')),
+ ('library', models.ForeignKey(to='samples.Library')),
+ ],
+ options={
+ 'abstract': False,
+ },
+ bases=(models.Model,),
+ ),
+ ]
from django.core import urlresolvers
from django.db.models.signals import post_save
from django.db import connection
+from django.core.validators import RegexValidator
import six
logger = logging.getLogger(__name__)
+class AccessionAgency(models.Model):
+ """An organization one submits data to
+ """
+ name = models.CharField(max_length=255)
+ homepage = models.URLField(blank=True)
+ library_template = models.URLField(blank=True)
+
+ class Meta:
+ verbose_name_plural = 'Accession Agencies'
+
+ def __str__(self):
+ return self.name
+
+
+class Accession(models.Model):
+ """Track accession IDs assigned to our objects.
+ """
+ accession = models.CharField(
+ max_length=255,
+ db_index=True,
+ validators=[RegexValidator(
+ "^[-A-Za-z0-9:.]*$",
+ message="Please only use letters, digits, and :.-")]
+ )
+ url = models.URLField(blank=True, null=True)
+ agency = models.ForeignKey(AccessionAgency)
+ created = models.DateTimeField()
+
+ class Meta:
+ abstract = True
+
+ def update_url(self, template):
+ if template and not self.url:
+ self.url = template.format(self.accession)
+
+ def __str__(self):
+ return str(self.agency) + ":" + self.accession
+
+
+class LibraryAccession(Accession):
+ library = models.ForeignKey('Library')
+
+ def save(self, *args, **kwargs):
+ self.update_url(self.agency.library_template)
+ super(LibraryAccession, self).save(*args, **kwargs)
+
+
class Antibody(models.Model):
antigene = models.CharField(max_length=500, db_index=True)
# New field Aug/20/08
undiluted_concentration = '5.01'
hidden = False
library_type = SubFactory(LibraryTypeFactory)
+
+
+class AccessionAgencyFactory(DjangoModelFactory):
+ class Meta:
+ model = models.AccessionAgency
+
+ name = FuzzyText(prefix="agency ")
+ homepage = FuzzyText(prefix="http://", suffix=".example.com")
+ library_template = LazyAttribute(lambda o: "%s/library/{}" % (o.homepage,))
+
+
+class LibraryAccessionFactory(DjangoModelFactory):
+ class Meta:
+ model = models.LibraryAccession
+
+ accession = FuzzyText(prefix="ACC")
+ agency = SubFactory(AccessionAgencyFactory)
import json
from unittest import skipUnless
+from django.core.exceptions import ValidationError
from django.test import TestCase, RequestFactory
from django.utils.encoding import smart_text, smart_str
from .models import Affiliation, ExperimentType, Species, Library
-from .views import library_dict, library_json, library
-from .samples_factory import *
-
+from .views import library_dict
+from .samples_factory import (
+ AffiliationFactory,
+ LibraryAccessionFactory,
+ LibraryFactory,
+ SpeciesFactory,
+)
from htsworkflow.auth import apidata
from htsworkflow.util.conversion import str_or_none
from htsworkflow.util.ethelp import validate_xhtml
HAVE_RDF = False
+class LibraryAccessionTestCase(TestCase):
+ def test_validator(self):
+ library = LibraryFactory()
+ acc = LibraryAccessionFactory(library_id=library.id)
+ acc.clean_fields()
+ accession = acc.accession
+ # test a variety of escape characters one at a time
+ for c in "<>'\"&;":
+ acc.accession = accession + c
+ self.assertRaises(ValidationError, acc.clean_fields)
+
+ def test_library_save_hook(self):
+ library = LibraryFactory()
+ acc = LibraryAccessionFactory(library_id=library.id)
+
+ self.assertEquals(acc.url[:len(acc.agency.homepage)],
+ acc.agency.homepage)
+ self.assertEquals(acc.url[len(acc.agency.homepage):],
+ '/library/'+acc.accession)
+
+ @skipUnless(HAVE_RDF, "No RDF Support")
+ def test_have_accession(self):
+ library = LibraryFactory()
+ acc = LibraryAccessionFactory(library_id=library.id)
+ lib_response = self.client.get(library.get_absolute_url())
+ lib_content = smart_text(lib_response.content)
+
+ model = get_model()
+ load_string_into_model(model, 'rdfa', lib_content)
+
+ body = """prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+ prefix libns: <http://jumpgate.caltech.edu/wiki/LibraryOntology#>
+
+ select ?library ?accession
+ where {
+ ?library libns:accession ?accession
+ }"""
+ query = RDF.SPARQLQuery(body)
+ accessions = []
+ for row in query.execute(model):
+ accessions.append(str(row['accession']))
+ self.assertEqual(len(accessions), 1)
+ self.assertEqual(accessions[0], acc.url)
+
+
class LibraryTestCase(TestCase):
def testOrganism(self):
human = SpeciesFactory(common_name='human')
def suite():
from unittest import TestSuite, defaultTestLoader
suite = TestSuite()
+ suite.addTests(defaultTestLoader.loadTestsFromTestCase(LibraryAccessionTestCase))
suite.addTests(defaultTestLoader.loadTestsFromTestCase(LibraryTestCase))
suite.addTests(defaultTestLoader.loadTestsFromTestCase(SampleWebTestCase))
suite.addTests(defaultTestLoader.loadTestsFromTestCase(TestRDFaLibrary))