Take a function and a number of ("app_label", "modelname") tuples, and when all the corresponding models have been imported and registered, call the function with the model classes as its arguments. The function passed to this method must accept exactly n models as
(self, function, *model_keys)
| 386 | model._meta._expire_cache() |
| 387 | |
| 388 | def lazy_model_operation(self, function, *model_keys): |
| 389 | """ |
| 390 | Take a function and a number of ("app_label", "modelname") tuples, and |
| 391 | when all the corresponding models have been imported and registered, |
| 392 | call the function with the model classes as its arguments. |
| 393 | |
| 394 | The function passed to this method must accept exactly n models as |
| 395 | arguments, where n=len(model_keys). |
| 396 | """ |
| 397 | # Base case: no arguments, just execute the function. |
| 398 | if not model_keys: |
| 399 | function() |
| 400 | # Recursive case: take the head of model_keys, wait for the |
| 401 | # corresponding model class to be imported and registered, then apply |
| 402 | # that argument to the supplied function. Pass the resulting partial |
| 403 | # to lazy_model_operation() along with the remaining model args and |
| 404 | # repeat until all models are loaded and all arguments are applied. |
| 405 | else: |
| 406 | next_model, *more_models = model_keys |
| 407 | |
| 408 | # This will be executed after the class corresponding to next_model |
| 409 | # has been imported and registered. The `func` attribute provides |
| 410 | # duck-type compatibility with partials. |
| 411 | def apply_next_model(model): |
| 412 | next_function = partial(apply_next_model.func, model) |
| 413 | self.lazy_model_operation(next_function, *more_models) |
| 414 | |
| 415 | apply_next_model.func = function |
| 416 | |
| 417 | # If the model has already been imported and registered, partially |
| 418 | # apply it to the function now. If not, add it to the list of |
| 419 | # pending operations for the model, where it will be executed with |
| 420 | # the model class as its sole argument once the model is ready. |
| 421 | try: |
| 422 | model_class = self.get_registered_model(*next_model) |
| 423 | except LookupError: |
| 424 | self._pending_operations[next_model].append(apply_next_model) |
| 425 | else: |
| 426 | apply_next_model(model_class) |
| 427 | |
| 428 | def do_pending_operations(self, model): |
| 429 | """ |