Django backoffice config

Version 4 (Etienne Pallier, 03/24/2016 04:02 pm)

1 2 Etienne Pallier
h1. CONFIGURATION of the Django Back Office (administration interface)
2 1 Etienne Pallier
3 1 Etienne Pallier
4 3 Etienne Pallier
{{>toc}}
5 3 Etienne Pallier
6 3 Etienne Pallier
7 1 Etienne Pallier
---
8 1 Etienne Pallier
9 1 Etienne Pallier
h3. Back Office setup
10 1 Etienne Pallier
11 1 Etienne Pallier
 * Prerequisites in src/pyros/settings.py :
12 1 Etienne Pallier
13 1 Etienne Pallier
    * INSTALLED_APPS must (at least) contain :
14 1 Etienne Pallier
15 1 Etienne Pallier
        * django.contrib.admin
16 1 Etienne Pallier
        * django.contrib.auth
17 1 Etienne Pallier
        * django.contrib.contenttypes
18 1 Etienne Pallier
        * django.contrib.sessions
19 1 Etienne Pallier
20 4 Etienne Pallier
    * MIDDLEWARE_CLASSES must (at least) contain :
21 1 Etienne Pallier
22 1 Etienne Pallier
        * django.contrib.sessions.middleware.SessionMiddleware
23 1 Etienne Pallier
        * django.middleware.common.CommonMiddleware
24 1 Etienne Pallier
        * django.contrib.auth.middleware.AuthenticationMiddleware
25 1 Etienne Pallier
26 1 Etienne Pallier
 * At least one 'python manage.py migrate' must have been executed
27 1 Etienne Pallier
28 1 Etienne Pallier
 * Create a superuser for the administration :
29 1 Etienne Pallier
30 1 Etienne Pallier
<pre>
31 1 Etienne Pallier
$ python manage.py createsuperuser
32 1 Etienne Pallier
</pre>
33 1 Etienne Pallier
34 1 Etienne Pallier
* For each app of the project, fill the admin.py file :
35 1 Etienne Pallier
36 1 Etienne Pallier
<pre>
37 1 Etienne Pallier
from django.contrib import admin
38 1 Etienne Pallier
from app.models import Model1, Model2
39 1 Etienne Pallier
40 1 Etienne Pallier
admin.site.register(Model1)
41 1 Etienne Pallier
admin.site.register(Model2)
42 1 Etienne Pallier
</pre>
43 1 Etienne Pallier
44 1 Etienne Pallier
*Reminder* : each application must be registered in the settings.py INSTALLED_APPS variable.
45 1 Etienne Pallier
46 1 Etienne Pallier
* For each model in models.py, add a '__str__()' method in order to identify the object on the back office. Example :
47 1 Etienne Pallier
48 1 Etienne Pallier
<pre>
49 1 Etienne Pallier
class UserLevel(models.Model):
50 1 Etienne Pallier
    name = models.CharField(max_length=45, blank=True, null=True)
51 1 Etienne Pallier
    desc = models.TextField(blank=True, null=True)
52 1 Etienne Pallier
    priority = models.IntegerField(blank=True, null=True)
53 1 Etienne Pallier
    quota = models.FloatField(blank=True, null=True)
54 1 Etienne Pallier
55 1 Etienne Pallier
    class Meta:
56 1 Etienne Pallier
        managed = True
57 1 Etienne Pallier
        db_table = 'userlevel'
58 1 Etienne Pallier
59 1 Etienne Pallier
    def __str__(self):
60 1 Etienne Pallier
        return (str(self.name))
61 1 Etienne Pallier
</pre>
62 1 Etienne Pallier
63 1 Etienne Pallier
*Naming convention* : Use self.name when possible, the creation time/date otherwise. Example :
64 1 Etienne Pallier
65 1 Etienne Pallier
<pre>
66 1 Etienne Pallier
class SiteWatch(models.Model):
67 1 Etienne Pallier
    updated = models.DateTimeField(blank=True, null=True)
68 1 Etienne Pallier
    lights = models.CharField(max_length=45, blank=True, null=True)
69 1 Etienne Pallier
    dome = models.CharField(max_length=45, blank=True, null=True)
70 1 Etienne Pallier
    doors = models.CharField(max_length=45, blank=True, null=True)
