|
9 | 9 | - [Security](#security) |
10 | 10 | - [Deployments](#deployments) |
11 | 11 | - [Authentication](#authentication) |
12 | | -- [Autherization](#authorization) |
13 | | -- [Views](#views) |
14 | | -- [Urls](#urls) |
| 12 | +- [Authorization](#authorization) |
15 | 13 |
|
16 | 14 | ## Designing Models |
17 | 15 |
|
|
143 | 141 |
|
144 | 142 | - Do not use `null=True` or `blank=True` for `BooleanField`. It is better to specify default values for such fields. If you realise that the field can remain empty, you need `NullBooleanField`. |
145 | 143 |
|
| 144 | +- [`Class Meta`](https://docs.djangoproject.com/en/3.0/ref/models/options/) can be used to set default order of a list of objects. E.g. if you want to list all players in alphabetical order this is how you do it: |
| 145 | + |
| 146 | + ```python |
| 147 | + class Player(models.Model): |
| 148 | + name = models.CharField(max_length=100) |
| 149 | + |
| 150 | + class Meta: |
| 151 | + ordering = ['-name'] |
| 152 | + ``` |
| 153 | + |
| 154 | + Now `Player.objects.all()` will return queryset of players in an alphabetical order but [ordering is expensive](https://docs.djangoproject.com/en/3.0/topics/db/optimization/#don-t-order-results-if-you-don-t-care) so you should not use it when you don't need it. |
| 155 | + |
| 156 | + You might want to add an index to your database which may help to improve ordering performance: |
| 157 | + |
| 158 | + ```python |
| 159 | + class Player(models.Model): |
| 160 | + name = models.CharField(max_length=100) |
| 161 | + |
| 162 | + class Meta: |
| 163 | + indexes = [models.Index(fields=['name'])] |
| 164 | + ordering = ['-name'] |
| 165 | + ``` |
| 166 | + |
146 | 167 | ## Caching |
147 | 168 |
|
148 | 169 | - ToDo |
149 | 170 |
|
150 | 171 | ## Database optimization |
151 | 172 |
|
152 | | -- ToDo |
| 173 | +- Use `QuerySet.explain()` to understand how specific QuerySets are executed by your database. Also checkout [django-debug-toolbar](https://github.com/jazzband/django-debug-toolbar/) |
| 174 | + |
| 175 | +- Use indexes to fields that you frequently query by using `filter()`, `exclude()`, `order_by` etc. |
| 176 | + |
| 177 | +- Use indexed field to query: |
| 178 | + |
| 179 | + ```python |
| 180 | + # Faster |
| 181 | + player = Player.objects.get(id=10) |
| 182 | + |
| 183 | + # Slower. Assuming the name field is not indexed. |
| 184 | + player = Player.objects.get(name='Krishna') |
| 185 | + ``` |
| 186 | + |
| 187 | +- Do not perform operations on all the objects all the time, use `filter()` and `exclude()` when needed. |
| 188 | + |
| 189 | +- [Use iterator](https://docs.djangoproject.com/en/3.0/ref/models/querysets/#iterator) when dealing with `QuerySet` with large amount of data that you only need to access once. |
| 190 | + |
| 191 | +- Use [`F expression`](https://docs.djangoproject.com/en/3.0/ref/models/expressions/#f-expressions) to update fields in the same model. |
| 192 | + |
| 193 | + ```python |
| 194 | + # Don't |
| 195 | + for player in Player.objects.all(): |
| 196 | + player.rating += 1 |
| 197 | + player.save() |
| 198 | + |
| 199 | + # Do |
| 200 | + Entry.objects.update(rating=F('rating') + 1) |
| 201 | + ``` |
153 | 202 |
|
154 | 203 | ## Security |
155 | 204 |
|
|
162 | 211 | ## Authentication |
163 | 212 |
|
164 | 213 | - ToDo |
| 214 | + |
| 215 | +## Authorization |
| 216 | + |
| 217 | +- ToDo |
0 commit comments