Commit 0742ddb5 authored by Nicolas Noé's avatar Nicolas Noé
Browse files

Basic expedition/stations models.

parent c7c8680f
from django.contrib import admin
from django import forms
from .models import Specimen, SpecimenLocation, Person, Fixation
from .models import Specimen, SpecimenLocation, Person, Fixation, Station, Expedition
from .widgets import LatLongWidget
......@@ -16,26 +16,36 @@ class MyAdminForm(forms.ModelForm):
}
@admin.register(Specimen)
class SpecimenAdmin(admin.ModelAdmin):
form = MyAdminForm
list_display = ('specimen_id', 'scientific_name', 'identified_by', 'specimen_location', 'depth_str', 'fixation')
list_filter = ('identified_by', 'specimen_location', 'fixation')
list_display = ('specimen_id', 'station', 'scientific_name', 'identified_by', 'specimen_location', 'depth_str', 'fixation')
list_filter = ('identified_by', 'specimen_location', 'fixation', 'station')
search_fields = ['scientific_name', 'specimen_id']
# TODO: document searchable fields in template? (https://stackoverflow.com/questions/11411622/add-help-text-for-search-field-in-admin-py)
@admin.register(SpecimenLocation)
class SpecimenLocationAdmin(admin.ModelAdmin):
pass
@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
pass
@admin.register(Fixation)
class FixationAdmin(admin.ModelAdmin):
pass
admin.site.register(Specimen, SpecimenAdmin)
admin.site.register(SpecimenLocation, SpecimenLocationAdmin)
admin.site.register(Person, PersonAdmin)
admin.site.register(Fixation, FixationAdmin)
@admin.register(Station)
class StationAdmin(admin.ModelAdmin):
pass
@admin.register(Expedition)
class ExpeditionAdmin(admin.ModelAdmin):
pass
admin.site.site_header = 'Astapor administration'
\ No newline at end of file
......@@ -2,12 +2,13 @@ import csv
from psycopg2.extras import NumericRange
from django.core.exceptions import ObjectDoesNotExist
from django.core.management.base import BaseCommand, CommandError
from django.contrib.gis.geos import Point
from specimens.models import Person, SpecimenLocation, Specimen, Fixation
from specimens.models import Person, SpecimenLocation, Specimen, Fixation, Expedition, Station
MODELS_TO_TRUNCATE = [Fixation, Person, SpecimenLocation, Specimen]
MODELS_TO_TRUNCATE = [Station, Expedition, Fixation, Person, SpecimenLocation, Specimen]
# TODO: document use of this script:
# - export Google Sheet (specimens) as CSV (separator: comma)
......@@ -15,6 +16,21 @@ MODELS_TO_TRUNCATE = [Fixation, Person, SpecimenLocation, Specimen]
# - Lat/lon use comma as a separator
def get_or_create_station_and_expedition(station_name, expedition_name):
# Returns a Station object, ready to assign to Specimen.station
"""
:rtype: Station
"""
try: # A station already exists for the correct expedition?
return Station.objects.get(name=station_name, expedition__name=expedition_name)
except ObjectDoesNotExist: # New station, let's create it (with expedition if needed):
expedition, _ = Expedition.objects.get_or_create(name=expedition_name)
station = Station.objects.create(name=station_name, expedition=expedition)
return station
class Command(BaseCommand):
help = 'Initial data import to populate the tables'
......@@ -42,6 +58,8 @@ class Command(BaseCommand):
self.stdout.write('Processing row #{i}...'.format(i=i), ending='')
specimen = Specimen()
specimen.station = get_or_create_station_and_expedition(row['Station'].strip(), row['Expedition'].strip())
# Identificators
identified_by = row['Identified_by'].strip()
id_first_name, id_last_name = identified_by.split()
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-06-16 10:52
# Generated by Django 1.11.2 on 2017-06-20 08:54
from __future__ import unicode_literals
import django.contrib.gis.db.models.fields
......@@ -16,6 +16,13 @@ class Migration(migrations.Migration):
]
operations = [
migrations.CreateModel(
name='Expedition',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
],
),
migrations.CreateModel(
name='Fixation',
fields=[
......@@ -54,11 +61,24 @@ class Migration(migrations.Migration):
('name', models.CharField(max_length=100)),
],
),
migrations.CreateModel(
name='Station',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('expedition', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='specimens.Expedition')),
],
),
migrations.AddField(
model_name='specimen',
name='specimen_location',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='specimens.SpecimenLocation'),
),
migrations.AddField(
model_name='specimen',
name='station',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='specimens.Station'),
),
migrations.AlterUniqueTogether(
name='person',
unique_together=set([('first_name', 'last_name')]),
......
......@@ -24,6 +24,21 @@ class Fixation(models.Model):
def __str__(self):
return self.name
class Expedition(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Station(models.Model):
name = models.CharField(max_length=100)
expedition = models.ForeignKey(Expedition)
# It may be interesting to add a location (point, polygon or line) for the station itself, but for now we keep the
# coordinates as a specimen attribute (when sampling we generally try to set the lat/lon for the specimen as precisely
# as possible, sometimes more than the station)
def __str__(self):
return "{name} (from exp. {exp_name})".format(name=self.name, exp_name=self.expedition)
class Specimen(models.Model):
specimen_id = models.IntegerField(unique=True) # ID from the lab, not Django's PK
scientific_name = models.CharField(max_length=100)
......@@ -33,6 +48,7 @@ class Specimen(models.Model):
specimen_location = models.ForeignKey(SpecimenLocation)
fixation = models.ForeignKey(Fixation, blank=True, null=True)
comment = models.TextField(blank=True, null=True)
station = models.ForeignKey(Station)
def depth_str(self):
if self.depth:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment