Completed
Push — master ( 8a2447...e2760f )
by Paolo
06:42
created

uid.admin.SubmissionAdmin.short_message()   A

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 2
rs 10
c 0
b 0
f 0
cc 1
nop 2
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
"""
4
Created on Wed Nov  7 11:54:15 2018
5
6
@author: Paolo Cozzi <[email protected]>
7
"""
8
9
from django import forms
10
from django.contrib import admin
11
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
12
from django.contrib.auth.models import User
13
from django.template.defaultfilters import truncatechars
14
15
from .models import (Animal, DictBreed, DictCountry, DictRole, DictSpecie,
16
                     Ontology, Organization, Person, Publication, Sample,
17
                     Submission, DictSex, DictUberon, DictDevelStage,
18
                     DictPhysioStage)
19
20
21
class DictBreedAdmin(admin.ModelAdmin):
22
    search_fields = ['supplied_breed']
23
    list_per_page = 25
24
    list_display = (
25
        'supplied_breed', 'get_label', 'get_term', 'mapped_breed',
26
        'mapped_breed_term', 'confidence', 'country', 'specie')
27
28
    # override label and term verbose names
29
    def get_label(self, instance):
30
        return instance.label
31
    get_label.short_description = "label"
32
33
    def get_term(self, instance):
34
        return instance.term
35
    get_term.short_description = "term"
36
37
    list_filter = ('country', 'specie')
38
39
40
# inspired from here:
41
# https://github.com/geex-arts/django-jet/issues/244#issuecomment-325001298
42
class SampleInLineFormSet(forms.BaseInlineFormSet):
43
    ''' Base Inline formset for Sample Model'''
44
45
    def __init__(self, *args, **kwargs):
46
        super(SampleInLineFormSet, self).__init__(*args, **kwargs)
47
48
        # Animal will be a Animal object called when editing animal
49
        animal = kwargs["instance"]
50
51
        # get all Sample names from a certain animal with a unique query
52
        # HINT: all problems related to subquery when displaying names arise
53
        # from my __str__s methods, which display Sample and Animal name
54
        # and the relation between table Name. In order to have all sample
55
        # names for each animal, I need a join with three tables
56
        self.queryset = Sample.objects.select_related(
57
            'animal').filter(animal=animal)
58
59
60
class SampleInline(admin.StackedInline):
61
    formset = SampleInLineFormSet
62
63
    fields = (
64
        ('name', 'alternative_id', 'biosample_id'),
65
        ('submission', 'owner', 'status'),
66
        ('description', 'publication'),
67
        ('animal', 'protocol', 'organism_part'),
68
        ('collection_date', 'collection_place', 'collection_place_latitude',
69
         'collection_place_longitude', 'collection_place_accuracy'),
70
        ('developmental_stage',
71
         'physiological_stage', 'animal_age_at_collection',
72
         'animal_age_at_collection_units', 'availability'),
73
        ('storage', 'storage_processing', 'preparation_interval',
74
         'preparation_interval_units'),
75
        'last_submitted',
76
    )
77
78
    # manage a fields with many FK keys
79
    # https://books.agiliq.com/projects/django-admin-cookbook/en/latest/many_fks.html
80
    raw_id_fields = ("animal", "submission", "publication")
81
82
    model = Sample
83
    extra = 0
84
85
86
class SampleAdmin(admin.ModelAdmin):
87
    # exclude = ('author',)
88
    # prepopulated_fields = {'name': ['description']}
89
    search_fields = ['name', 'biosample_id']
90
    list_per_page = 25
91
92
    list_display = (
93
        'name', 'biosample_id', 'submission', 'status', 'last_changed',
94
        'last_submitted', 'alternative_id', 'animal', 'collection_date',
95
        'collection_place', 'collection_place_latitude',
96
        'collection_place_longitude', 'collection_place_accuracy',
97
        'organism_part', 'developmental_stage', 'physiological_stage',
98
        'animal_age_at_collection', 'animal_age_at_collection_units',
99
        'availability', 'storage', 'storage_processing',
100
        'preparation_interval', 'preparation_interval_units',
101
        'description', 'publication', 'owner'
102
        )
