Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Belgian Biodiversity Platform
astapor
Commits
0742ddb5
Commit
0742ddb5
authored
Jun 20, 2017
by
Nicolas Noé
Browse files
Basic expedition/stations models.
parent
c7c8680f
Changes
4
Hide whitespace changes
Inline
Side-by-side
website/specimens/admin.py
View file @
0742ddb5
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
website/specimens/management/commands/csv_import.py
View file @
0742ddb5
...
...
@@ -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
()
...
...
website/specimens/migrations/0001_initial.py
View file @
0742ddb5
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-06-
16 10
:5
2
# Generated by Django 1.11.2 on 2017-06-
20 08
:5
4
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'
)]),
...
...
website/specimens/models.py
View file @
0742ddb5
...
...
@@ -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
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment