Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
sensor_tracker
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
6
Issues
6
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
CEOTR Public
sensor_tracker
Commits
3121bd2f
Commit
3121bd2f
authored
Nov 26, 2019
by
xaingling
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update features and fix bug
parent
f67fb2cd
Changes
32
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
868 additions
and
451 deletions
+868
-451
common/admin_common.py
common/admin_common.py
+7
-0
common/model.py
common/model.py
+19
-0
common/tests/__init__.py
common/tests/__init__.py
+0
-0
common/tests/create_mock_sensor_tracker_database.py
common/tests/create_mock_sensor_tracker_database.py
+84
-0
common/utilities.py
common/utilities.py
+7
-1
general/migrations/0003_auto_20191125_1652.py
general/migrations/0003_auto_20191125_1652.py
+38
-0
general/migrations/0004_auto_20191125_1653.py
general/migrations/0004_auto_20191125_1653.py
+18
-0
general/models.py
general/models.py
+11
-15
instruments/admin.py
instruments/admin.py
+27
-123
instruments/migrations/0023_instrumentcomment_event_time.py
instruments/migrations/0023_instrumentcomment_event_time.py
+18
-0
instruments/model_form.py
instruments/model_form.py
+96
-0
instruments/models.py
instruments/models.py
+9
-15
instruments/tests/test_admin.py
instruments/tests/test_admin.py
+51
-0
instruments/tests/test_form.py
instruments/tests/test_form.py
+0
-0
instruments/tests/test_model.py
instruments/tests/test_model.py
+0
-0
platforms/admin.py
platforms/admin.py
+65
-247
platforms/admin_filter.py
platforms/admin_filter.py
+120
-0
platforms/migrations/0012_platformcomment_event_time.py
platforms/migrations/0012_platformcomment_event_time.py
+18
-0
platforms/migrations/0013_platformdeploymentcomment_event_time.py
...s/migrations/0013_platformdeploymentcomment_event_time.py
+18
-0
platforms/model_form.py
platforms/model_form.py
+98
-0
platforms/models.py
platforms/models.py
+28
-44
platforms/tests/__init__.py
platforms/tests/__init__.py
+0
-0
platforms/tests/test_admin.py
platforms/tests/test_admin.py
+0
-0
platforms/tests/test_models.py
platforms/tests/test_models.py
+2
-0
platforms/tests/tests.py
platforms/tests/tests.py
+44
-0
sensor_tracker/templates/admin/custom_instrument_change_form.html
...racker/templates/admin/custom_instrument_change_form.html
+2
-2
sensor_tracker/templates/admin/custom_platform_change_form.html
..._tracker/templates/admin/custom_platform_change_form.html
+18
-0
sensor_tracker/templates/admin/custom_sensor_change_form.html
...or_tracker/templates/admin/custom_sensor_change_form.html
+18
-0
sensor_tracker/templates/admin/instrument_on_platform_info.html
..._tracker/templates/admin/instrument_on_platform_info.html
+2
-2
sensor_tracker/templates/admin/platform_info.html
sensor_tracker/templates/admin/platform_info.html
+24
-0
sensor_tracker/templates/admin/sensor_info.html
sensor_tracker/templates/admin/sensor_info.html
+24
-0
sensor_tracker/templates/admin/sensor_on_instrument_info.html
...or_tracker/templates/admin/sensor_on_instrument_info.html
+2
-2
No files found.
common/admin_common.py
View file @
3121bd2f
...
...
@@ -10,3 +10,10 @@ class CommentBoxAdminBase(admin.ModelAdmin):
instance
.
user
=
request
.
user
formset
.
save
()
class
BaseCommentBoxInline
(
admin
.
TabularInline
):
extra
=
0
readonly_fields
=
(
'user'
,
'created_date'
,
'modified_date'
)
fields
=
(
'user'
,
'created_date'
,
'modified_date'
,
'event_time'
,
'comment'
)
common/model.py
0 → 100644
View file @
3121bd2f
from
django.db
import
models
class
ModelBase
(
models
.
Model
):
class
Meta
:
abstract
=
True
"""
Most of our model has modified date and create date
"""
created_date
=
models
.
DateTimeField
(
auto_now_add
=
True
,
null
=
True
,
blank
=
True
)
modified_date
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
,
blank
=
True
)
class
CommentModelBase
(
ModelBase
):
class
Meta
:
abstract
=
True
event_time
=
models
.
DateTimeField
(
null
=
True
,
blank
=
True
)
common/tests/__init__.py
0 → 100644
View file @
3121bd2f
common/tests/create_mock_sensor_tracker_database.py
0 → 100644
View file @
3121bd2f
import
os
import
json
MOCK_JSON_FILE_NAME
=
"mock_json_data"
JSON_DATA_FILES
=
[
"institution"
,
"manufacturer"
,
"project"
,
"platform_type"
,
"platform"
,
"instrument"
,
"power_type"
,
"deployment"
,
"sensor"
,
"instrument_on_platform"
,
"sensor_on_instrument"
]
def
create_mock_database
():
from
general
import
models
as
general
from
instruments
import
models
as
instruments
from
platforms
import
models
as
platforms
json_dict_list
=
import_json_contents
()
project_json
=
json_dict_list
[
"project"
]
for
x
in
project_json
:
general
.
Project
.
objects
.
create
(
**
filter_out_create_day_modified_day
(
x
))
institution_json
=
json_dict_list
[
"institution"
]
for
x
in
institution_json
:
general
.
Institution
.
objects
.
create
(
**
filter_out_create_day_modified_day
(
x
))
manufacturer_json
=
json_dict_list
[
"manufacturer"
]
for
x
in
manufacturer_json
:
general
.
Manufacturer
.
objects
.
create
(
**
filter_out_create_day_modified_day
(
x
))
platform_type_json
=
json_dict_list
[
"platform_type"
]
for
x
in
platform_type_json
:
platforms
.
PlatformType
.
objects
.
create
(
**
replace_to_id
(
filter_out_create_day_modified_day
(
x
)))
platform_json
=
json_dict_list
[
"platform"
]
for
x
in
platform_json
:
platforms
.
Platform
.
objects
.
create
(
**
replace_to_id
(
filter_out_create_day_modified_day
(
x
)))
instrument_json
=
json_dict_list
[
"instrument"
]
for
x
in
instrument_json
:
instruments
.
Instrument
.
objects
.
create
(
**
replace_to_id
(
filter_out_create_day_modified_day
(
x
)))
power_type_json
=
json_dict_list
[
"power_type"
]
for
x
in
power_type_json
:
platforms
.
PlatformPowerType
.
objects
.
create
(
**
replace_to_id
(
filter_out_create_day_modified_day
(
x
)))
deployment_json
=
json_dict_list
[
"deployment"
]
for
x
in
deployment_json
:
platforms
.
PlatformDeployment
.
objects
.
create
(
**
replace_to_id
(
filter_out_create_day_modified_day
(
x
)))
sensor_json
=
json_dict_list
[
"sensor"
]
for
x
in
sensor_json
:
instruments
.
Sensor
.
objects
.
create
(
**
replace_to_id
(
filter_out_create_day_modified_day
(
x
)))
instrument_on_platform_json
=
json_dict_list
[
"instrument_on_platform"
]
for
x
in
instrument_on_platform_json
:
instruments
.
InstrumentOnPlatform
.
objects
.
create
(
**
replace_to_id
(
filter_out_create_day_modified_day
(
x
)))
sensor_on_instrument_json
=
json_dict_list
[
"sensor_on_instrument"
]
for
x
in
sensor_on_instrument_json
:
instruments
.
SensorOnInstrument
.
objects
.
create
(
**
replace_to_id
(
filter_out_create_day_modified_day
(
x
)))
return
json_dict_list
def
import_json_contents
():
current
=
os
.
path
.
dirname
(
os
.
path
.
realpath
(
__file__
))
json_folder
=
os
.
path
.
join
(
current
,
MOCK_JSON_FILE_NAME
)
json_dict
=
dict
()
for
x
in
JSON_DATA_FILES
:
with
open
(
os
.
path
.
join
(
json_folder
,
"."
.
join
([
x
,
"json"
])))
as
f
:
json_dict
[
x
]
=
json
.
loads
(
f
.
read
())[
"results"
]
return
json_dict
def
filter_out_create_day_modified_day
(
the_dict
):
the_dict
.
pop
(
"the_dict"
,
None
)
the_dict
.
pop
(
"created_date"
,
None
)
the_dict
.
pop
(
"modified_date"
,
None
)
return
the_dict
def
replace_to_id
(
the_dict
):
for
x
in
JSON_DATA_FILES
:
if
x
in
the_dict
:
the_dict
[
x
+
"_id"
]
=
the_dict
.
pop
(
x
)
return
the_dict
common/utilities.py
View file @
3121bd2f
from
django.urls
import
reverse
from
django.db.models
import
Q
from
django.urls
import
get_script_prefix
def
make_edit_link
(
instance
):
...
...
@@ -14,12 +15,17 @@ def make_add_link(instance):
return
link
def
make_server_compatibility_relative_url
(
url
):
the_link
=
get_script_prefix
()[:
-
1
]
+
url
return
the_link
def
qs_time_overlap
(
base_qs
,
start_time
,
end_time
):
if
end_time
:
soi_qs_overlap
=
base_qs
.
filter
(
Q
(
start_time__lte
=
start_time
,
end_time__gte
=
start_time
)
|
Q
(
start_time__lte
=
end_time
,
end_time__gte
=
end_time
))
else
:
soi_qs_overlap
=
base_qs
.
filter
(
Q
(
end_time
=
None
)
|
Q
(
start_time__
l
te
=
start_time
))
soi_qs_overlap
=
base_qs
.
filter
(
Q
(
end_time
=
None
)
|
Q
(
start_time__
g
te
=
start_time
))
return
soi_qs_overlap
general/migrations/0003_auto_20191125_1652.py
0 → 100644
View file @
3121bd2f
# Generated by Django 2.2.6 on 2019-11-25 16:52
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'general'
,
'0002_auto_20190611_1951'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'institution'
,
name
=
'city'
,
field
=
models
.
CharField
(
blank
=
True
,
max_length
=
40
,
null
=
True
),
),
migrations
.
AlterField
(
model_name
=
'institution'
,
name
=
'country'
,
field
=
models
.
CharField
(
blank
=
True
,
max_length
=
80
,
null
=
True
),
),
migrations
.
AlterField
(
model_name
=
'institution'
,
name
=
'postal_code'
,
field
=
models
.
CharField
(
blank
=
True
,
max_length
=
20
,
null
=
True
),
),
migrations
.
AlterField
(
model_name
=
'institution'
,
name
=
'province'
,
field
=
models
.
CharField
(
blank
=
True
,
max_length
=
80
,
null
=
True
),
),
migrations
.
AlterField
(
model_name
=
'institution'
,
name
=
'street'
,
field
=
models
.
TextField
(
blank
=
True
,
max_length
=
255
,
null
=
True
),
),
]
general/migrations/0004_auto_20191125_1653.py
0 → 100644
View file @
3121bd2f
# Generated by Django 2.2.6 on 2019-11-25 16:53
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'general'
,
'0003_auto_20191125_1652'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'institution'
,
name
=
'url'
,
field
=
models
.
CharField
(
blank
=
True
,
help_text
=
"The institution's URL"
,
max_length
=
1000
,
null
=
True
),
),
]
general/models.py
View file @
3121bd2f
from
django.db
import
models
from
common.model
import
ModelBase
class
Institution
(
models
.
Model
):
class
Institution
(
ModelBase
):
# Name of the institution
name
=
models
.
CharField
(
max_length
=
300
,
...
...
@@ -10,38 +11,35 @@ class Institution(models.Model):
# re.match(r'(https?(://)?)?(?P<url>.*)', url)
url
=
models
.
CharField
(
max_length
=
1000
,
help_text
=
"The institution's URL"
help_text
=
"The institution's URL"
,
blank
=
True
,
null
=
True
)
# Location of the institution
street
=
models
.
TextField
(
max_length
=
255
)
city
=
models
.
CharField
(
max_length
=
40
)
province
=
models
.
CharField
(
max_length
=
80
)
postal_code
=
models
.
CharField
(
max_length
=
20
)
country
=
models
.
CharField
(
max_length
=
80
)
street
=
models
.
TextField
(
max_length
=
255
,
blank
=
True
,
null
=
True
)
city
=
models
.
CharField
(
max_length
=
40
,
blank
=
True
,
null
=
True
)
province
=
models
.
CharField
(
max_length
=
80
,
blank
=
True
,
null
=
True
)
postal_code
=
models
.
CharField
(
max_length
=
20
,
blank
=
True
,
null
=
True
)
country
=
models
.
CharField
(
max_length
=
80
,
blank
=
True
,
null
=
True
)
# Contact at the institution
contact_name
=
models
.
CharField
(
max_length
=
70
,
blank
=
True
,
null
=
True
)
contact_phone
=
models
.
CharField
(
max_length
=
15
,
blank
=
True
,
null
=
True
)
contact_email
=
models
.
CharField
(
max_length
=
255
,
blank
=
True
,
null
=
True
)
created_date
=
models
.
DateTimeField
(
auto_now_add
=
True
,
null
=
True
,
blank
=
True
)
modified_date
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
,
blank
=
True
)
def
__str__
(
self
):
return
self
.
name
class
Project
(
models
.
Model
):
class
Project
(
ModelBase
):
name
=
models
.
CharField
(
max_length
=
1000
,
help_text
=
"<b>Example:</b> Collaborative Operations with Mote Marine Laboratory"
)
created_date
=
models
.
DateTimeField
(
auto_now_add
=
True
,
null
=
True
,
blank
=
True
)
modified_date
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
,
blank
=
True
)
def
__str__
(
self
):
return
self
.
name
class
Manufacturer
(
models
.
Model
):
class
Manufacturer
(
ModelBase
):
name
=
models
.
CharField
(
max_length
=
300
)
street
=
models
.
TextField
(
max_length
=
255
,
blank
=
True
,
null
=
True
)
city
=
models
.
CharField
(
max_length
=
40
,
blank
=
True
,
null
=
True
)
...
...
@@ -52,8 +50,6 @@ class Manufacturer(models.Model):
contact_name
=
models
.
CharField
(
max_length
=
70
,
blank
=
True
,
null
=
True
)
contact_phone
=
models
.
CharField
(
max_length
=
15
,
blank
=
True
,
null
=
True
)
contact_email
=
models
.
CharField
(
max_length
=
255
,
blank
=
True
,
null
=
True
)
created_date
=
models
.
DateTimeField
(
auto_now_add
=
True
,
null
=
True
,
blank
=
True
)
modified_date
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
,
blank
=
True
)
def
__str__
(
self
):
return
self
.
name
instruments/admin.py
View file @
3121bd2f
import
warnings
from
django.contrib
import
admin
from
django.forms
import
ModelForm
from
django
import
forms
from
datetime
import
datetime
from
django.db.models
import
Q
from
django.core.exceptions
import
ObjectDoesNotExist
from
instruments.admin_filter
import
(
SensorOnInstrumentPlatformFilter
,
)
from
suit.widgets
import
SuitSplitDateTimeWidget
from
instruments.admin_filter
import
(
InstrumentPlatformNameFilter
,
InstrumentOnPlatformSortFilter
,
...
...
@@ -33,21 +29,16 @@ from .models import (
SensorOnInstrument
,
)
from
platforms.models
import
Platform
from
common.admin_common
import
CommentBoxAdminBase
from
common.utilities
import
make_edit_link
,
make_add_link
from
django.utils.safestring
import
mark_safe
from
common.utilities
import
qs_time_overlap
class
InstrumentOnPlatformForm
(
ModelForm
):
class
Meta
:
model
=
InstrumentOnPlatform
fields
=
'__all__'
widgets
=
{
'start_time'
:
SuitSplitDateTimeWidget
,
'end_time'
:
SuitSplitDateTimeWidget
}
from
instruments.model_form
import
(
InstrumentOnPlatformForm
,
SensorForm
,
InstrumentForm
,
SensorOnInstrumentForm
,
InstrumentCommentBoxForm
)
from
common.admin_common
import
BaseCommentBoxInline
class
InstrumentOnPlatformAdmin
(
admin
.
ModelAdmin
):
...
...
@@ -80,25 +71,6 @@ class InstrumentOnPlatformAdmin(admin.ModelAdmin):
admin
.
site
.
register
(
InstrumentOnPlatform
,
InstrumentOnPlatformAdmin
)
class
SensorForm
(
ModelForm
):
class
Meta
:
model
=
Sensor
fields
=
'__all__'
def
clean
(
self
):
cleaned_data
=
super
()
.
clean
()
include_in_output
=
cleaned_data
.
get
(
"include_in_output"
)
long_name
=
cleaned_data
.
get
(
"long_name"
)
if
include_in_output
and
not
long_name
:
# Only do something if both fields are valid so far.
raise
forms
.
ValidationError
(
"Long name must be given when included in output checked"
)
return
self
.
cleaned_data
@
admin
.
register
(
Sensor
)
class
SensorAdmin
(
admin
.
ModelAdmin
):
form
=
SensorForm
...
...
@@ -111,6 +83,23 @@ class SensorAdmin(admin.ModelAdmin):
SensorPlatformNameFilter
,
SensorInstrumentIdentifierFilter
,
)
change_form_template
=
'admin/custom_sensor_change_form.html'
def
change_view
(
self
,
request
,
object_id
,
form_url
=
''
,
extra_context
=
None
):
sensor_obj
=
Sensor
.
objects
.
get
(
id
=
int
(
object_id
))
instrument_on_platform_qs
=
SensorOnInstrument
.
objects
.
filter
(
sensor
=
sensor_obj
)
.
order_by
(
'start_time'
)
.
prefetch_related
(
'instrument'
)
.
prefetch_related
(
'sensor'
)
objs
=
list
(
instrument_on_platform_qs
)
for
obj
in
objs
:
obj
.
url_edit_link
=
make_edit_link
(
obj
)
obj
.
url_sensor_change
=
make_edit_link
(
obj
.
sensor
)
sensor_on_instrument_add_link
=
make_add_link
(
SensorOnInstrument
)
extra_context
=
{
"extra_content"
:
objs
,
"sensor_on_instrument_add_link"
:
sensor_on_instrument_add_link
,
}
return
super
()
.
change_view
(
request
,
object_id
,
form_url
=
''
,
extra_context
=
extra_context
)
def
delete_queryset
(
self
,
request
,
queryset
):
super
()
.
delete_queryset
(
request
,
queryset
)
...
...
@@ -150,46 +139,6 @@ class SensorAdmin(admin.ModelAdmin):
super
()
.
save_model
(
request
,
obj
,
form
,
change
)
class
InstrumentForm
(
ModelForm
):
class
Meta
:
model
=
Instrument
fields
=
'__all__'
class
PlatformForm
(
ModelForm
):
class
Meta
:
model
=
Platform
fields
=
'__all__'
class
PlatformInline
(
admin
.
StackedInline
):
model
=
InstrumentOnPlatform
exclude
=
[
"comment"
]
readonly_fields
=
[
"platform"
,
"start_time"
,
"end_time"
]
def
get_queryset
(
self
,
request
):
qs
=
super
()
.
get_queryset
(
request
)
qs
=
qs
.
prefetch_related
(
'instrument'
)
.
prefetch_related
(
'platform'
)
return
qs
def
has_add_permission
(
self
,
request
,
obj
=
None
):
return
False
def
has_delete_permission
(
self
,
request
,
obj
=
None
):
return
False
class
InstrumentOnPlatformDisplayItem
:
def
__init__
(
self
,
instance
):
self
.
instrument_on_platform_instance
=
instance
class
SensorOnInstrumentInline
(
admin
.
StackedInline
):
model
=
Sensor
min_num
=
0
@
admin
.
register
(
Instrument
)
class
InstrumentAdmin
(
admin
.
ModelAdmin
):
readonly_fields
=
(
'created_date'
,
'modified_date'
)
...
...
@@ -200,7 +149,7 @@ class InstrumentAdmin(admin.ModelAdmin):
search_fields
=
[
'identifier'
,
'short_name'
,
'long_name'
,
'serial'
,
'manufacturer__name'
]
list_display
=
(
'identifier'
,
'short_name'
,
'long_name'
,
'serial'
,
'manufacturer'
,
'created_date'
,
'modified_date'
)
form
=
InstrumentForm
change_form_template
=
'admin/custom_change_form.html'
change_form_template
=
'admin/custom_
instrument_
change_form.html'
list_per_page
=
40
def
get_queryset
(
self
,
request
):
...
...
@@ -235,41 +184,6 @@ class InstrumentAdmin(admin.ModelAdmin):
return
super
()
.
change_view
(
request
,
object_id
,
form_url
=
''
,
extra_context
=
extra_context
)
class
SensorOnInstrumentForm
(
ModelForm
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
*
args
,
**
kwargs
)
if
self
.
initial
:
self
.
fields
[
'sensor'
]
.
disabled
=
True
self
.
fields
[
'instrument'
]
.
disabled
=
True
class
Meta
:
model
=
SensorOnInstrument
fields
=
'__all__'
def
clean
(
self
):
cleaned_data
=
super
()
.
clean
()
instrument
=
cleaned_data
.
get
(
"instrument"
)
sensor
=
cleaned_data
.
get
(
"sensor"
)
start_time
=
cleaned_data
.
get
(
"start_time"
)
end_time
=
cleaned_data
.
get
(
"end_time"
)
base_soi_qs
=
SensorOnInstrument
.
objects
.
filter
(
instrument
=
instrument
,
sensor
=
sensor
)
soi_qs_overlap
=
qs_time_overlap
(
base_soi_qs
,
start_time
,
end_time
)
soi_qs_overlap_count
=
soi_qs_overlap
.
count
()
if
soi_qs_overlap_count
!=
0
:
msg
=
"You can't save this table since it overlap with
\n
"
for
soi
in
soi_qs_overlap
:
msg
=
msg
+
"{} {} {}
\n
"
.
format
(
soi
.
instrument
.
identifier
,
soi
.
sensor
.
identifier
,
"<a href=
\"
{}
\"
>sensor_on_instrument</a>"
.
format
(
make_edit_link
(
soi
)))
raise
forms
.
ValidationError
(
mark_safe
(
msg
)
)
return
self
.
cleaned_data
@
admin
.
register
(
SensorOnInstrument
)
class
SensorOnInstrumentAdmin
(
admin
.
ModelAdmin
):
list_display
=
(
'sensor'
,
'instrument'
,
'start_time'
,
'end_time'
)
...
...
@@ -306,18 +220,8 @@ class SensorOnInstrumentAdmin(admin.ModelAdmin):
super
()
.
save_model
(
request
,
obj
,
form
,
change
)
class
InstrumentCommentBoxInline
(
admin
.
Tabular
Inline
):
class
InstrumentCommentBoxInline
(
BaseCommentBox
Inline
):
model
=
InstrumentComment
extra
=
0
readonly_fields
=
(
'user'
,
'created_date'
,
'modified_date'
)
fields
=
(
'user'
,
'created_date'
,
'modified_date'
,
'comment'
)
class
InstrumentCommentBoxForm
(
ModelForm
):
class
Meta
:
model
=
InstrumentCommentBox
fields
=
(
'instrument'
,)
class
InstrumentCommentBoxAdmin
(
CommentBoxAdminBase
):
...
...
instruments/migrations/0023_instrumentcomment_event_time.py
0 → 100644
View file @
3121bd2f
# Generated by Django 2.2.6 on 2019-11-26 15:24
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'instruments'
,
'0022_auto_20191121_1054'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'instrumentcomment'
,
name
=
'event_time'
,
field
=
models
.
DateTimeField
(
blank
=
True
,
null
=
True
),
),
]
instruments/model_form.py
0 → 100644
View file @
3121bd2f
from
django.forms
import
ModelForm
from
django
import
forms
from
django.db.models
import
Q
from
suit.widgets
import
SuitSplitDateTimeWidget
from
.models
import
(
Instrument
,
InstrumentOnPlatform
,
Sensor
,
SensorOnInstrument
,
InstrumentCommentBox
)
from
common.utilities
import
make_edit_link
from
django.utils.safestring
import
mark_safe
from
common.utilities
import
qs_time_overlap
class
InstrumentOnPlatformForm
(
ModelForm
):
class
Meta
:
model
=
InstrumentOnPlatform
fields
=
'__all__'
widgets
=
{
'start_time'
:
SuitSplitDateTimeWidget
,
'end_time'
:
SuitSplitDateTimeWidget
}
class
SensorForm
(
ModelForm
):
class
Meta
:
model
=
Sensor
fields
=
'__all__'
def
clean
(
self
):
cleaned_data
=
super
()
.
clean
()
include_in_output
=
cleaned_data
.
get
(
"include_in_output"
)
long_name
=
cleaned_data
.
get
(
"long_name"
)
if
include_in_output
and
not
long_name
:
# Only do something if both fields are valid so far.
raise
forms
.
ValidationError
(
"Long name must be given when included in output checked"
)
return
self
.
cleaned_data
class
InstrumentForm
(
ModelForm
):
class
Meta
:
model
=
Instrument
fields
=
'__all__'
class
SensorOnInstrumentForm
(
ModelForm
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
*
args
,
**
kwargs
)
if
self
.
initial
:
self
.
fields
[
'sensor'
]
.
disabled
=
True
self
.
fields
[
'instrument'
]
.
disabled
=
True
class
Meta
:
model
=
SensorOnInstrument
fields
=
'__all__'
def
clean
(
self
):
cleaned_data
=
super
()
.
clean
()
instrument
=
cleaned_data
.
get
(
"instrument"
)
sensor
=
cleaned_data
.
get
(
"sensor"
)
start_time
=
cleaned_data
.
get
(
"start_time"
)
end_time
=
cleaned_data
.
get
(
"end_time"
)
base_soi_qs
=
SensorOnInstrument
.
objects
.
filter
(
instrument
=
instrument
,
sensor
=
sensor
)
self_instance
=
self
.
instance
soi_qs_overlap
=
qs_time_overlap
(
base_soi_qs
,
start_time
,
end_time
)
the_id
=
self_instance
.
id
if
the_id
:
soi_qs_overlap
=
soi_qs_overlap
.
filter
(
~
Q
(
pk
=
the_id
))
soi_qs_overlap_count
=
soi_qs_overlap
.
count
()
if
soi_qs_overlap_count
!=
0
:
msg
=
"You can't save this table since it overlap with
\n
"
for
soi
in
soi_qs_overlap
:
msg
=
msg
+
"{} {} {}
\n
"
.
format
(
soi
.
instrument
.
identifier
,
soi
.
sensor
.
identifier
,
"<a href=
\"
{}
\"
>sensor_on_instrument</a>"
.
format
(
make_edit_link
(
soi
)))
raise
forms
.
ValidationError
(
mark_safe
(
msg
)
)
return
self
.
cleaned_data
class
InstrumentCommentBoxForm
(
ModelForm
):
class
Meta
:
model
=
InstrumentCommentBox
fields
=
(
'instrument'
,)
instruments/models.py
View file @
3121bd2f
from
django.db
import
models
from
django.contrib.auth.admin
import
User
from
common.model
import
CommentModelBase
,
ModelBase
class
Instrument
(
models
.
Model
):
class
Instrument
(
ModelBase
):
identifier
=
models
.
CharField
(
max_length
=
300
,
help_text
=
"The name used to identify this instrument in the raw data. IE: SATCTD7229, sci_water"
...
...
@@ -35,8 +36,6 @@ class Instrument(models.Model):
blank
=
True
,
help_text
=
"This is a good place to document anything unusual about this instrument's configuration"
)
created_date
=
models
.
DateTimeField
(
auto_now_add
=
True
,
null
=
True
,
blank
=
True
)
modified_date
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
,
blank
=
True
)
def
__str__
(
self
):
return_string
=
'
%
s -
%
s'
%
(
self
.
identifier
,
self
.
short_name
)
...
...
@@ -52,27 +51,27 @@ class InstrumentCommentBox(models.Model):
class
Meta
:
verbose_name
=
'Instrument Comment Box'
verbose_name_plural
=
'Instrument Comment Boxes'
instrument
=
models
.
OneToOneField
(
'Instrument'
,
on_delete
=
models
.
PROTECT
)
def
__str__
(
self
):
return
"
%
s comment box"
%
(
self
.
instrument
)
class
InstrumentComment
(
models
.
Model
):
class
InstrumentComment
(
CommentModelBase
):
user
=
models
.
ForeignKey
(
User
,
on_delete
=
models
.
PROTECT
)
comment
=
models
.
TextField
(
help_text
=
"Comments"
)
created_date
=
models
.
DateTimeField
(
auto_now_add
=
True
,
null
=
True
,
blank
=
True
)
instrument_comment_box
=
models
.
ForeignKey
(
InstrumentCommentBox
,
on_delete
=
models
.
CASCADE
)
modified_date
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
,
blank
=
True
)
def
__str__
(
self
):
return
"
%
s"
%
(
self
.
id
)
class
InstrumentOnPlatform
(
models
.
Model
):
class
InstrumentOnPlatform
(
ModelBase
):
class
Meta
:
verbose_name
=
'Instrument on Platform History'
verbose_name_plural
=
'Instrument on Platform History'
instrument
=
models
.
ForeignKey
(
Instrument
,
help_text
=
"The instrument that was put on a platform"
,
...
...
@@ -94,14 +93,12 @@ class InstrumentOnPlatform(models.Model):
help_text
=
"The date the instrument was removed from the platform"
)
comment
=
models
.
TextField
(
null
=
True
,
blank
=
True
)
created_date
=
models
.
DateTimeField
(
auto_now_add
=
True
,
null
=
True
,
blank
=
True
)
modified_date
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
,
blank
=
True
)
def
__str__
(
self
):
return
"
%
s -
%
s -
%
s"
%
(
self
.
instrument
,
self
.
platform
,
self
.
start_time
)
class
Sensor
(
models
.
Model
):
class
Sensor
(
ModelBase
):
identifier
=
models
.
CharField
(
max_length
=
300
,
help_text
=
"The name used to identify this sensor in the raw data. ie: sci_water_temp"
...
...
@@ -190,17 +187,16 @@ class Sensor(models.Model):
blank
=
True
,
help_text
=
"This is a good place to document anything unusual about this particular sensor. IE: wavelengths for spectral sensors"
)
created_date
=
models
.
DateTimeField
(
auto_now_add
=
True
,
null
=
True
,
blank
=
True
)
modified_date
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
,
blank
=
True
)
def
__str__
(
self
):
return
"
%
s"
%
(
self
.
identifier
)
class
SensorOnInstrument
(
models
.
Model
):
class
SensorOnInstrument
(
ModelBase
):
class
Meta
:
verbose_name
=
'Sensor on Instrument History'
verbose_name_plural
=
'Sensor on Instrument History'
instrument
=
models
.
ForeignKey
(
Instrument
,
help_text
=
"The instrument that was put on a platform"
,
...
...
@@ -222,8 +218,6 @@ class SensorOnInstrument(models.Model):
help_text
=
"The date the instrument was removed from the platform"
)
comment
=
models
.
TextField
(
null
=
True
,
blank
=
True
)
created_date
=
models
.
DateTimeField
(
auto_now_add
=
True
,
null
=
True
,
blank
=
True
)
modified_date
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
,
blank
=
True
)
def
__str__
(
self
):
return
"
%
s -
%
s -
%
s"
%
(
self
.
sensor
,
self
.
instrument
,
self
.
start_time
)
instruments/tests/test_admin.py
0 → 100644
View file @
3121bd2f
from
django.contrib.admin.sites
import
AdminSite
from
django.test
import
SimpleTestCase
,
TestCase
from
django.test.utils
import
isolate_apps
from
datetime
import
datetime
from
instruments.admin
import
SensorOnInstrumentAdmin
from
instruments.models
import
Instrument
,
SensorOnInstrument
,
Sensor
,
InstrumentOnPlatform
,
InstrumentComment
,
\
InstrumentCommentBox
from
instruments.tests.create_mock_sensor_tracker_database
import
create_mock_database
from
instruments.admin
import
SensorOnInstrumentForm
class
InstrumentAdminTests
(
TestCase
):
def
setUp
(
self
):
create_mock_database
()
self
.
site
=
AdminSite
()
def
test_create_sensor_on_instrument
(
self
):
now
=
datetime
.
now
()