71 1 Etienne Pallier
    temperature = models.FloatField(blank=True, null=True)
72 1 Etienne Pallier
73 1 Etienne Pallier
    class Meta:
74 1 Etienne Pallier
        managed = True
75 1 Etienne Pallier
        db_table = 'sitewatch'
76 1 Etienne Pallier
77 1 Etienne Pallier
    def __str__(self):
78 1 Etienne Pallier
        return (str(self.updated))
79 1 Etienne Pallier
</pre>
80 1 Etienne Pallier
81 1 Etienne Pallier
---
82 1 Etienne Pallier
83 1 Etienne Pallier
h3. Adaptation of the one-to-many and many-to-many display
84 1 Etienne Pallier
85 1 Etienne Pallier
* The one-to-many relationships are the following (One.many format) :
86 1 Etienne Pallier
87 1 Etienne Pallier
    * Schedule.sequences
88 1 Etienne Pallier
    * Request.sequences
89 1 Etienne Pallier
    * Sequence.albums
90 1 Etienne Pallier
    * Album.plans
91 1 Etienne Pallier
    * Plan.images
92 1 Etienne Pallier
    * Telescope.detectors
93 1 Etienne Pallier
    * Detector.filters
94 1 Etienne Pallier
    * NrtAnalysis.images
95 1 Etienne Pallier
    * Filter.plans
96 1 Etienne Pallier
    * Detector.albums
97 1 Etienne Pallier
    * UserLevel.users
98 1 Etienne Pallier
    * Country.users
99 1 Etienne Pallier
    * ScientificProgram.requests
100 1 Etienne Pallier
    * User.requests
101 1 Etienne Pallier
    * StrategyObs.alerts
102 1 Etienne Pallier
    * SequenceType.sequences
103 1 Etienne Pallier
104 1 Etienne Pallier
* For each "many", create a new class in admin.py just after the imports, following these examples :
105 1 Etienne Pallier
106 1 Etienne Pallier
<pre>
107 1 Etienne Pallier
108 1 Etienne Pallier
For Schedule.sequences, Request.sequences and Sequentype.sequences, we will need :
109 1 Etienne Pallier
110 1 Etienne Pallier
class SequenceInline(admin.TabularInline):
111 1 Etienne Pallier
    model = Sequence
112 1 Etienne Pallier
    fields = ("name",)
113 1 Etienne Pallier
    show_change_link = True
114 1 Etienne Pallier
115 1 Etienne Pallier
116 1 Etienne Pallier
For Sequence.albums and Detector.albums, we will need :
117 1 Etienne Pallier
118 1 Etienne Pallier
class AlbumInline(admin.TabularInline):
119 1 Etienne Pallier
    model = Album
120 1 Etienne Pallier
    fields = ("name",)
121 1 Etienne Pallier
    show_change_link = True
122 1 Etienne Pallier
123 1 Etienne Pallier
124 1 Etienne Pallier
For StrategyObs.alerts, we will need :
125 1 Etienne Pallier
126 1 Etienne Pallier
class AlertInline(admin.TabularInline):
127 1 Etienne Pallier
    model = Alert
128 1 Etienne Pallier
    fields = ("request.name",) # there is no 'name' attribute in the Alert model
129 1 Etienne Pallier
    show_change_link = True
130 1 Etienne Pallier
131 1 Etienne Pallier
</pre>
132 1 Etienne Pallier
133 1 Etienne Pallier
* For each "One", declare a new class in admin.py, just after the "Inlines" class declaration, as done in the following examples :
134 1 Etienne Pallier
135 1 Etienne Pallier
<pre>
136 1 Etienne Pallier
For Request.sequences :
137 1 Etienne Pallier
138 1 Etienne Pallier
class RequestAdmin(admin.ModelAdmin):
139 1 Etienne Pallier
    inlines = [
140 1 Etienne Pallier
	SequenceInline,
141 1 Etienne Pallier
    ]
142 1 Etienne Pallier
143 1 Etienne Pallier
For Detector.filters and Detector.albums :
144 1 Etienne Pallier
145 1 Etienne Pallier
class DetectorAdmin(admin.ModelAdmin):
146 1 Etienne Pallier
    inlines = [
147 1 Etienne Pallier
	FilterInline,
148 1 Etienne Pallier
        AlbumInline,
149 1 Etienne Pallier
    ]