103
104
    # To tell Django we want to perform a join instead of fetching the names of
105
    # the categories one by one
106
    # https://medium.com/@hakibenita/things-you-must-know-about-django-admin-as-your-app-gets-bigger-6be0b0ee9614
107
    list_select_related = (
108
        'submission', 'submission__gene_bank_country', 'animal',
109
        'organism_part', 'developmental_stage', 'physiological_stage', 'owner'
110
    )
111
112
    list_filter = ('owner', 'status')
113
114
    fields = (
115
        ('name', 'alternative_id', 'biosample_id'),
116
        ('submission', 'owner', 'status'),
117
        ('description', 'publication'),
118
        ('animal', 'protocol', 'organism_part'),
119
        ('collection_date', 'collection_place', 'collection_place_latitude',
120
         'collection_place_longitude', 'collection_place_accuracy'),
121
        ('developmental_stage',
122
         'physiological_stage', 'animal_age_at_collection',
123
         'animal_age_at_collection_units', 'availability'),
124
        ('storage', 'storage_processing', 'preparation_interval',
125
         'preparation_interval_units'),
126
        'last_submitted',
127
    )
128
129
    # manage a fields with many FK keys
130
    # https://books.agiliq.com/projects/django-admin-cookbook/en/latest/many_fks.html
131
    raw_id_fields = ("animal", "submission", "publication")
132
133
134
class AnimalAdmin(admin.ModelAdmin):
135
    search_fields = ['name', 'biosample_id']
136
137
    list_per_page = 25
138
    list_display = (
139
        'name', 'biosample_id', 'submission', 'status', 'last_changed',
140
        'last_submitted', 'alternative_id', 'breed', 'sex', 'father', 'mother',
141
        'birth_date', 'birth_location', 'birth_location_latitude',
142
        'birth_location_longitude', 'birth_location_accuracy', 'description',
143
        'publication', 'owner'
144
        )
145
146
    list_filter = ('owner', 'status')
147
148
    # I don't want to change this
149
    readonly_fields = ("owner",)
150
151
    fields = (
152
        ('name', 'alternative_id', 'biosample_id'),
153
        ('submission', 'owner', 'status'),
154
        ('description', 'publication'),
155
        ('breed', 'sex'),
156
        ('father', 'mother'),
157
        ('birth_date', 'birth_location'),
158
        ('birth_location_latitude',
159
         'birth_location_longitude', 'birth_location_accuracy'),
160
        'last_submitted',
161
    )
162
163
    # manage a fields with many FK keys
164
    # https://books.agiliq.com/projects/django-admin-cookbook/en/latest/many_fks.html
165
    raw_id_fields = ("father", "mother", "breed", "submission", "publication")
166
167
    # https://medium.com/@hakibenita/things-you-must-know-about-django-admin-as-your-app-gets-bigger-6be0b0ee9614
168
    list_select_related = (
169
        'submission', 'submission__gene_bank_country', 'breed',
170
        'breed__specie', 'breed__country', 'sex', 'father', 'mother', 'owner')
171
172
    inlines = [SampleInline]
173
174
175
class SubmissionAdmin(admin.ModelAdmin):
176
    list_per_page = 25
177
    list_display = (
178
        'title', 'owner', 'short_organization', 'created_at', 'updated_at',
179
        'status', 'gene_bank_name', 'short_country', 'datasource_type',
180
        'datasource_version', 'short_message'
181
    )
182
183
    def short_organization(self, obj):
184
        return truncatechars(obj.organization.name, 30)
185
186
    # rename column in admin
187
    short_organization.short_description = "Organization"
188
189
    def short_country(self, obj):
190
        return obj.gene_bank_country.label
191
192
    # rename column in admin
193
    short_country.short_description = "Gene Bank Country"
194
195
    def short_message(self, obj):
