| 1 | = CookBook - preload_related() = |
| 2 | |
| 3 | Django's !ManyToMany fields aren't sufficient when you need to provide additional data for the relation. Querying related objects can easily lead to dozens of SQL queries for just simple operations, and Django's select_related(True) doesn't help in this case. |
| 4 | |
| 5 | {{{preload_related()}}} is a utility function which retrieves related objects for a list of objects already in memory. Here is a simplified example: |
| 6 | |
| 7 | {{{ |
| 8 | >>> users = User.objects.filter(username__startswith='a') |
| 9 | >>> preload_related(users, |
| 10 | ... User, |
| 11 | ... (UserProperty.objects, Property.objects, 'properties'), |
| 12 | ... (UserAlias.objects , Alias.objects , 'aliases' )) |
| 13 | >>> users[0].properties |
| 14 | [<a list containing Property objects>] |
| 15 | >>> users[0].aliases |
| 16 | [<a list containing Alias objects>] |
| 17 | }}} |
| 18 | |
| 19 | {{{UserProperty}}} and {{{UserAlias}}} are the models creating many-to-many relations between the {{{User}}} model and the {{{Property}}} and {{{Alias}}} models. Here I'm asking that all Properties and Aliases which relate to a user in my users list are retrieved from the database and connected to the corresponding User objects. A list of Properties will be stored in each User object's {{{properties}}} attribute, and Aliases end up as lists in {{{aliases}}} attributes. |
| 20 | |
| 21 | In addition, attributes {{{properties_ids}}} and {{{aliases_ids}}} will contain lists of primary keys for the related objects. |
| 22 | |
| 23 | {{{preload_related()}}} will create one SQL query for each related model. This is a huge improvement, since previously every access to, say, {{{user.userproperty_set.all()}}} would run a separate SQL query. In one of my more complex views, this reduced the number of queries from over 6000 to just eight. |
| 24 | |
| 25 | -- ''akaihola'' 2006-04-05 |