150 1 Etienne Pallier
151 1 Etienne Pallier
</pre>
152 1 Etienne Pallier
153 1 Etienne Pallier
154 1 Etienne Pallier
* The many-to-many relationships are the following :
155 1 Etienne Pallier
156 1 Etienne Pallier
    * ScientificProgram - User
157 1 Etienne Pallier
    * ScheduleHistory - Sequence
158 1 Etienne Pallier
159 1 Etienne Pallier
* For each many-to-many relationship, declare a new "Inline" class in admin.py just after the imports, like this :
160 1 Etienne Pallier
161 1 Etienne Pallier
<pre>
162 1 Etienne Pallier
For ScientificProgram - User :
163 1 Etienne Pallier
164 1 Etienne Pallier
class UserAndSPInline(admin.TabularInline):
165 1 Etienne Pallier
    model = ScientificProgram.users.through
166 1 Etienne Pallier
167 1 Etienne Pallier
168 1 Etienne Pallier
For ScheduleHistory - Sequence
169 1 Etienne Pallier
170 1 Etienne Pallier
class SequenceAndSHInline(admin.TabularInline):
171 1 Etienne Pallier
    model = ScheduleHistory.sequences.through
172 1 Etienne Pallier
173 1 Etienne Pallier
</pre>
174 1 Etienne Pallier
175 1 Etienne Pallier
+Note :+ The order in the line "model = ScientificProgram.users.through" is very important : the first model (ScientificProgram) is the one in which is declared the ManyToManyField relationship.
176 1 Etienne Pallier
177 1 Etienne Pallier
* For each many-to-many relationship, declare two new classes in admin.py, just after the inlines, like in the following examples :
178 1 Etienne Pallier
179 1 Etienne Pallier
<pre>
180 1 Etienne Pallier
For the ScheduleHistory - Sequence relationship :
181 1 Etienne Pallier
182 1 Etienne Pallier
class ScheduleHistoryAdmin(admin.ModelAdmin):
183 1 Etienne Pallier
    inlines = [
184 1 Etienne Pallier
        SequenceAndSHInline,
185 1 Etienne Pallier
    ]
186 1 Etienne Pallier
    exclude = ('sequences',) # ScheduleHistory declares the ManyToManyField, and we want to replace its display in the back office, so we won't display the default field
187 1 Etienne Pallier
188 1 Etienne Pallier
class SequenceAdmin(admin.ModelAdmin):
189 1 Etienne Pallier
    inlines = [
190 1 Etienne Pallier
        AlbumInline,        # This is the Inline for the one-to-many relationship Sequence.albums
191 1 Etienne Pallier
        SequenceAndSHInline,                                                                
192 1 Etienne Pallier
    ]
193 1 Etienne Pallier
194 1 Etienne Pallier
For the ScientificProgram - User relationship :
195 1 Etienne Pallier
196 1 Etienne Pallier
class ScientificProgramAdmin(admin.ModelAdmin):
197 1 Etienne Pallier
    inlines = [
198 1 Etienne Pallier
        RequestInline,
199 1 Etienne Pallier
	UserAndSPInline,                                                                         
200 1 Etienne Pallier
    ]
201 1 Etienne Pallier
    exclude = ('users',) # Same as ScheduleHistory                                                                         
202 1 Etienne Pallier
203 1 Etienne Pallier
class UserAdmin(admin.ModelAdmin):
204 1 Etienne Pallier
    inlines = [
205 1 Etienne Pallier
	RequestInline,   # This is the Inline for the one-to-many relationship User.requests
206 1 Etienne Pallier
        UserAndSPInline,                                                                    
207 1 Etienne Pallier
    ]
208 1 Etienne Pallier
209 1 Etienne Pallier
</pre>
210 1 Etienne Pallier
211 1 Etienne Pallier
* For each ModelAdmin class in the admin.py, change the registering line
212 1 Etienne Pallier
213 1 Etienne Pallier
<pre>
214 1 Etienne Pallier
admin.site.register(Album)
215 1 Etienne Pallier
</pre>
216 1 Etienne Pallier
217 1 Etienne Pallier
to
218 1 Etienne Pallier
219 1 Etienne Pallier
<pre>
220 1 Etienne Pallier
admin.site.register(Album, AlbumAdmin)
221 1 Etienne Pallier
</pre>