| 175 | == Solution 2c: Generic swappable models == |
| 176 | |
| 177 | Follows the general direction of Solution 2a, but instead of a `USER_MODEL` setting that only solves the problem for auth.User, sets up the infrastructure for the general concept of swappable models. |
| 178 | |
| 179 | == Implementation == |
| 180 | |
| 181 | A model that wants to declare itself as swappable adds a new Meta option: |
| 182 | |
| 183 | {{{ |
| 184 | class User(Model): |
| 185 | .... |
| 186 | class Meta: |
| 187 | swappable = 'user' |
| 188 | }}} |
| 189 | |
| 190 | Here, the name 'user' is an identifier that will be used to refer to this swappable model. By convention, it might be a good idea to namespace this tag (e.g., 'auth.user', instead of just 'user'. |
| 191 | |
| 192 | We then introduce a `SWAPPABLE_MODELS` setting that provides a way for users to specify which models will be overridden in this application: |
| 193 | |
| 194 | {{{ |
| 195 | SWAPPABLE_MODELS = { |
| 196 | 'user': 'myapp.SuperDuperUser' |
| 197 | } |
| 198 | }}} |
| 199 | This specifies that the 'user' model will be satisfied by !SuperDuperUser in this project. |
| 200 | |
| 201 | If a model identifier (i.e., 'user') is mentioned in `SWAPPABLE_MODELS`, then the original model (auth.User) isn't synchronised to the database, and isn't added to the App cache. |
| 202 | |
| 203 | We then add a !LazyForeignKey(): |
| 204 | {{{ |
| 205 | class Comment(Model): |
| 206 | user = LazyForeignKey('user') |
| 207 | .... |
| 208 | }}} |
| 209 | that will resolve the !ForeignKey to the currently defined swappable model. |
| 210 | |
| 211 | If an app defines a model with a !ForeignKey to a swappable model, a warning is raised (since the model could potentially be swapped out); if the model is currently defined as swapped out, then an error will be raised (since the ForeignKey will be pointing at the wrong table). |
| 212 | |
| 213 | The app cache gains a registry of swappable models, and a `get_swappable_model(identifier)` entry point, so that users can easily retrieve the model currently being used as the swappable model for the various swappable endpoints. |
| 214 | |
| 215 | === Advantages === |
| 216 | |
| 217 | As for Solution 2a, but: |
| 218 | |
| 219 | * Solves the general problem of swappable models, so other apps with similar problems (e.g., comments) can use the same infrastructure instead of having to reinvent the wheel. |
| 220 | * Catches migration problems as warnings/errors if existing apps haven't been updated to point to the swappable model. |
| 221 | |
| 222 | === Problems === |
| 223 | |
| 224 | As for Solution 2a. |
| 225 | |