196
        return truncatechars(obj.message, 40)
197
198
    # rename column in admin
199
    short_message.short_description = "Message"
200
201
    # manage a fields with many FK keys
202
    # https://books.agiliq.com/projects/django-admin-cookbook/en/latest/many_fks.html
203
    raw_id_fields = ("gene_bank_country", "organization")
204
205
    # I cannot edit a auto_add_now field
206
    readonly_fields = ('owner', 'created_at', 'updated_at')
207
208
    list_filter = ('owner', 'status')
209
210
211
class PersonAdmin(admin.ModelAdmin):
212
    list_per_page = 25
213
    list_display = (
214
        'user_name', 'full_name', 'initials', 'affiliation', 'role',
215
    )
216
217
    def user_name(self, obj):
218
        return obj.user.username
219
220
    # rename column in admin
221
    user_name.short_description = "User Name"
222
223
    def full_name(self, obj):
224
        return "%s %s" % (obj.user.first_name, obj.user.last_name)
225
226
    full_name.short_description = "Full Name"
227
228
229
# https://simpleisbetterthancomplex.com/tutorial/2016/11/23/how-to-add-user-profile-to-django-admin.html
230
class PersonInLine(admin.StackedInline):
231
    model = Person
232
    can_delete = False
233
    verbose_name_plural = 'Person'
234
    fk_name = 'user'
235
236
237
class UserAdmin(BaseUserAdmin):
238
    inlines = (PersonInLine, )
239
    list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff',
240
                    'get_role')
241
    list_select_related = ('person', )
242
243
    # this will display a column Role in User admin
244
    def get_role(self, instance):
245
        return instance.person.role
246
    get_role.short_description = 'Role'
247
248
    # display the inlines only in the edit form
249
    def get_inline_instances(self, request, obj=None):
250
        if not obj:
251
            return list()
252
        return super(UserAdmin, self).get_inline_instances(request, obj)
253
254
255
class OrganizationAdmin(admin.ModelAdmin):
256
    list_per_page = 25
257
    search_fields = ['name']
258
    list_display = (
259
        'name', 'address', 'country', 'URI', 'role',
260
    )
261
262
263
class OntologyAdmin(admin.ModelAdmin):
264
    list_per_page = 25
265
    search_fields = ['library_name']
266
    list_display = (
267
        'library_name', 'library_uri', 'comment',
268
    )
269
270
271
class DictCountryAdmin(admin.ModelAdmin):
272
    list_per_page = 25
273
    list_display = ('label', 'term', 'confidence')
274
275
276
class DictSpecieAdmin(admin.ModelAdmin):
277
    list_per_page = 25
278
    list_display = (
279
        'label', 'term', 'confidence', 'general_breed_label',
280
        'general_breed_term')
281
282
283
# --- registering applications
284
285
# default admin class
286
admin.site.register(DictRole, admin.ModelAdmin)
287
admin.site.register(DictSex, admin.ModelAdmin)
288
admin.site.register(DictUberon, admin.ModelAdmin)
289
admin.site.register(DictDevelStage, admin.ModelAdmin)
290
admin.site.register(DictPhysioStage, admin.ModelAdmin)
291
292
# Custom admin class
293
admin.site.register(DictSpecie, DictSpecieAdmin)
294
admin.site.register(DictCountry, DictCountryAdmin)
295
admin.site.register(Submission, SubmissionAdmin)
296
admin.site.register(Animal, AnimalAdmin)
297
admin.site.register(Sample, SampleAdmin)
298
# admin.site.register(Name, NameAdmin)
299
admin.site.register(DictBreed, DictBreedAdmin)
300
admin.site.register(Person, PersonAdmin)
301
admin.site.register(Organization, OrganizationAdmin)
302
admin.site.register(Publication, admin.ModelAdmin)
303
admin.site.register(Ontology, OntologyAdmin)
304
305
# Re-register UserAdmin (to see related person data)
306
admin.site.unregister(User)
307
admin.site.register(User, UserAdmin)
308