Passed
Pull Request — master (#72)
by Paolo
16:34
created

uid.admin   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 282
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 9
eloc 164
dl 0
loc 282
rs 10
c 0
b 0
f 0

8 Methods

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