| | 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 | |