Since the app registry is always populated before the first request is
processed, the situation described in #18251 for the old app cache
cannot happen any more.
Refs #18251, #21628.
Also ensured the transaction state is clean on Oracle while I was there.
This change cannot be backported to 1.6 because it's
backwards-incompatible for custom database backends.
When settings.DATABASES['default']['AUTOCOMMIT'] = False, the connection
wasn't in autocommit mode but Django pretended it was.
Thanks Anssi for analysing this issue.
Refs #17062.
Validating STATIC_ROOT in StaticFilesStorage.__init__ turned out to be
problematic - especially with tests - because the storage refuses to work even
if there are no actual interactions with the file system, which is backward
incompatible.
Originally the validation happened in the StaticFilesStorage.path method, but
that didn't work as expected because the call to FileSystemStorage.__init__
replaced the empty value by a valid path. The new approach is to move back the
check to the StaticFilesStorage.path method, but ensure that the location
attribute remains None after the call to super.
Refs #21581.
Originating WSGIRequests are now attached to the ``wsgi_request`` attribute of
the ``HttpResponse`` returned by the testing client.
Thanks rvdrijst for the suggestion.
Make use of `weakref.finalize` and `weakref.WeakMethod` on python 3.4.
Simplified the removal of receivers, the old function looked overly
complicated.
Many thanks go to Antoine Pitrou for helping me to debug and explain all
the failures I ran into while writing that patch.
In get_commands, setup() might already have been called, for example
when the management command is called through call_command. Moving
setup() to ManagementUtility so as it is only called when the command
is run from command line.
When STATIC_ROOT wasn't set, collectstatic --clear would delete
every files within the current directory and its descendants.
This patch makes the following changes:
Prevent collectstatic from running if STATIC_ROOT isn't set.
Fixed an issue that prevented collectstatic from displaying the
destination directory.
Changed the warning header to notify when the command is run
in dry-run mode.
Now that the refactorings are complete, it isn't particularly useful any
more, nor very well named. Let's keep the API as simple as possible.
Fixed#21689.
To the best of my understanding, since populate_models() is now called
as soon as Django starts, it cannot be called while a models module is
being imported, and that removes the need for postponing.
(If hell breaks loose we'll revert this commit.)
Refs #21681.
Since it triggers imports, it shouldn't be done lightly.
This commit adds a public API for doing it explicitly, django.setup(),
and does it automatically when using manage.py and wsgi.py.
Thanks Florian for isolating the shortest way to reproduce this issue:
./runtests.py \
django.contrib.auth.tests.test_context_processors.AuthContextProcessorTests.test_perms_attrs \
django.contrib.auth.tests.test_auth_backends.ChangedBackendSettingsTest.test_changed_backend_settings \
django.contrib.auth.tests.test_auth_backends.CustomUserModelBackendAuthenticateTest.test_authenticate \
django.contrib.auth.tests.test_basic.BasicTestCase.test_createsuperuser_management_command
SQLite accepts the relevant standard SQL (although by default it doesn't
enforce the constraint), and the 'traditional' creation backend helper
generate it, so this allows us to:
- Maintain the status quo
- Improve readability of the SQL code generated for that backend.
Also, we will need this for when we fix Refs #14204.
Returning None on errors required unpythonic error checking and was
inconsistent with get_app_config.
get_model was a private API until the previous commit, but given that it
was certainly used in third party software, the change is explained in
the release notes.
Applied the same change to get_registered_model, which is a new private
API introduced during the recent refactoring.
ContentTypes are only created for installed applications, and I could
make a case for not returning a model that isn't installed any more.
The check for stale ContentTypes in update_contenttypes doesn't use
model_class.
ModelSignal actually needs get_registered_model since the lookup happens
at import time. I took this opportunity to perform a small refactoring.
This removes the gap between the master app registry and ad-hoc app
registries created by the migration framework, specifically in terms
of behavior of the get_model[s] methods.
This commit contains a stealth feature that I'd rather not describe.
This is to provide a consistent interface (namely bytes) for the smtp
backend which after all sends bytes over the wire; encoding with as_string
yields different results since mails as unicode are not really specified.
as_string stays for backwardscompatibilty mostly and some debug outputs.
But keep in mind that the output doesn't match as_bytes!
Made it use 'AUTOINCREMENT' suffix for PK creation. This way it doeesn't
regress when compared with the 'traditional' DB backend creation
infrastructure.
Refs #10164.
The last component of the dotted path to the application module is
consistently referenced as the application "label". For instance it's
AppConfig.label. appname could be confused with AppConfig.name, which is
the full dotted path.
register_model is called exactly once in the entire Django code base, at the
bottom of ModelBase.__new__:
new_class._meta.apps.register_model(new_class._meta.app_label, new_class)
ModelBase.__new__ exits prematurely 120 lines earlier (sigh) if a model with
the same name is already registered:
if new_class._meta.apps.get_registered_model(new_class._meta.app_label, name):
return
(This isn't the exact code, but it's equivalent.)
apps.register_model and apps.get_registered_model are essentially a setter and
a getter for apps.all_models, and apps.register_model is the only setter. As a
consequence, new_class._meta.apps.all_models cannot change in-between.
Considering that name == new_class.__name__, we can conclude that
register_model(app_label, model) is always called with such arguments that
get_registered_model(app_label, model.__name__) returns None.
Considering that model._meta.model_name == model.__name__.lower(), and looking
at the implementation of register_model and get_registered_model, this proves
that self.all_models[app_label] doesn't contain model._meta.model_name in
register_model, allowing us to simplify the implementation.