Django Documentation - Read the Docs - MOAM.INFO (2023)

tag to allow including lists inside help text. • ConditionalGetMiddleware no longer sets the Date header as Web servers set that header. It also no longer sets the Content-Length header as this is now done by CommonMiddleware. If you have a middleware that modifies a response’s content and appears before CommonMiddleware in the MIDDLEWARE or MIDDLEWARE_CLASSES settings, you must reorder your middleware so that responses aren’t modified after Content-Length is set, or have the response modifying middleware reset the Content-Length header. • get_model() and get_models() now raise AppRegistryNotReady if they’re called before models of all applications have been loaded. Previously they only required the target application’s models to be loaded and thus could return models without all their relations set up. If you need the old behavior of get_model(), set the require_ready argument to False. • The unused BaseCommand.can_import_settings attribute is removed. • The undocumented django.utils.functional.lazy_property is removed.

Chapter 9. Release notes

• For consistency with non-multipart requests, MultiPartParser.parse() now leaves request.POST immutable. If you’re modifying that QueryDict, you must now first copy it, e.g. request.POST.copy(). • Support for cx_Oracle < 5.2 is removed. • Support for IPython < 1.0 is removed from the shell command. • The signature of private API Widget.build_attrs() changed from extra_attrs=None, **kwargs to base_attrs, extra_attrs=None. • File-like objects (e.g., StringIO and BytesIO) uploaded to an ImageField using the test client now require a name attribute with a value that passes the validate_image_file_extension validator. See the note in Client.post(). Features deprecated in 1.11 models.permalink() decorator Use django.urls.reverse() instead. For example: from django.db import models class MyModel(models.Model): ... @models.permalink def url(self): return ('guitarist_detail', [self.slug])

becomes: from django.db import models from django.urls import reverse class MyModel(models.Model): ... def url(self): return reverse('guitarist_detail', args=[self.slug])

Miscellaneous • contrib.auth’s login() and logout() function-based views are deprecated in favor of new class-based views LoginView and LogoutView. • The unused extra_context parameter of contrib.auth.views.logout_then_login() is deprecated. • contrib.auth’s password_change(), password_change_done(), password_reset(), password_reset_done(), password_reset_confirm(), and password_reset_complete() function-based views are deprecated in favor of new class-based views PasswordChangeView, PasswordChangeDoneView, PasswordResetView, PasswordResetDoneView, PasswordResetConfirmView, and PasswordResetCompleteView.

9.1. Final releases

• django.test.runner.setup_databases() is setup_databases(). The old location is deprecated.

django.test.utils.

• django.utils.translation.string_concat() is deprecated in favor of django.utils. text.format_lazy(). string_concat(*strings) can be replaced by format_lazy('{}' * len(strings), *strings). • For the PyLibMCCache cache backend, passing pylibmc behavior settings as top-level attributes of OPTIONS is deprecated. Set them under a behaviors key within OPTIONS instead. • The host parameter of django.utils.http.is_safe_url() is deprecated in favor of the new allowed_hosts parameter. • Silencing exceptions raised while rendering the {% include %} template tag is deprecated as the behavior is often more confusing than helpful. In Django 2.1, the exception will be raised. • DatabaseIntrospection.get_indexes() is deprecated in favor of DatabaseIntrospection. get_constraints(). • authenticate() now passes a request argument to the authenticate() method of authentication backends. Support for methods that don’t accept request as the first positional argument will be removed in Django 2.1. • The USE_ETAGS setting is deprecated in favor of ConditionalGetMiddleware which now adds the ETag header to responses regardless of the setting. CommonMiddleware and django.utils.cache. patch_response_headers() will no longer set ETags when the deprecation ends. • Model._meta.has_auto_field is deprecated in favor of checking if Model._meta.auto_field is not None. • Using regular expression groups with iLmsu# in url() is deprecated. The only group that’s useful is (?i) for case-insensitive URLs, however, case-insensitive URLs aren’t a good practice because they create multiple entries for search engines, for example. An alternative solution could be to create a handler404 that looks for uppercase characters in the URL and redirects to a lowercase equivalent. • The renderer argument is added to the Widget.render() method. Methods that don’t accept that argument will work through a deprecation period.

9.1.4 1.10 release Django 1.10.8 release notes September 5, 2017 Django 1.10.8 fixes a security issue in 1.10.7. CVE-2017-12794: Possible XSS in traceback section of technical 500 debug page In older versions, HTML autoescaping was disabled in a portion of the template for the technical 500 debug page. Given the right circumstances, this allowed a cross-site scripting attack. This vulnerability shouldn’t affect most production sites since you shouldn’t run with DEBUG = True (which makes this page accessible) in your production settings. Django 1.10.7 release notes April 4, 2017

Chapter 9. Release notes

Django 1.10.7 fixes two security issues and a bug in 1.10.6. CVE-2017-7233: Open redirect and possible XSS attack via user-supplied numeric redirect URLs Django relies on user input in some cases (e.g. django.contrib.auth.views.login() and i18n) to redirect the user to an “on success” URL. The security check for these redirects (namely django.utils.http. is_safe_url()) considered some numeric URLs (e.g. http:999999999) “safe” when they shouldn’t be. Also, if a developer relies on is_safe_url() to provide safe redirect targets and puts such a URL into a link, they could suffer from an XSS attack. CVE-2017-7234: Open redirect vulnerability in django.views.static.serve() A maliciously crafted URL to a Django site using the serve() view could redirect to any other domain. The view no longer does any redirects as they don’t provide any known, useful functionality. Note, however, that this view has always carried a warning that it is not hardened for production use and should be used only as a development aid. Bugfixes • Made admin’s RelatedFieldWidgetWrapper value_omitted_from_data() method (#27905).

• Fixed model form default fallback for SelectMultiple (#27993). Django 1.10.6 release notes March 1, 2017 Django 1.10.6 fixes several bugs in 1.10.5. Bugfixes • Fixed ClearableFileInput’s “Clear” checkbox on model form fields where the model field has a default (#27805). • Fixed RequestDataTooBig and TooManyFieldsSent exceptions crashing rather than generating a bad request response (#27820). • Fixed a crash on Oracle and PostgreSQL when subtracting DurationField or IntegerField from DateField (#27828). • Fixed query expression date subtraction accuracy on PostgreSQL for differences larger than a month (#27856). • Fixed a GDALException raised by GDALClose on GDAL ≥ 2.0 (#27479). Django 1.10.5 release notes January 4, 2017 Django 1.10.5 fixes several bugs in 1.10.4.

9.1. Final releases

Bugfixes • Fixed a crash in the debug view if request.user can’t be retrieved, such as if the database is unavailable (#27567). • Fixed occasional missing plural forms in JavaScriptCatalog (#27418). • Fixed a regression in the timesince and timeuntil filters that caused incorrect results for dates in a leap year (#27637). • Fixed a regression where collectstatic overwrote newer files in remote storages (#27658). Django 1.10.4 release notes December 1, 2016 Django 1.10.4 fixes several bugs in 1.10.3. Bugfixes • Quoted the Oracle test user’s password in queries to fix the “ORA-00922: missing or invalid option” error when the password starts with a number or special character (#27420). • Fixed incorrect app_label / model_name arguments for allow_migrate() in makemigrations migration consistency checks (#27461). • Made Model.delete(keep_parents=True) preserve parent reverse relationships in multi-table inheritance (#27407). • Fixed a QuerySet.update() crash on SQLite when updating a DateTimeField with an F() expression and a timedelta (#27544). • Prevented LocaleMiddleware from redirecting on URLs that should return 404 when using prefix_default_language=False (#27402). • Prevented an unnecessary index from being created on an InnoDB ForeignKey when the field was added after the model was created (#27558). Django 1.10.3 release notes November 1, 2016 Django 1.10.3 fixes two security issues and several bugs in 1.10.2. User with hardcoded password created when running tests on Oracle When running tests with an Oracle database, Django creates a temporary database user. In older versions, if a password isn’t manually specified in the database settings TEST dictionary, a hardcoded password is used. This could allow an attacker with network access to the database server to connect. This user is usually dropped after the test suite completes, but not when using the manage.py test --keepdb option or if the user has an active session (such as an attacker’s connection). A randomly generated password is now used for each test run.

Chapter 9. Release notes

DNS rebinding vulnerability when DEBUG=True Older versions of Django don’t validate the Host header against settings.ALLOWED_HOSTS when settings. DEBUG=True. This makes them vulnerable to a DNS rebinding attack. While Django doesn’t ship a module that allows remote code execution, this is at least a cross-site scripting vector, which could be quite serious if developers load a copy of the production database in development or connect to some production services for which there’s no development instance, for example. If a project uses a package like the django-debug-toolbar, then the attacker could execute arbitrary SQL, which could be especially bad if the developers connect to the database with a superuser account. settings.ALLOWED_HOSTS is now validated regardless of DEBUG. For convenience, if ALLOWED_HOSTS is empty and DEBUG=True, the following variations of localhost are allowed ['localhost', '127.0.0.1', '::1']. If your local settings file has your production ALLOWED_HOSTS value, you must now omit it to get those fallback values. Bugfixes • Allowed User.is_authenticated and User.is_anonymous properties to be tested for set membership (#27309). • Fixed a performance regression when running migrate in projects with RenameModel operations (#27279). • Added model_name to the allow_migrate() calls in makemigrations (#27200). • Made the JavaScriptCatalog view respect the packages argument; previously it was ignored (#27374). • Fixed QuerySet.bulk_create() on PostgreSQL when the number of objects is a multiple plus one of batch_size (#27385). • Prevented i18n_patterns() from using too much of the URL as the language to fix a use case for prefix_default_language=False (#27063). • Replaced a possibly incorrect redirect from SessionMiddleware when a session is destroyed in a concurrent request with a SuspiciousOperation to indicate that the request can’t be completed (#27363). Django 1.10.2 release notes October 1, 2016 Django 1.10.2 fixes several bugs in 1.10.1. Bugfixes • Fixed a crash in MySQL database validation where SELECT @@sql_mode doesn’t return a result (#27180). • Allowed combining contrib.postgres.search.SearchQuery with more than one & or | operators (#27143). • Disabled system check for URL patterns beginning with a ‘/’ when APPEND_SLASH=False (#27238). • Fixed model form default fallback for CheckboxSelectMultiple, MultiWidget, FileInput, SplitDateTimeWidget, SelectDateWidget, and SplitArrayWidget (#27186). Custom widgets affected by this issue should implement value_omitted_from_data(). • Fixed a crash in runserver logging during a “Broken pipe” error (#27271).

9.1. Final releases

• Fixed a regression where unchanged localized date/time fields were listed as changed in the admin’s model history messages (#27302). Django 1.10.1 release notes September 1, 2016 Django 1.10.1 fixes several bugs in 1.10. Bugfixes • Fixed a crash in MySQL connections where SELECT @@SQL_AUTO_IS_NULL doesn’t return a result (#26991). • Allowed User.is_authenticated and User.is_anonymous properties to be compared using ==, !=, and | (#26988, #27154). • Removed the broken BaseCommand.usage() method which was for optparse support (#27000). • Fixed a checks framework crash with an empty Meta.default_permissions (#26997). • Fixed a regression in the number of queries when using RadioSelect with a ModelChoiceField form field (#27001). • Fixed a crash if request.META['CONTENT_LENGTH'] is an empty string (#27005). • Fixed the isnull lookup on a ForeignKey with its to_field pointing to a CharField or pointing to a CharField defined with primary_key=True (#26983). • Prevented the migrate command from raising InconsistentMigrationHistory in the presence of unapplied squashed migrations (#27004). • Fixed a regression in Client.force_login() which required specifying a backend rather than automatically using the first one if multiple backends are configured (#27027). • Made QuerySet.bulk_create() properly initialize model instances on backends, such as PostgreSQL, that support returning the IDs of the created records so that many-to-many relationships can be used on the new objects (#27026). • Fixed crash of django.views.static.serve() with show_indexes enabled (#26973). • Fixed ClearableFileInput to avoid the required HTML attribute when initial data exists (#27037). • Fixed annotations with database functions when combined with lookups on PostGIS (#27014). • Reallowed the {% for %} tag to unpack any iterable (#27058). • Made makemigrations skip inconsistent history checks on non-default databases if database routers aren’t in use or if no apps can be migrated to the database (#27054, #27110, #27142). • Removed duplicated managers in Model._meta.managers (#27073). • Fixed contrib.admindocs crash when a view is in a class, such as some of the admin views (#27018). • Reverted a few admin checks that checked field.many_to_many back to isinstance(field, models.ManyToManyField) since it turned out the checks weren’t suitable to be generalized like that (#26998). • Added the database alias to the InconsistentMigrationHistory makemigrations and migrate (#27089).

Chapter 9. Release notes

• Fixed the creation of ContentType and Permission objects for models of applications without migrations when calling the migrate command with no migrations to apply (#27044). • Included the already applied migration state changes in the Apps instance provided to the pre_migrate signal receivers to allow ContentType renaming to be performed on model rename (#27100). • Reallowed subclassing UserCreationForm without USERNAME_FIELD in Meta.fields (#27111). • Fixed a regression in model forms where model fields with a default that didn’t appear in POST data no longer used the default (#27039). Django 1.10 release notes August 1, 2016 Welcome to Django 1.10! These release notes cover the new features, as well as some backwards incompatible changes you’ll want to be aware of when upgrading from Django 1.9 or older versions. We’ve dropped some features that have reached the end of their deprecation cycle, and we’ve begun the deprecation process for some features. See the Upgrading Django to a newer version guide if you’re updating an existing project. Python compatibility Like Django 1.9, Django 1.10 requires Python 2.7, 3.4, or 3.5. We highly recommend and only officially support the latest release of each series. What’s new in Django 1.10 Full text search for PostgreSQL django.contrib.postgres now includes a collection of database functions to allow the use of the full text search engine. You can search across multiple fields in your relational database, combine the searches with other lookups, use different language configurations and weightings, and rank the results by relevance. It also now includes trigram support, using the trigram_similar lookup, and the TrigramSimilarity and TrigramDistance expressions. New-style middleware A new style of middleware is introduced to solve the lack of strict request/response layering of the old-style of middleware described in DEP 0005. You’ll need to adapt old, custom middleware and switch from the MIDDLEWARE_CLASSES setting to the new MIDDLEWARE setting to take advantage of the improvements. Official support for Unicode usernames The User model in django.contrib.auth originally only accepted ASCII letters and numbers in usernames. Although it wasn’t a deliberate choice, Unicode characters have always been accepted when using Python 3. The username validator now explicitly accepts Unicode characters by default on Python 3 only. This default behavior can be overridden by changing the username_validator attribute of the User model, or to any proxy of that

9.1. Final releases

model, using either ASCIIUsernameValidator or UnicodeUsernameValidator. Custom user models may also use those validators. Minor features django.contrib.admin • For sites running on a subpath, the default URL for the "View site" link at the top of each admin page will now point to request.META['SCRIPT_NAME'] if set, instead of /. • The success message that appears after adding or editing an object now contains a link to the object’s change form. • All inline JavaScript is removed so you can enable the Content-Security-Policy HTTP header if you wish. • The new InlineModelAdmin.classes attribute allows specifying classes on inline fieldsets. Inlines with a collapse class will be initially collapsed and their header will have a small “show” link. • If a user doesn’t have the add permission, the object-tools block on a model’s changelist will now be rendered (without the add button, of course). This makes it easier to add custom tools in this case. • The LogEntry model now stores change messages in a JSON structure so that the message can be dynamically translated using the current active language. A new LogEntry.get_change_message() method is now the preferred way of retrieving the change message. • Selected objects for fields in ModelAdmin.raw_id_fields now have a link to object’s change form. • Added “No date” and “Has date” choices for DateFieldListFilter if the field is nullable. • The jQuery library embedded in the admin is upgraded from version 2.1.4 to 2.2.3. django.contrib.auth • Added support for the Argon2 password hash. It’s recommended over PBKDF2, however, it’s not the default as it requires a third-party library. • The default iteration count for the PBKDF2 password hasher has been increased by 25%. This backwards compatible change will not affect users who have subclassed django.contrib.auth.hashers. PBKDF2PasswordHasher to change the default value. • The django.contrib.auth.views.logout() view sends “no-cache” headers to prevent an issue where Safari caches redirects and prevents a user from being able to log out. • Added the optional backend argument to django.contrib.auth.login() to allow using it without credentials. • The new LOGOUT_REDIRECT_URL setting controls the redirect of the django.contrib.auth.views. logout() view, if the view doesn’t get a next_page argument. • The new redirect_authenticated_user parameter for the django.contrib.auth.views. login() view allows redirecting authenticated users visiting the login page. • The new AllowAllUsersModelBackend and AllowAllUsersRemoteUserBackend ignore the value of User.is_active, while ModelBackend and RemoteUserBackend now reject inactive users.

Chapter 9. Release notes

django.contrib.gis • Distance lookups now accept expressions as the distance value parameter. • The new GEOSGeometry.unary_union property computes the union of all the elements of this geometry. • Added the GEOSGeometry.covers() binary predicate. • Added the GDALBand.statistics() method and mean and std attributes. • Added support for the MakeLine aggregate and GeoHash function on SpatiaLite. • Added support for the Difference, Intersection, and SymDifference functions on MySQL. • Added support for instantiating empty GEOS geometries. • The new trim and precision properties of WKTWriter allow controlling output of the fractional part of the coordinates in WKT. • Added the LineString.closed and MultiLineString.closed properties. • The GeoJSON serializer now outputs the primary key of objects in the properties dictionary if specific fields aren’t specified. • The ability to replicate input data on the GDALBand.data() method was added. Band data can now be updated with repeated values efficiently. • Added database functions IsValid and MakeValid, as well as the isvalid lookup, all for PostGIS. This allows filtering and repairing invalid geometries on the database side. • Added raster support for all spatial lookups. django.contrib.postgres • For convenience, HStoreField now casts its keys and values to strings. django.contrib.sessions • The clearsessions management command now removes file-based sessions. django.contrib.sites • The Site model now supports natural keys. django.contrib.staticfiles • The static template tag now uses django.contrib.staticfiles if it’s in INSTALLED_APPS. This is especially useful for third-party apps which can now always use {% load static %} (instead of {% load staticfiles %} or {% load static from staticfiles %}) and not worry about whether or not the staticfiles app is installed. • You can more easily customize the collectstatic --ignore option with a custom AppConfig.

9.1. Final releases

Cache • The file-based cache backend now uses the highest pickling protocol. CSRF • The default CSRF_FAILURE_VIEW , views.csrf.csrf_failure() now accepts an optional template_name parameter, defaulting to '403_csrf.html', to control the template used to render the page. • To protect against BREACH attacks, the CSRF protection mechanism now changes the form token value on every request (while keeping an invariant secret which can be used to validate the different tokens). Database backends • Temporal data subtraction was unified on all backends. • If the database supports it, backends can set DatabaseFeatures. can_return_ids_from_bulk_insert=True and implement DatabaseOperations. fetch_returned_insert_ids() to set primary keys on objects created using QuerySet. bulk_create(). • Added keyword arguments to the as_sql() methods of various expressions (Func, When, Case, and OrderBy) to allow database backends to customize them without mutating self, which isn’t safe when using different database backends. See the arg_joiner and **extra_context parameters of Func. as_sql() for an example. File Storage • Storage backends now present a timezone-aware API with new methods get_accessed_time(), get_created_time(), and get_modified_time(). They return a timezone-aware datetime if USE_TZ is True and a naive datetime in the local timezone otherwise. • The new Storage.generate_filename() method makes it easier to implement custom storages that don’t use the os.path calls previously in FileField. Forms • Form and widget Media is now served using django.contrib.staticfiles if installed. • The tag rendered by CharField now includes a minlength attribute if the field has a min_length. • Required form fields now have the required HTML attribute. Set the new Form. use_required_attribute attribute to False to disable it. The required attribute isn’t included on forms of formsets because the browser validation may not be correct when adding and deleting formsets. Generic Views • The View class can now be imported from django.views.

Chapter 9. Release notes

Internationalization • The i18n_patterns() helper function can now be used in a root URLConf specified using request. urlconf. • By setting the new prefix_default_language parameter for i18n_patterns() to False, you can allow accessing the default language without a URL prefix. • set_language() now returns a 204 status code (No Content) for AJAX requests when there is no next parameter in POST or GET. • The JavaScriptCatalog and JSONCatalog class-based views supersede the deprecated javascript_catalog() and json_catalog() function-based views. The new views are almost equivalent to the old ones except that by default the new views collect all JavaScript strings in the djangojs translation domain from all installed apps rather than only the JavaScript strings from LOCALE_PATHS. Management Commands • call_command() now returns the value returned from the command.handle() method. • The new check --fail-level option allows specifying the message level that will cause the command to exit with a non-zero status. • The new makemigrations --check option makes the command exit with a non-zero status when model changes without migrations are detected. • makemigrations now displays the path to the migration files that it generates. • The shell --interface option now accepts python to force use of the “plain” Python interpreter. • The new shell --command option lets you run a command as Django and exit, instead of opening the interactive shell. • Added a warning to dumpdata if a proxy model is specified (which results in no output) without its concrete parent. • The new BaseCommand.requires_migrations_checks attribute may be set to True if you want your command to print a warning, like runserver does, if the set of migrations on disk don’t match the migrations in the database. • To assist with testing, call_command() now accepts a command object as the first argument. • The shell command supports tab completion on systems using libedit, e.g. macOS. • The inspectdb command lets you choose what tables should be inspected by specifying their names as arguments. Migrations • Added support for serialization of enum.Enum objects. • Added the elidable argument to the RunSQL and RunPython operations to allow them to be removed when squashing migrations. • Added support for non-atomic migrations by setting the atomic attribute on a Migration. • The migrate and makemigrations commands now check for a consistent migration history. If they find some unapplied dependencies of an applied migration, InconsistentMigrationHistory is raised. • The pre_migrate() and post_migrate() signals now dispatch their migration plan and apps.

9.1. Final releases

Models • Reverse foreign keys from proxy models are now propagated to their concrete class. The reverse relation attached by a ForeignKey pointing to a proxy model is now accessible as a descriptor on the proxied model class and may be referenced in queryset filtering. • The new Field.rel_db_type() method returns the database column data type for fields such as ForeignKey and OneToOneField that point to another field. • The arity class attribute is added to Func. This attribute can be used to set the number of arguments the function accepts. • Added BigAutoField which acts much like an AutoField except that it is guaranteed to fit numbers from 1 to 9223372036854775807. • QuerySet.in_bulk() may be called without any arguments to return all objects in the queryset. • related_query_name now supports app label and class interpolation using the '%(app_label)s' and '%(class)s' strings. • Allowed overriding model fields inherited from abstract base classes. • The prefetch_related_objects() function is now a public API. • QuerySet.bulk_create() sets the primary key on objects when using PostgreSQL. • Added the Cast database function. • A proxy model may now inherit multiple proxy models that share a common non-abstract parent class. • Added Extract functions to extract datetime components as integers, such as year and hour. • Added Trunc functions to truncate a date or datetime to a significant component. They enable queries like sales-per-day or sales-per-hour. • Model.__init__() now sets values of virtual fields from its keyword arguments. • The new Meta.base_manager_name and Meta.default_manager_name options allow controlling the _base_manager and _default_manager, respectively. Requests and Responses • Added request.user to the debug view. • Added HttpResponse methods readable() and seekable() to make an instance a stream-like object and allow wrapping it with io.TextIOWrapper. • Added the HttpRequest.content_type and content_params attributes which are parsed from the CONTENT_TYPE header. • The parser for request.COOKIES is simplified to better match the behavior of browsers. request. COOKIES may now contain cookies that are invalid according to RFC 6265 but are possible to set via document.cookie. Serialization • The django.core.serializers.json.DjangoJSONEncoder now knows how to serialize lazy strings, typically used for translatable content.

Chapter 9. Release notes

Templates • Added the autoescape option to the DjangoTemplates backend and the Engine class. • Added the is and is not comparison operators to the if tag. • Allowed dictsort to order a list of lists by an element at a specified index. • The debug() context processor contains queries for all database aliases instead of only the default alias. • Added relative path support for string arguments of the extends and include template tags. Tests • To better catch bugs, TestCase now checks deferrable database constraints at the end of each test. • Tests and test cases can be marked with tags and run selectively with the new test --tag and test --exclude-tag options. • You can now login and use sessions with the test client even if django.contrib.sessions is not in INSTALLED_APPS. URLs • An addition in django.setup() allows URL resolving that happens outside of the request/response cycle (e.g. in management commands and standalone scripts) to take FORCE_SCRIPT_NAME into account when it is set. Validators • URLValidator now limits the length of domain name labels to 63 characters and the total length of domain names to 253 characters per RFC 1034. • int_list_validator() now accepts an optional allow_negative boolean parameter, defaulting to False, to allow negative integers. Backwards incompatible changes in 1.10

Warning: In addition to the changes outlined in this section, be sure to review the Features removed in 1.10 for the features that have reached the end of their deprecation cycle and therefore been removed. If you haven’t updated your code within the deprecation timeline for a given feature, its removal may appear as a backwards incompatible change. Database backend API • GIS’s AreaField uses an unspecified underlying numeric type that could in practice be any numeric Python type. decimal.Decimal values retrieved from the database are now converted to float to make it easier to combine them with values used by the GIS libraries.

9.1. Final releases

• In order to enable temporal subtraction you must set the supports_temporal_subtraction database feature flag to True and implement the DatabaseOperations.subtract_temporals() method. This method should return the SQL and parameters required to compute the difference in microseconds between the lhs and rhs arguments in the datatype used to store DurationField. select_related() prohibits non-relational fields for nested relations Django 1.8 added validation for non-relational fields in select_related(): >>> Book.objects.select_related('title') Traceback (most recent call last): ... FieldError: Non-relational field given in select_related: 'title'

But it didn’t prohibit nested non-relation fields as it does now: >>> Book.objects.select_related('author__name') Traceback (most recent call last): ... FieldError: Non-relational field given in select_related: 'name'

_meta.get_fields() returns consistent reverse fields for proxy models Before Django 1.10, the get_fields() method returned different reverse fields when called on a proxy model compared to its proxied concrete class. This inconsistency was fixed by returning the full set of fields pointing to a concrete class or one of its proxies in both cases. AbstractUser.username max_length increased to 150 A migration for django.contrib.auth.models.User.username is included. If you have a custom user model inheriting from AbstractUser, you’ll need to generate and apply a database migration for your user model. We considered an increase to 254 characters to more easily allow the use of email addresses (which are limited to 254 characters) as usernames but rejected it due to a MySQL limitation. When using the utf8mb4 encoding (recommended for proper Unicode support), MySQL can only create unique indexes with 191 characters by default. Therefore, if you need a longer length, please use a custom user model. If you want to preserve the 30 character limit for usernames, use a custom form when creating a user or changing usernames: from django.contrib.auth.forms import UserCreationForm class MyUserCreationForm(UserCreationForm): username = forms.CharField( max_length=30, help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ ˓→only.', )

If you wish to keep this restriction in the admin, set UserAdmin.add_form to use this form: from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.contrib.auth.models import User

Chapter 9. Release notes

class UserAdmin(BaseUserAdmin): add_form = MyUserCreationForm admin.site.unregister(User) admin.site.register(User, UserAdmin)

Dropped support for PostgreSQL 9.1 Upstream support for PostgreSQL 9.1 ends in September 2016. As a consequence, Django 1.10 sets PostgreSQL 9.2 as the minimum version it officially supports. runserver output goes through logging Request and response handling of the runserver command is sent to the django.server logger instead of to sys. stderr. If you disable Django’s logging configuration or override it with your own, you’ll need to add the appropriate logging configuration if you want to see that output: 'formatters': { 'django.server': { '()': 'django.utils.log.ServerFormatter', 'format': '[%(server_time)s] %(message)s', } }, 'handlers': { 'django.server': { 'level': 'INFO', 'class': 'logging.StreamHandler', 'formatter': 'django.server', }, }, 'loggers': { 'django.server': { 'handlers': ['django.server'], 'level': 'INFO', 'propagate': False, } }

auth.CustomUser and auth.ExtensionUser test models were removed Since the introduction of migrations for the contrib apps in Django 1.8, the tables of these custom user test models were not created anymore making them unusable in a testing context. Apps registry is no longer auto-populated when unpickling models outside of Django The apps registry is no longer auto-populated when unpickling models. This was added in Django 1.7.2 as an attempt to allow unpickling models outside of Django, such as in an RQ worker, without calling django.setup(), but it creates the possibility of a deadlock. To adapt your code in the case of RQ, you can provide your own worker script that calls django.setup().

9.1. Final releases

Removed null assignment check for non-null foreign key fields In older versions, assigning None to a non-nullable ForeignKey or OneToOneField raised ValueError('Cannot assign None: "model.field" does not allow null values.'). For consistency with other model fields which don’t have a similar check, this check is removed. Removed weak password hashers from the default PASSWORD_HASHERS setting Django 0.90 stored passwords as unsalted MD5. Django 0.91 added support for salted SHA1 with automatic upgrade of passwords when a user logs in. Django 1.4 added PBKDF2 as the default password hasher. If you have an old Django project with MD5 or SHA1 (even salted) encoded passwords, be aware that these can be cracked fairly easily with today’s hardware. To make Django users acknowledge continued use of weak hashers, the following hashers are removed from the default PASSWORD_HASHERS setting: 'django.contrib.auth.hashers.SHA1PasswordHasher' 'django.contrib.auth.hashers.MD5PasswordHasher' 'django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher' 'django.contrib.auth.hashers.UnsaltedMD5PasswordHasher' 'django.contrib.auth.hashers.CryptPasswordHasher'

Consider using a wrapped password hasher to strengthen the hashes in your database. If that’s not feasible, add the PASSWORD_HASHERS setting to your project and add back any hashers that you need. You can check if your database has any of the removed hashers like this: from django.contrib.auth import get_user_model User = get_user_model() # Unsalted MD5/SHA1: User.objects.filter(password__startswith='md5$$') User.objects.filter(password__startswith='sha1$$') # Salted MD5/SHA1: User.objects.filter(password__startswith='md5$').exclude(password__startswith='md5$$') User.objects.filter(password__startswith='sha1$').exclude(password__startswith='sha1$$ ˓→') # Crypt hasher: User.objects.filter(password__startswith='crypt$$') from django.db.models import CharField from django.db.models.functions import Length CharField.register_lookup(Length) # Unsalted MD5 passwords might not have an 'md5$$' prefix: User.objects.filter(password__length=32)

Field.get_prep_lookup() and Field.get_db_prep_lookup() methods are removed If you have a custom field that implements either of these methods, register a custom lookup for it. For example: from django.db.models import Field from django.db.models.lookups import Exact class MyField(Field): ...

Chapter 9. Release notes

class MyFieldExact(Exact): def get_prep_lookup(self): # do_custom_stuff_for_myfield .... MyField.register_lookup(MyFieldExact)

django.contrib.gis • Support for SpatiaLite < 3.0 and GEOS < 3.3 is dropped. • The add_postgis_srs() backwards compatibility alias for django.contrib.gis.utils. add_srs_entry() is removed. • On Oracle/GIS, the Area aggregate function now returns a float instead of decimal.Decimal. (It’s still wrapped in a measure of square meters.) • The default GEOSGeometry representation (WKT output) is trimmed by default. That is, instead of POINT (23.0000000000000000 5.5000000000000000), you’ll get POINT (23 5.5). Maximum size of a request body and the number of GET/POST parameters is limited Two new settings help mitigate denial-of-service attacks via large requests: • DATA_UPLOAD_MAX_MEMORY_SIZE limits the size that a request body may be. File uploads don’t count towards this limit. • DATA_UPLOAD_MAX_NUMBER_FIELDS limits the number of GET/POST parameters that are parsed. Applications that receive unusually large form posts may need to tune these settings. Miscellaneous • The repr() of a QuerySet is wrapped in to disambiguate it from a plain list when debugging. • utils.version.get_version() returns PEP 440 compliant release candidate versions (e.g. ‘1.10rc1’ instead of ‘1.10c1’). • CSRF token values are now required to be strings of 64 alphanumerics; values of 32 alphanumerics, as set by older versions of Django by default, are automatically replaced by strings of 64 characters. Other values are considered invalid. This should only affect developers or users who replace these tokens. • The LOGOUT_URL setting is removed as Django hasn’t made use of it since pre-1.0. If you use it in your project, you can add it to your project’s settings. The default value was '/accounts/logout/'. • Objects with a close() method such as files and generators passed to HttpResponse are now closed immediately instead of when the WSGI server calls close() on the response. • A redundant transaction.atomic() call in QuerySet.update_or_create() is removed. This may affect query counts tested by TransactionTestCase.assertNumQueries(). • Support for skip_validation in BaseCommand.execute(**options) is removed. skip_checks (added in Django 1.7) instead.

• loaddata now raises a CommandError instead of showing a warning when the specified fixture file is not found. 9.1. Final releases

• Instead of directly accessing the LogEntry.change_message attribute, it’s now better to call the LogEntry.get_change_message() method which will provide the message in the current language. • The default error views now raise TemplateDoesNotExist if a nonexistent template_name is specified. • The unused choices keyword argument of the Select and SelectMultiple widgets’ render() method is removed. The choices argument of the render_options() method is also removed, making selected_choices the first argument. • Tests that violate deferrable database constraints will now error when run on a database that supports deferrable constraints. • Built-in management commands now use indexing of keys in options, e.g. options['verbosity'], instead of options.get() and no longer perform any type coercion. This could be a problem if you’re calling commands using Command.execute() (which bypasses the argument parser that sets a default value) instead of call_command(). Instead of calling Command.execute(), pass the command object as the first argument to call_command(). • ModelBackend and RemoteUserBackend now reject inactive users. This means that inactive users can’t login and will be logged out if they are switched from is_active=True to False. If you need the previous behavior, use the new AllowAllUsersModelBackend or AllowAllUsersRemoteUserBackend in AUTHENTICATION_BACKENDS instead. • In light of the previous change, the test client’s login() method no longer always rejects inactive users but instead delegates this decision to the authentication backend. force_login() also delegates the decision to the authentication backend, so if you’re using the default backends, you need to use an active user. • django.views.i18n.set_language() may now return a 204 status code for AJAX requests. • The base_field attribute of RangeField is now a type of field, not an instance of a field. If you have created a custom subclass of RangeField, you should change the base_field attribute. • Middleware classes are now initialized when the server starts rather than during the first request. • If you override is_authenticated() or is_anonymous() in a custom user model, you must convert them to attributes or properties as described in the deprecation note. • When using ModelAdmin.save_as=True, the “Save as new” button now redirects to the change view for the new object instead of to the model’s changelist. If you need the previous behavior, set the new ModelAdmin.save_as_continue attribute to False. • Required form fields now have the required HTML attribute. Set the Form. use_required_attribute attribute to False to disable it. You could also add the novalidate attribute to if you don’t want browser validation. To disable the required attribute on custom widgets, override the Widget.use_required_attribute() method. • The WSGI handler no longer removes content of responses from HEAD requests or responses with a status_code of 100-199, 204, or 304. Most Web servers already implement this behavior. Responses retrieved using the Django test client continue to have these “response fixes” applied. • Model.__init__() now receives django.db.models.DEFERRED as the value of deferred fields. • The Model._deferred attribute is removed as dynamic model classes when using QuerySet.defer() and only() is removed. • Storage.save() no longer replaces '\' with '/'. This behavior is moved to FileSystemStorage since this is a storage specific implementation detail. Any Windows user with a custom storage implementation that relies on this behavior will need to implement it in the custom storage’s save() method. • Private FileField methods get_directory_name() and get_filename() are no longer called (and are now deprecated) which is a backwards incompatible change for users overriding those methods

Chapter 9. Release notes

on custom fields. To adapt such code, override FileField.generate_filename() or Storage. generate_filename() instead. It might be possible to use upload_to also. • The subject of mail sent by AdminEmailHandler is no longer truncated at 989 characters. If you were counting on a limited length, truncate the subject yourself. • Private expressions django.db.models.expressions.Date and DateTime are removed. The new Trunc expressions provide the same functionality. • The _base_manager and _default_manager attributes are removed from model instances. They remain accessible on the model class. • Accessing a deleted field on a model instance, e.g. after del obj.field, reloads the field’s value instead of raising AttributeError. • If you subclass AbstractBaseUser and override clean(), be sure it calls super(). AbstractBaseUser.normalize_username() is called in a new AbstractBaseUser.clean() method. • Private API django.forms.models.model_to_dict() returns a queryset rather than a list of primary keys for ManyToManyFields. • If django.contrib.staticfiles is installed, the static template tag uses the staticfiles storage to construct the URL rather than simply joining the value with STATIC_ROOT. The new approach encodes the URL, which could be backwards-incompatible in cases such as including a fragment in a path, e.g. {% static 'img.svg#fragment' %}, since the # is encoded as %23. To adapt, move the fragment outside the template tag: {% static 'img.svg' %}#fragment. • When USE_L10N is True, localization is now applied for the date and time filters when no format string is specified. The DATE_FORMAT and TIME_FORMAT specifiers from the active locale are used instead of the settings of the same name. Features deprecated in 1.10 Direct assignment to a reverse foreign key or many-to-many relation Instead of assigning related objects using direct assignment: >>> new_list = [obj1, obj2, obj3] >>> e.related_set = new_list

Use the set() method added in Django 1.9: >>> e.related_set.set([obj1, obj2, obj3])

This prevents confusion about an assignment resulting in an implicit save. Non-timezone-aware Storage API The old, non-timezone-aware methods accessed_time(), created_time(), and modified_time() are deprecated in favor of the new get_*_time() methods. Third-party storage backends should implement the new methods and mark the old ones as deprecated. Until then, the new get_*_time() methods on the base Storage class convert datetimes from the old methods as required and emit a deprecation warning as they do so. Third-party storage backends may retain the old methods as long as they wish to support earlier versions of Django.

9.1. Final releases

django.contrib.gis • The get_srid() and set_srid() methods of GEOSGeometry are deprecated in favor of the srid property. • The get_x(), set_x(), get_y(), set_y(), get_z(), and set_z() methods of Point are deprecated in favor of the x, y, and z properties. • The get_coords() and set_coords() methods of Point are deprecated in favor of the tuple property. • The cascaded_union property of MultiPolygon is deprecated in favor of the unary_union property. • The django.contrib.gis.utils.precision_wkt() function is deprecated in favor of WKTWriter. CommaSeparatedIntegerField model field CommaSeparatedIntegerField is deprecated in validate_comma_separated_integer_list() validator:

from django.core.validators import validate_comma_separated_integer_list from django.db import models class MyModel(models.Model): numbers = models.CharField(..., validators=[validate_comma_separated_integer_ ˓→list])

If you’re using Oracle, CharField uses a different database field type (NVARCHAR2) than CommaSeparatedIntegerField (VARCHAR2). Depending on your database settings, this might imply a different encoding, and thus a different length (in bytes) for the same contents. If your stored values are longer than the 4000 byte limit of NVARCHAR2, you should use TextField (NCLOB) instead. In this case, if you have any queries that group by the field (e.g. annotating the model with an aggregation or using distinct()) you’ll need to change them (to defer the field). Using a model name as a query lookup when default_related_name is set Assume the following models: from django.db import models class Foo(models.Model): pass class Bar(models.Model): foo = models.ForeignKey(Foo) class Meta: default_related_name = 'bars'

In older versions, default_related_name couldn’t be used as a query lookup. This is fixed and support for the old lookup name is deprecated. For example, since default_related_name is set in model Bar, instead of using the model name bar as the lookup: >>> bar = Bar.objects.get(pk=1) >>> Foo.objects.get(bar=bar)

Chapter 9. Release notes

__search query lookup The search lookup, which supports MySQL only and is extremely limited in features, is deprecated. Replace it with a custom lookup: from django.db import models class Search(models.Lookup): lookup_name = 'search' def as_mysql(self, compiler, connection): lhs, lhs_params = self.process_lhs(compiler, connection) rhs, rhs_params = self.process_rhs(compiler, connection) params = lhs_params + rhs_params return 'MATCH (%s) AGAINST (%s IN BOOLEAN MODE)' % (lhs, rhs), params models.CharField.register_lookup(Search) models.TextField.register_lookup(Search)

Using User.is_authenticated() and User.is_anonymous() as methods The is_authenticated() and is_anonymous() methods of AbstractBaseUser and AnonymousUser classes are now properties. They will still work as methods until Django 2.0, but all usage in Django now uses attribute access. For example, if you use AuthenticationMiddleware and want to know whether the user is currently logged-in you would use: if request.user.is_authenticated: ... # Do something for logged-in users. else: ... # Do something for anonymous users.

instead of request.user.is_authenticated(). This change avoids accidental information leakage if you forget to call the method, e.g.: if request.user.is_authenticated: return sensitive_information

If you override these methods in a custom user model, you must change them to properties or attributes. Django uses a CallableBool object to allow these attributes to work as both a property and a method. Thus, until the deprecation period ends, you cannot compare these properties using the is operator. That is, the following won’t work: if request.user.is_authenticated is True: ...

9.1. Final releases

If you defined a custom manager class available through prefetch_related() you must make sure it defines a _apply_rel_filters() method. This method must accept a QuerySet instance as its single argument and return a filtered version of the queryset for the model instance the manager is bound to. The “escape” half of django.utils.safestring The mark_for_escaping() function and the classes it uses: EscapeData, EscapeBytes, EscapeText, EscapeString, and EscapeUnicode are deprecated. As a result, the “lazy” behavior of the escape filter (where it would always be applied as the last filter no matter where in the filter chain it appeared) is deprecated. The filter will change to immediately apply conditional_escape() in Django 2.0. Manager.use_for_related_fields and inheritance changes Manager.use_for_related_fields is deprecated in favor of setting Meta.base_manager_name on the model. Model Manager inheritance will follow MRO inheritance rules in Django 2.0, changing the current behavior where managers defined on non-abstract base classes aren’t inherited by child classes. A deprecating warning with instructions on how to adapt your code is raised if you have any affected managers. You’ll either redeclare a manager from an abstract model on the child class to override the manager from the concrete model, or you’ll set the model’s Meta.manager_inheritance_from_future=True option to opt-in to the new inheritance behavior. During the deprecation period, use_for_related_fields will be honored and raise a warning, even if a base_manager_name is set. This allows third-party code to preserve legacy behavior while transitioning to the new API. The warning can be silenced by setting silence_use_for_related_fields_deprecation=True on the manager. Miscellaneous • The makemigrations --exit option is deprecated in favor of the makemigrations --check option. • django.utils.functional.allow_lazy() is deprecated in favor of the new keep_lazy() function which can be used with a more natural decorator syntax. • The shell --plain option is deprecated in favor of -i python or --interface python. • Importing from the django.core.urlresolvers module is deprecated in favor of its new location, django.urls. • The template Context.has_key() method is deprecated in favor of in. • The private attribute virtual_fields of Model._meta is deprecated in favor of private_fields. • The private keyword arguments virtual_only in Field.contribute_to_class() and virtual in Model._meta.add_field() are deprecated in favor of private_only and private, respectively. • The javascript_catalog() and json_catalog() views are deprecated in favor of class-based views JavaScriptCatalog and JSONCatalog.

Chapter 9. Release notes

• In multi-table inheritance, implicit promotion of a OneToOneField to a parent_link is deprecated. Add parent_link=True to such fields. • The private API Widget._format_value() is made public and renamed to format_value(). The old name will work through a deprecation period. • Private FileField methods get_directory_name() and get_filename() are deprecated in favor of performing this work in Storage.generate_filename()). • Old-style middleware that uses settings.MIDDLEWARE_CLASSES are deprecated. Adapt old, custom middleware and use the new MIDDLEWARE setting. Features removed in 1.10 These features have reached the end of their deprecation cycle and are removed in Django 1.10. See Features deprecated in 1.8 for details, including how to remove usage of these features. • Support for calling a SQLCompiler directly as an alias for calling its quote_name_unless_alias method is removed. • The cycle and firstof template tags are removed from the future template tag library. • django.conf.urls.patterns() is removed. • Support for the prefix argument to django.conf.urls.i18n.i18n_patterns() is removed. • SimpleTestCase.urls is removed. • Using an incorrect count of unpacked values in the for template tag raises an exception rather than failing silently. • The ability to reverse() URLs using a dotted Python path is removed. • The ability to use a dotted Python path for the LOGIN_URL and LOGIN_REDIRECT_URL settings is removed. • Support for optparse is dropped for custom management commands. • The class django.core.management.NoArgsCommand is removed. • django.core.context_processors module is removed. • django.db.models.sql.aggregates module is removed. • django.contrib.gis.db.models.sql.aggregates module is removed. • The following methods and properties of django.db.sql.query.Query are removed: – Properties: aggregates and aggregate_select – Methods: add_aggregate, set_aggregate_mask, and append_aggregate_mask. • django.template.resolve_variable is removed. • The following private APIs are removed from django.db.models.options.Options (Model. _meta): – get_field_by_name() – get_all_field_names() – get_fields_with_model() – get_concrete_fields_with_model() – get_m2m_with_model()

9.1. Final releases

– get_all_related_objects() – get_all_related_objects_with_model() – get_all_related_many_to_many_objects() – get_all_related_m2m_objects_with_model() • The error_message argument of django.forms.RegexField is removed. • The unordered_list filter no longer supports old style lists. • Support for string view arguments to url() is removed. • The backward compatible has_changed() is removed.

• The removetags template filter is removed. • The remove_tags() and strip_entities() functions in django.utils.html is removed. • The is_admin_site argument to django.contrib.auth.views.password_reset() is removed. • django.db.models.field.subclassing.SubfieldBase is removed. • django.utils.checksums is removed. • The original_content_type_id InlineAdminForm is removed.

django.contrib.admin.helpers.

• The backwards compatibility shim to allow FormMixin.get_form() to be defined with no default value for its form_class argument is removed. • The following settings are removed, and you must upgrade to the TEMPLATES setting: – ALLOWED_INCLUDE_ROOTS – TEMPLATE_CONTEXT_PROCESSORS – TEMPLATE_DEBUG – TEMPLATE_DIRS – TEMPLATE_LOADERS – TEMPLATE_STRING_IF_INVALID • The backwards compatibility alias django.template.loader.BaseLoader is removed. • Django template objects returned by get_template() and select_template() no longer accept a Context in their render() method. • Template response APIs enforce the use of dict and backend-dependent template objects instead of Context and Template respectively. • The current_app parameter for the following function and classes is removed: – django.shortcuts.render() – django.template.Context() – django.template.RequestContext() – django.template.response.TemplateResponse() • The dictionary and context_instance parameters for the following functions are removed: – django.shortcuts.render()

Chapter 9. Release notes

– django.shortcuts.render_to_response() – django.template.loader.render_to_string() • The dirs parameter for the following functions is removed: – django.template.loader.get_template() – django.template.loader.select_template() – django.shortcuts.render() – django.shortcuts.render_to_response() • Session verification is enabled regardless of whether or not 'django.contrib.auth. middleware.SessionAuthenticationMiddleware' is in MIDDLEWARE_CLASSES. SessionAuthenticationMiddleware no longer has any purpose and can be removed from MIDDLEWARE_CLASSES. It’s kept as a stub until Django 2.0 as a courtesy for users who don’t read this note. • Private attribute django.db.models.Field.related is removed. • The --list option of the migrate management command is removed. • The ssi template tag is removed. • Support for the = comparison operator in the if template tag is removed. • The backwards compatibility shims to allow Storage.get_available_name() and Storage. save() to be defined without a max_length argument are removed. • Support for the legacy %()s syntax in ModelFormMixin.success_url is removed. • GeoQuerySet aggregate methods collect(), extent(), extent3d(), make_line(), and unionagg() are removed. • The ability to specify ContentType.name when creating a content type instance is removed. • Support for the old signature of allow_migrate is removed. • Support for the syntax of {% cycle %} that uses comma-separated arguments is removed. • The warning that Signer issued when given an invalid separator is now a ValueError.

9.1.5 1.9 release Django 1.9.13 release notes April 4, 2017 Django 1.9.13 fixes two security issues and a bug in 1.9.12. This is the final release of the 1.9.x series. CVE-2017-7233: Open redirect and possible XSS attack via user-supplied numeric redirect URLs Django relies on user input in some cases (e.g. django.contrib.auth.views.login() and i18n) to redirect the user to an “on success” URL. The security check for these redirects (namely django.utils.http. is_safe_url()) considered some numeric URLs (e.g. http:999999999) “safe” when they shouldn’t be. Also, if a developer relies on is_safe_url() to provide safe redirect targets and puts such a URL into a link, they could suffer from an XSS attack.

9.1. Final releases

CVE-2017-7234: Open redirect vulnerability in django.views.static.serve() A maliciously crafted URL to a Django site using the serve() view could redirect to any other domain. The view no longer does any redirects as they don’t provide any known, useful functionality. Note, however, that this view has always carried a warning that it is not hardened for production use and should be used only as a development aid. Bugfixes • Fixed a regression in the timesince and timeuntil filters that caused incorrect results for dates in a leap year (#27637). Django 1.9.12 release notes December 1, 2016 Django 1.9.12 fixes a regression in 1.9.11. Bugfixes • Quoted the Oracle test user’s password in queries to fix the “ORA-00922: missing or invalid option” error when the password starts with a number or special character (#27420). Django 1.9.11 release notes November 1, 2016 Django 1.9.11 fixes two security issues in 1.9.10. User with hardcoded password created when running tests on Oracle When running tests with an Oracle database, Django creates a temporary database user. In older versions, if a password isn’t manually specified in the database settings TEST dictionary, a hardcoded password is used. This could allow an attacker with network access to the database server to connect. This user is usually dropped after the test suite completes, but not when using the manage.py test --keepdb option or if the user has an active session (such as an attacker’s connection). A randomly generated password is now used for each test run. DNS rebinding vulnerability when DEBUG=True Older versions of Django don’t validate the Host header against settings.ALLOWED_HOSTS when settings. DEBUG=True. This makes them vulnerable to a DNS rebinding attack. While Django doesn’t ship a module that allows remote code execution, this is at least a cross-site scripting vector, which could be quite serious if developers load a copy of the production database in development or connect to some production services for which there’s no development instance, for example. If a project uses a package like the django-debug-toolbar, then the attacker could execute arbitrary SQL, which could be especially bad if the developers connect to the database with a superuser account.

Chapter 9. Release notes

settings.ALLOWED_HOSTS is now validated regardless of DEBUG. For convenience, if ALLOWED_HOSTS is empty and DEBUG=True, the following variations of localhost are allowed ['localhost', '127.0.0.1', '::1']. If your local settings file has your production ALLOWED_HOSTS value, you must now omit it to get those fallback values. Django 1.9.10 release notes September 26, 2016 Django 1.9.10 fixes a security issue in 1.9.9. CSRF protection bypass on a site with Google Analytics An interaction between Google Analytics and Django’s cookie parsing could allow an attacker to set arbitrary cookies leading to a bypass of CSRF protection. The parser for request.COOKIES is simplified to better match the behavior of browsers and to mitigate this attack. request.COOKIES may now contain cookies that are invalid according to RFC 6265 but are possible to set via document.cookie. Django 1.9.9 release notes August 1, 2016 Django 1.9.9 fixes several bugs in 1.9.8. Bugfixes • Fixed invalid HTML in template postmortem on the debug page (#26938). • Fixed some GIS database function crashes on MySQL 5.7 (#26657). Django 1.9.8 release notes July 18, 2016 Django 1.9.8 fixes a security issue and several bugs in 1.9.7. XSS in admin’s add/change related popup Unsafe usage of JavaScript’s Element.innerHTML could result in XSS in the admin’s add/change related popup. Element.textContent is now used to prevent execution of the data. The debug view also used innerHTML. Although a security issue wasn’t identified there, out of an abundance of caution it’s also updated to use textContent. Bugfixes • Fixed missing varchar/text_pattern_ops index on CharField and TextField respectively when using AddField on PostgreSQL (#26889). • Fixed makemessages crash on Python 2 with non-ASCII file names (#26897). 9.1. Final releases

Django 1.9.7 release notes June 4, 2016 Django 1.9.7 fixes several bugs in 1.9.6. Bugfixes • Removed the need for the request context processor on the admin login page to fix a regression in 1.9 (#26558). • Fixed translation of password validators’ help_text in forms (#26544). • Fixed a regression causing the cached template loader to crash when using lazy template names (#26603). • Fixed on_commit callbacks execution order when callbacks make transactions (#26627). • Fixed HStoreField to raise a ValidationError instead of crashing on non-dictionary JSON input (#26672). • Fixed dbshell crash on PostgreSQL with an empty database name (#26698). • Fixed a regression in queries on a OneToOneField that has to_field and primary_key=True (#26667). Django 1.9.6 release notes May 2, 2016 Django 1.9.6 fixes several bugs in 1.9.5. Bugfixes • Added support for relative path redirects to the test client and to SimpleTestCase.assertRedirects() because Django 1.9 no longer converts redirects to absolute URIs (#26428). • Fixed TimeField microseconds round-tripping on MySQL and SQLite (#26498). • Prevented makemigrations from generating infinite migrations for a model field that references a functools.partial (#26475). • Fixed a regression where SessionBase.pop() returned None rather than raising a KeyError for nonexistent values (#26520). • Fixed a regression causing the cached template loader to crash when using template names starting with a dash (#26536). • Restored conversion of an empty string to null when saving values of GenericIPAddressField on SQLite and MySQL (#26557). • Fixed a makemessages regression where temporary .py extensions were leaked in source file paths (#26341). Django 1.9.5 release notes April 1, 2016 Django 1.9.5 fixes several bugs in 1.9.4.

Chapter 9. Release notes

Bugfixes • Made MultiPartParser ignore filenames that normalize to an empty string to fix crash in MemoryFileUploadHandler on specially crafted user input (#26325). • Fixed a race condition in BaseCache.get_or_set() (#26332). It now returns the default value instead of False if there’s an error when trying to add the value to the cache. • Fixed data loss on SQLite where DurationField values with fractional seconds could be saved as None (#26324). • The forms in contrib.auth no longer strip trailing and leading whitespace from the password fields (#26334). The change requires users who set their password to something with such whitespace after a site updated to Django 1.9 to reset their password. It provides backwards-compatibility for earlier versions of Django. • Fixed a memory leak in the cached template loader (#26306). • Fixed a regression that caused collectstatic --clear to fail if the storage doesn’t implement path() (#26297). • Fixed a crash when using a reverse lookup with a subquery when a ForeignKey has a to_field set to something other than the primary key (#26373). • Fixed a regression in CommonMiddleware that caused spurious warnings in logs on requests missing a trailing slash (#26293). • Restored the functionality of the admin’s raw_id_fields in list_editable (#26387). • Fixed a regression with abstract model inheritance and explicit parent links (#26413). • Fixed a migrations crash on SQLite when renaming the primary key of a model containing a ForeignKey to 'self' (#26384). • Fixed JSONField inadvertently escaping its contents when displaying values after failed form validation (#25532). Django 1.9.4 release notes March 5, 2016 Django 1.9.4 fixes a regression on Python 2 in the 1.9.3 security release where utils.http.is_safe_url() crashes on bytestring URLs (#26308). Django 1.9.3 release notes March 1, 2016 Django 1.9.3 fixes two security issues and several bugs in 1.9.2. CVE-2016-2512: Malicious redirect and possible XSS attack via user-supplied redirect URLs containing basic auth Django relies on user input in some cases (e.g. django.contrib.auth.views.login() and i18n) to redirect the user to an “on success” URL. The security check for these redirects (namely django.utils.http. is_safe_url()) considered some URLs with basic authentication credentials “safe” when they shouldn’t be. For example, a URL like http://mysite.example.com\@attacker.com would be considered safe if the request’s host is http://mysite.example.com, but redirecting to this URL sends the user to attacker.com.

9.1. Final releases

Also, if a developer relies on is_safe_url() to provide safe redirect targets and puts such a URL into a link, they could suffer from an XSS attack. CVE-2016-2513: User enumeration through timing difference on password hasher work factor upgrade In each major version of Django since 1.6, the default number of iterations for the PBKDF2PasswordHasher and its subclasses has increased. This improves the security of the password as the speed of hardware increases, however, it also creates a timing difference between a login request for a user with a password encoded in an older number of iterations and login request for a nonexistent user (which runs the default hasher’s default number of iterations since Django 1.6). This only affects users who haven’t logged in since the iterations were increased. The first time a user logs in after an iterations increase, their password is updated with the new iterations and there is no longer a timing difference. The new BasePasswordHasher.harden_runtime() method allows hashers to bridge the runtime gap between the work factor (e.g. iterations) supplied in existing encoded passwords and the default work factor of the hasher. This method is implemented for PBKDF2PasswordHasher and BCryptPasswordHasher. The number of rounds for the latter hasher hasn’t changed since Django 1.4, but some projects may subclass it and increase the work factor as needed. A warning will be emitted for any third-party password hashers that don’t implement a harden_runtime() method. If you have different password hashes in your database (such as SHA1 hashes from users who haven’t logged in since the default hasher switched to PBKDF2 in Django 1.4), the timing difference on a login request for these users may be even greater and this fix doesn’t remedy that difference (or any difference when changing hashers). You may be able to upgrade those hashes to prevent a timing attack for that case. Bugfixes • Skipped URL checks (new in 1.9) if the ROOT_URLCONF setting isn’t defined (#26155). • Fixed a crash on PostgreSQL that prevented using TIME_ZONE=None and USE_TZ=False (#26177). • Added system checks for query name clashes of hidden relationships (#26162). • Fixed a regression for cases where ForeignObject.get_extra_descriptor_filter() returned a Q object (#26153). • Fixed regression with an __in=qs lookup for a ForeignKey with to_field set (#26196). • Made forms.FileField and utils.translation.lazy_number() picklable (#26212). • Fixed RangeField and ArrayField serialization with None values (#26215). • Fixed a crash when filtering by a Decimal in RawQuery (#26219). • Reallowed dashes in top-level domain names of URLs checked by URLValidator to fix a regression in Django 1.8 (#26204). • Fixed some crashing deprecation shims in SimpleTemplateResponse that regressed in Django 1.9 (#26253). • Fixed BoundField to reallow slices of subwidgets (#26267). • Changed the admin’s “permission denied” message in the login template to use get_username instead of username to support custom user models (#26231).

Chapter 9. Release notes

• Fixed a crash when passing a nonexistent template name to the cached template loader’s load_template() method (#26280). • Prevented ContentTypeManager instances from sharing their cache (#26286). • Reverted a change in Django 1.9.2 (#25858) that prevented relative lazy relationships defined on abstract models to be resolved according to their concrete model’s app_label (#26186). Django 1.9.2 release notes February 1, 2016 Django 1.9.2 fixes a security regression in 1.9 and several bugs in 1.9.1. It also makes a small backwards incompatible change that hopefully doesn’t affect any users. Security issue: User with “change” but not “add” permission can create objects for ModelAdmin’s with save_as=True If a ModelAdmin uses save_as=True (not the default), the admin provides an option when editing objects to “Save as new”. A regression in Django 1.9 prevented that form submission from raising a “Permission Denied” error for users without the “add” permission. Backwards incompatible change: .py-tpl files rewritten in project/app templates The addition of some Django template language syntax to the default app template in Django 1.9 means those files now have some invalid Python syntax. This causes difficulties for packaging systems that unconditionally byte-compile *. py files. To remedy this, a .py-tpl suffix is now used for the project and app template files included in Django. The . py-tpl suffix is replaced with .py by the startproject and startapp commands. For example, a template with the filename manage.py-tpl will be created as manage.py. Please file a ticket if you have a custom project template containing .py-tpl files and find this behavior problematic. Bugfixes • Fixed a regression in ConditionalGetMiddleware causing If-None-Match checks to always return HTTP 200 (#26024). • Fixed a regression that caused the “user-tools” items to display on the admin’s logout page (#26035). • Fixed a crash in the translations system when the current language has no translations (#26046). • Fixed a regression that caused the incorrect day to be selected when opening the admin calendar widget for timezones from GMT+0100 to GMT+1200 (#24980). • Fixed a regression in the admin’s edit related model popup that caused an escaped value to be displayed in the select dropdown of the parent window (#25997). • Fixed a regression in 1.8.8 causing incorrect index handling in migrations on PostgreSQL when adding db_index=True or unique=True to a CharField or TextField that already had the other specified, or when removing one of them from a field that had both, or when adding unique=True to a field already listed in unique_together (#26034).

9.1. Final releases

• Fixed a regression where defining a relation on an abstract model’s field using a string model name without an app_label no longer resolved that reference to the abstract model’s app if using that model in another application (#25858). • Fixed a crash when destroying an existing test database on MySQL or PostgreSQL (#26096). • Fixed CSRF cookie check on POST requests when USE_X_FORWARDED_PORT=True (#26094). • Fixed a QuerySet.order_by() crash when ordering by a relational field of a ManyToManyField through model (#26092). • Fixed a regression that caused an exception when making database queries on SQLite with more than 2000 parameters when DEBUG is True on distributions that increase the SQLITE_MAX_VARIABLE_NUMBER compile-time limit to over 2000, such as Debian (#26063). • Fixed a crash when using a reverse OneToOneField in ModelAdmin.readonly_fields (#26060). • Fixed a crash when calling the migrate command in a test case with the available_apps attribute pointing to an application with migrations disabled using the MIGRATION_MODULES setting (#26135). • Restored the ability for testing and debugging tools to determine the template from which a node came from, even during template inheritance or inclusion. Prior to Django 1.9, debugging tools could access the template origin from the node via Node.token.source[0]. This was an undocumented, private API. The origin is now available directly on each node using the Node.origin attribute (#25848). • Fixed a regression in Django 1.8.5 that broke copying a SimpleLazyObject with copy.copy() (#26122). • Always included geometry_field in the GeoJSON serializer output regardless of the fields parameter (#26138). • Fixed the contrib.gis map widgets when using USE_THOUSAND_SEPARATOR=True (#20415). • Made invalid forms display the initial of values of their disabled fields (#26129). Django 1.9.1 release notes January 2, 2016 Django 1.9.1 fixes several bugs in 1.9. Bugfixes • Fixed BaseCache.get_or_set() with the DummyCache backend (#25840). • Fixed a regression in FormMixin causing forms to be validated twice (#25548, #26018). • Fixed a system check crash with nested ArrayFields (#25867). • Fixed a state bug when migrating a SeparateDatabaseAndState operation backwards (#25896). • Fixed a regression in CommonMiddleware causing If-None-Match checks to always return HTTP 200 (#25900). • Fixed missing varchar/text_pattern_ops index on CharField and TextField respectively when using AlterField on PostgreSQL (#25412). • Fixed admin’s delete confirmation page’s summary counts of related objects (#25883). • Added from __future__ import unicode_literals to the default apps.py created by startapp on Python 2 (#25909). Add this line to your own apps.py files created using Django 1.9 if you want your migrations to work on both Python 2 and Python 3.

Chapter 9. Release notes

• Prevented QuerySet.delete() from crashing on MySQL when querying across relations (#25882). • Fixed evaluation of zero-length slices of QuerySet.values() (#25894). • Fixed a state bug when using an AlterModelManagers operation (#25852). • Fixed TypedChoiceField change detection with nullable fields (#25942). • Fixed incorrect timezone warnings in custom admin templates that don’t have a data-admin-utc-offset attribute in the body tag. (#25845). • Fixed a regression which prevented using a language not in Django’s default language list (LANGUAGES) (#25915). • Avoided hiding some exceptions, like an invalid INSTALLED_APPS setting, behind AppRegistryNotReady when starting runserver (#25510). This regression appeared in 1.8.5 as a side effect of fixing #24704 and by mistake the fix wasn’t applied to the stable/1.9.x branch. • Fixed migrate --fake-initial detection of many-to-many tables (#25922). • Restored the functionality of the admin’s list_editable add and change buttons (#25903). • Fixed isnull query lookup for ForeignObject (#25972). • Fixed a regression in the admin which ignored line breaks in read-only fields instead of converting them to
(#25465). • Fixed incorrect object reference in SingleObjectMixin.get_context_object_name() (#26006). • Made loaddata skip disabling and enabling database constraints when it doesn’t load any fixtures (#23372). • Restored contrib.auth hashers compatibility with py-bcrypt (#26016). • Fixed a crash in QuerySet.values()/values_list() after an annotate() and order_by() when values()/values_list() includes a field not in the order_by() (#25316). Django 1.9 release notes December 1, 2015 Welcome to Django 1.9! These release notes cover the new features, as well as some backwards incompatible changes you’ll want to be aware of when upgrading from Django 1.8 or older versions. We’ve dropped some features that have reached the end of their deprecation cycle, and we’ve begun the deprecation process for some features. See the Upgrading Django to a newer version guide if you’re updating an existing project. Python compatibility Django 1.9 requires Python 2.7, 3.4, or 3.5. We highly recommend and only officially support the latest release of each series. The Django 1.8 series is the last to support Python 3.2 and 3.3.

9.1. Final releases

What’s new in Django 1.9 Performing actions after a transaction commit The new on_commit() hook allows performing actions after a database transaction is successfully committed. This is useful for tasks such as sending notification emails, creating queued tasks, or invalidating caches. This functionality from the django-transaction-hooks package has been integrated into Django. Password validation Django now offers password validation to help prevent the usage of weak passwords by users. The validation is integrated in the included password change and reset forms and is simple to integrate in any other code. Validation is performed by one or more validators, configured in the new AUTH_PASSWORD_VALIDATORS setting. Four validators are included in Django, which can enforce a minimum length, compare the password to the user’s attributes like their name, ensure passwords aren’t entirely numeric, or check against an included list of common passwords. You can combine multiple validators, and some validators have custom configuration options. For example, you can choose to provide a custom list of common passwords. Each validator provides a help text to explain its requirements to the user. By default, no validation is performed and all passwords are accepted, so if you don’t set AUTH_PASSWORD_VALIDATORS, you will not see any change. In new projects created with the default startproject template, a simple set of validators is enabled. To enable basic validation in the included auth forms for your project, you could set, for example: AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation. ˓→UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ]

See Password validation for more details. Permission mixins for class-based views Django now ships with the mixins AccessMixin, LoginRequiredMixin, PermissionRequiredMixin, and UserPassesTestMixin to provide the functionality of the django.contrib.auth.decorators for class-based views. These mixins have been taken from, or are at least inspired by, the django-braces project. There are a few differences between Django’s and django-braces‘ implementation, though: • The raise_exception attribute can only be True or False. Custom exceptions or callables are not supported.

Chapter 9. Release notes

• The handle_no_permission() method does not take a request argument. The current request is available in self.request. • The custom test_func() of UserPassesTestMixin does not take a user argument. The current user is available in self.request.user. • The permission_required attribute supports a string (defining one permission) or a list/tuple of strings (defining multiple permissions) that need to be fulfilled to grant access. • The new permission_denied_message attribute allows passing a message to the PermissionDenied exception. New styling for contrib.admin The admin sports a modern, flat design with new SVG icons which look perfect on HiDPI screens. It still provides a fully-functional experience to YUI’s A-grade browsers. Older browser may experience varying levels of graceful degradation. Running tests in parallel The test command now supports a --parallel option to run a project’s tests in multiple processes in parallel. Each process gets its own database. You must ensure that different test cases don’t access the same resources. For instance, test cases that touch the filesystem should create a temporary directory for their own use. This option is enabled by default for Django’s own test suite provided: • the OS supports it (all but Windows) • the database backend supports it (all the built-in backends but Oracle) Minor features django.contrib.admin • Admin views now have model_admin or admin_site attributes. • The URL of the admin change view has been changed (was at /admin//// by default and is now at /admin////change/). This should not affect your application unless you have hardcoded admin URLs. In that case, replace those links by reversing admin URLs instead. Note that the old URL still redirects to the new one for backwards compatibility, but it may be removed in a future version. • ModelAdmin.get_list_select_related() was added to allow changing the select_related() values used in the admin’s changelist query based on the request. • The available_apps context variable, which lists the available applications for the current user, has been added to the AdminSite.each_context() method. • AdminSite.empty_value_display and ModelAdmin.empty_value_display were added to override the display of empty values in admin change list. You can also customize the value for each field. • Added jQuery events when an inline form is added or removed on the change form page. • The time picker widget includes a ‘6 p.m’ option for consistency of having predefined options every 6 hours. • JavaScript slug generation now supports Romanian characters.

9.1. Final releases

django.contrib.admindocs • The model section of the admindocs now also describes methods that take arguments, rather than ignoring them. django.contrib.auth • The default iteration count for the PBKDF2 password hasher has been increased by 20%. This backwards compatible change will not affect users who have subclassed django.contrib.auth.hashers. PBKDF2PasswordHasher to change the default value. • The BCryptSHA256PasswordHasher will now update passwords if its rounds attribute is changed. • AbstractBaseUser and BaseUserManager were moved to a new django.contrib.auth. base_user module so that they can be imported without including django.contrib.auth in INSTALLED_APPS (doing so raised a deprecation warning in older versions and is no longer supported in Django 1.9). • The permission argument of permission_required() accepts all kinds of iterables, not only list and tuples. • The new PersistentRemoteUserMiddleware makes it possible to use REMOTE_USER for setups where the header is only populated on login pages instead of every request in the session. • The django.contrib.auth.views.password_reset() extra_email_context parameter.

django.contrib.contenttypes • It’s now possible to use order_with_respect_to with a GenericForeignKey. django.contrib.gis • All GeoQuerySet methods have been deprecated and replaced by equivalent database functions. As soon as the legacy methods have been replaced in your code, you should even be able to remove the special GeoManager from your GIS-enabled classes. • The GDAL interface now supports instantiating file-based and in-memory GDALRaster objects from raw data. Setters for raster properties such as projection or pixel values have been added. • For PostGIS users, the new RasterField allows storing GDALRaster objects. It supports automatic spatial index creation and reprojection when saving a model. It does not yet support spatial querying. • The new GDALRaster.warp() method allows warping a raster by specifying target raster properties such as origin, width, height, or pixel size (amongst others). • The new GDALRaster.transform() method allows transforming a raster into a different spatial reference system by specifying a target srid. • The new GeoIP2 class allows using MaxMind’s GeoLite2 databases which includes support for IPv6 addresses. • The default OpenLayers library version included in widgets has been updated from 2.13 to 2.13.1.

Chapter 9. Release notes

django.contrib.postgres • Added support for the rangefield.contained_by lookup for some built in fields which correspond to the range fields. • Added JSONField. • Added PostgreSQL specific aggregation functions. • Added the TransactionNow database function. django.contrib.sessions • The session model and SessionStore classes for the db and cached_db backends are refactored to allow a custom database session backend to build upon them. See Extending database-backed session engines for more details. django.contrib.sites • get_current_site() now handles the case where request.get_host() returns domain:port, e.g. example.com:80. If the lookup fails because the host does not match a record in the database and the host has a port, the port is stripped and the lookup is retried with the domain part only. django.contrib.syndication • Support for multiple enclosures per feed item has been added. If multiple enclosures are defined on a RSS feed, an exception is raised as RSS feeds, unlike Atom feeds, do not support multiple enclosures per feed item. Cache • django.core.cache.backends.base.BaseCache now has a get_or_set() method. • django.views.decorators.cache.never_cache() now sends more persuasive headers (added no-cache, no-store, must-revalidate to Cache-Control) to better prevent caching. This was also added in Django 1.8.8. CSRF • The request header’s name used for CSRF authentication can be customized with CSRF_HEADER_NAME. • The CSRF referer header is now validated against the CSRF_COOKIE_DOMAIN setting if set. See How it works for details. • The new CSRF_TRUSTED_ORIGINS setting provides a way to allow cross-origin unsafe requests (e.g. POST) over HTTPS. Database backends • The PostgreSQL backend (django.db.backends.postgresql_psycopg2) is also available as django.db.backends.postgresql. The old name will continue to be available for backwards compatibility. 9.1. Final releases

File Storage • Storage.get_valid_name() is now called when the upload_to is a callable. • File now has the seekable() method when using Python 3. Forms • ModelForm accepts the new Meta option field_classes to customize the type of the fields. See Overriding the default fields for details. • You can now specify the order in which form fields are rendered with the field_order attribute, the field_order constructor argument , or the order_fields() method. • A form prefix can be specified inside a form class, not only when instantiating a form. See Prefixes for forms for details. • You can now specify keyword arguments that you want to pass to the constructor of forms in a formset. • SlugField now accepts an allow_unicode argument to allow Unicode characters in slugs. • CharField now accepts a strip argument to strip input data of leading and trailing whitespace. As this defaults to True this is different behavior from previous releases. • Form fields now support the disabled argument, allowing the field widget to be displayed disabled by browsers. • It’s now possible to customize bound fields by overriding a field’s get_bound_field() method. Generic Views • Class-based views generated using as_view() now have view_class and view_initkwargs attributes. • method_decorator() can now be used with a list or tuple of decorators. It can also be used to decorate classes instead of methods. Internationalization • The django.views.i18n.set_language() view now properly redirects to translated URLs, when available. • The django.views.i18n.javascript_catalog() view now works correctly if used multiple times with different configurations on the same page. • The django.utils.timezone.make_aware() function gained an is_dst argument to help resolve ambiguous times during DST transitions. • You can now use locale variants supported by gettext. These are usually used for languages which can be written in different scripts, for example Latin and Cyrillic (e.g. [emailprotected]). • Added the django.views.i18n.json_catalog() view to help build a custom client-side i18n library upon Django translations. It returns a JSON object containing a translations catalog, formatting settings, and a plural rule. • Added the name_translated attribute to the object returned by the get_language_info template tag. Also added a corresponding template filter: language_name_translated.

Chapter 9. Release notes

• You can now run compilemessages from the root directory of your project and it will find all the app message files that were created by makemessages. • makemessages now calls xgettext once per locale directory rather than once per translatable file. This speeds up localization builds. • blocktrans supports assigning its output to a variable using asvar. • Two new languages are available: Colombian Spanish and Scottish Gaelic. Management Commands • The new sendtestemail command lets you send a test email to easily confirm that email sending through Django is working. • To increase the readability of the SQL code generated by sqlmigrate, the SQL code generated for each migration operation is preceded by the operation’s description. • The dumpdata command output is now deterministically ordered. Moreover, when the --output option is specified, it also shows a progress bar in the terminal. • The createcachetable command now has a --dry-run flag to print out the SQL rather than execute it. • The startapp command creates an apps.py file. Since it doesn’t use default_app_config (a discouraged API), you must specify the app config’s path, e.g. 'polls.apps.PollsConfig', in INSTALLED_APPS for it to be used (instead of just 'polls'). • When using the PostgreSQL backend, the dbshell command can connect to the database using the password from your settings file (instead of requiring it to be manually entered). • The django package may be run as a script, i.e. python -m django, which will behave the same as django-admin. • Management commands that have the --noinput option now also take --no-input as an alias for that option. Migrations • Initial migrations are now marked with an initial = True class attribute which allows migrate --fake-initial to more easily detect initial migrations. • Added support for serialization of functools.partial and LazyObject instances. • When supplying None as a value in MIGRATION_MODULES, Django will consider the app an app without migrations. • When applying migrations, the “Rendering model states” step that’s displayed when running migrate with verbosity 2 or higher now computes only the states for the migrations that have already been applied. The model states for migrations being applied are generated on demand, drastically reducing the amount of required memory. However, this improvement is not available when unapplying migrations and therefore still requires the precomputation and storage of the intermediate migration states. This improvement also requires that Django no longer supports mixed migration plans. Mixed plans consist of a list of migrations where some are being applied and others are being unapplied. This was never officially supported and never had a public API that supports this behavior. • The squashmigrations command now supports specifying the starting migration from which migrations will be squashed.

9.1. Final releases

Models • QuerySet.bulk_create() now works on proxy models. • Database configuration gained a TIME_ZONE option for interacting with databases that store datetimes in local time and don’t support time zones when USE_TZ is True. • Added the RelatedManager.set() method to the related managers created by ForeignKey, GenericForeignKey, and ManyToManyField. • The add() method on a reverse foreign key now has a bulk parameter to allow executing one query regardless of the number of objects being added rather than one query per object. • Added the keep_parents parameter to Model.delete() to allow deleting only a child’s data in a model that uses multi-table inheritance. • Model.delete() and QuerySet.delete() return the number of objects deleted. • Added a system check to prevent defining both Meta.ordering and order_with_respect_to on the same model. • Date and time lookups can be chained with other lookups (such as exact, gt, lt, etc.). For example: Entry.objects.filter(pub_date__month__gt=6). • Time lookups (hour, minute, second) are now supported by TimeField for all database backends. Support for backends other than SQLite was added but undocumented in Django 1.7. • You can specify the output_field parameter of the Avg aggregate in order to aggregate over non-numeric columns, such as DurationField. • Added the date lookup to DateTimeField to allow querying the field by only the date portion. • Added the Greatest and Least database functions. • Added the Now database function, which returns the current date and time. • Transform is now a subclass of Func() which allows Transforms to be used on the right hand side of an expression, just like regular Funcs. This allows registering some database functions like Length, Lower, and Upper as transforms. • SlugField now accepts an allow_unicode argument to allow Unicode characters in slugs. • Added support for referencing annotations in QuerySet.distinct(). • connection.queries shows queries with substituted parameters on SQLite. • Query expressions can now be used when creating new model instances using save(), create(), and bulk_create(). Requests and Responses • Unless HttpResponse.reason_phrase is explicitly set, it now is determined by the current value of HttpResponse.status_code. Modifying the value of status_code outside of the constructor will also modify the value of reason_phrase. • The debug view now shows details of chained exceptions on Python 3. • The default 40x error views now accept a second positional parameter, the exception that triggered the view. • View error handlers now support TemplateResponse, commonly used with class-based views. • Exceptions raised by the render() method are now passed to the process_exception() method of each middleware.

Chapter 9. Release notes

• Request middleware can now set HttpRequest.urlconf to None to revert any changes made by previous middleware and return to using the ROOT_URLCONF. • The DISALLOWED_USER_AGENTS check in CommonMiddleware now raises a PermissionDenied exception as opposed to returning an HttpResponseForbidden so that handler403 is invoked. • Added HttpRequest.get_port() to fetch the originating port of the request. • Added the json_dumps_params parameter to JsonResponse to allow passing keyword arguments to the json.dumps() call used to generate the response. • The BrokenLinkEmailsMiddleware now ignores 404s when the referer is equal to the requested URL. To circumvent the empty referer check already implemented, some Web bots set the referer to the requested URL. Templates • Template tags created with the simple_tag() helper can now store results in a template variable by using the as argument. • Added a Context.setdefault() method. • The django.template logger was added and includes the following messages: – A DEBUG level message for missing context variables. – A WARNING level message for uncaught exceptions raised during the rendering of an {% include %} when debug mode is off (helpful since {% include %} silences the exception and returns an empty string). • The firstof template tag supports storing the output in a variable using ‘as’. • Context.update() can now be used as a context manager. • Django template loaders can now extend templates recursively. • The debug page template postmortem now include output from each engine that is installed. • Debug page integration for custom template engines was added. • The DjangoTemplates backend gained the ability to register libraries and builtins explicitly through the template OPTIONS. • The timesince and timeuntil filters were improved to deal with leap years when given large time spans. • The include tag now caches parsed templates objects during template rendering, speeding up reuse in places such as for loops. Tests • Added the json() method to test client responses to give access to the response body as JSON. • Added the force_login() method to the test client. Use this method to simulate the effect of a user logging into the site while skipping the authentication and verification steps of login(). URLs • Regular expression lookaround assertions are now allowed in URL patterns.

9.1. Final releases

• The application namespace can now be set using an app_name attribute on the included module or object. It can also be set by passing a 2-tuple of (, ) as the first argument to include(). • System checks have been added for common URL pattern mistakes. Validators • Added django.core.validators.int_list_validator() to generate validators of strings containing integers separated with a custom character. • EmailValidator now limits the length of domain name labels to 63 characters per RFC 1034. • Added validate_unicode_slug() to validate slugs that may contain Unicode characters. Backwards incompatible changes in 1.9

Warning: In addition to the changes outlined in this section, be sure to review the Features removed in 1.9 for the features that have reached the end of their deprecation cycle and therefore been removed. If you haven’t updated your code within the deprecation timeline for a given feature, its removal may appear as a backwards incompatible change. Database backend API • A couple of new tests rely on the ability of the backend to introspect column defaults (returning the result as Field.default). You can set the can_introspect_default database feature to False if your backend doesn’t implement this. You may want to review the implementation on the backends that Django includes for reference (#24245). • Registering a global adapter or converter at the level of the DB-API module to handle time zone information of datetime values passed as query parameters or returned as query results on databases that don’t support time zones is discouraged. It can conflict with other libraries. The recommended way to add a time zone to datetime values fetched from the database is to register a converter for DateTimeField in DatabaseOperations.get_db_converters(). The needs_datetime_string_cast database feature was removed. Database backends that set it must register a converter instead, as explained above. • The DatabaseOperations.value_to_db_() methods were renamed adapt_field_value() to mirror the convert_field_value() methods.

• To use the new date lookup, third-party database backends may need to implement the DatabaseOperations.datetime_cast_date_sql() method. • The DatabaseOperations.time_extract_sql() method was added. It calls the existing date_extract_sql() method. This method is overridden by the SQLite backend to add time lookups (hour, minute, second) to TimeField, and may be needed by third-party database backends. • The DatabaseOperations.datetime_cast_sql() method (not to be confused with DatabaseOperations.datetime_cast_date_sql() mentioned above) has been removed. This method served to format dates on Oracle long before 1.0, but hasn’t been overridden by any core backend in years and hasn’t been called anywhere in Django’s code or tests.

Chapter 9. Release notes

• In order to support test parallelization, you must implement the DatabaseCreation. _clone_test_db() method and set DatabaseFeatures.can_clone_databases = True. You may have to adjust DatabaseCreation.get_test_db_clone_settings(). Default settings that were tuples are now lists The default settings in django.conf.global_settings were a combination of lists and tuples. All settings that were formerly tuples are now lists. is_usable attribute on template loaders is removed Django template loaders previously required an is_usable attribute to be defined. If a loader was configured in the template settings and this attribute was False, the loader would be silently ignored. In practice, this was only used by the egg loader to detect if setuptools was installed. The is_usable attribute is now removed and the egg loader instead fails at runtime if setuptools is not installed. Related set direct assignment Direct assignment of related objects in the ORM used to perform a clear() followed by a call to add(). This caused needlessly large data changes and prevented using the m2m_changed signal to track individual changes in many-to-many relations. Direct assignment now relies on the the new set() method on related managers which by default only processes changes between the existing related set and the one that’s newly assigned. The previous behavior can be restored by replacing direct assignment by a call to set() with the keyword argument clear=True. ModelForm, and therefore ModelAdmin, internally rely on direct assignment for many-to-many relations and as a consequence now use the new behavior. Filesystem-based template loaders catch more specific exceptions When using the filesystem.Loader or app_directories.Loader template loaders, earlier versions of Django raised a TemplateDoesNotExist error if a template source existed but was unreadable. This could happen under many circumstances, such as if Django didn’t have permissions to open the file, or if the template source was a directory. Now, Django only silences the exception if the template source does not exist. All other situations result in the original IOError being raised. HTTP redirects no longer forced to absolute URIs Relative redirects are no longer converted to absolute URIs. RFC 2616 required the Location header in redirect responses to be an absolute URI, but it has been superseded by RFC 7231 which allows relative URIs in Location, recognizing the actual practice of user agents, almost all of which support them. Consequently, the expected URLs passed to assertRedirects should generally no longer include the scheme and domain part of the URLs. For example, self.assertRedirects(response, 'http://testserver/ some-url/') should be replaced by self.assertRedirects(response, '/some-url/') (unless the redirection specifically contained an absolute URL, of course). In the rare case that you need the old behavior (discovered with an ancient version of Apache with mod_scgi that interprets a relative redirect as an “internal redirect”), you can restore it by writing a custom middleware:

9.1. Final releases

class LocationHeaderFix(object): def process_response(self, request, response): if 'Location' in response: response['Location'] = request.build_absolute_uri(response['Location']) return response

Dropped support for PostgreSQL 9.0 Upstream support for PostgreSQL 9.0 ended in September 2015. As a consequence, Django 1.9 sets 9.1 as the minimum PostgreSQL version it officially supports. Dropped support for Oracle 11.1 Upstream support for Oracle 11.1 ended in August 2015. As a consequence, Django 1.9 sets 11.2 as the minimum Oracle version it officially supports. Bulk behavior of add() method of related managers To improve performance, the add() methods of the related managers created by ForeignKey and GenericForeignKey changed from a series of Model.save() calls to a single QuerySet.update() call. The change means that pre_save and post_save signals aren’t sent anymore. You can use the bulk=False keyword argument to revert to the previous behavior. Template LoaderOrigin and StringOrigin are removed In previous versions of Django, when a template engine was initialized with debug as True, an instance of django. template.loader.LoaderOrigin or django.template.base.StringOrigin was set as the origin attribute on the template object. These classes have been combined into Origin and is now always set regardless of the engine debug setting. For a minimal level of backwards compatibility, the old class names will be kept as aliases to the new Origin class until Django 2.0. Changes to the default logging configuration To make it easier to write custom logging configurations, Django’s default logging configuration no longer defines django.request and django.security loggers. Instead, it defines a single django logger, filtered at the INFO level, with two handlers: • console: filtered at the INFO level and only active if DEBUG=True. • mail_admins: filtered at the ERROR level and only active if DEBUG=False. If you aren’t overriding Django’s default logging, you should see minimal changes in behavior, but you might see some new logging to the runserver console, for example. If you are overriding Django’s default logging, you should check to see how your configuration merges with the new defaults.

Chapter 9. Release notes

HttpRequest details in error reporting It was redundant to display the full details of the HttpRequest each time it appeared as a stack frame variable in the HTML version of the debug page and error email. Thus, the HTTP request will now display the same standard representation as other variables (repr(request)). As a result, the ExceptionReporterFilter. get_request_repr() method and the undocumented django.http.build_request_repr() function were removed. The contents of the text version of the email were modified to provide a traceback of the same structure as in the case of AJAX requests. The traceback details are rendered by the ExceptionReporter.get_traceback_text() method. Removal of time zone aware global adapters and converters for datetimes Django no longer registers global adapters and converters for managing time zone information on datetime values sent to the database as query parameters or read from the database in query results. This change affects projects that meet all the following conditions: • The USE_TZ setting is True. • The database is SQLite, MySQL, Oracle, or a third-party database that doesn’t support time zones. In doubt, you can check the value of connection.features.supports_timezones. • The code queries the database outside of the ORM, typically with cursor.execute(sql, params). If you’re passing aware datetime parameters to such queries, you should turn them into naive datetimes in UTC: from django.utils import timezone param = timezone.make_naive(param, timezone.utc)

If you fail to do so, the conversion will be performed as in earlier versions (with a deprecation warning) up until Django 1.11. Django 2.0 won’t perform any conversion, which may result in data corruption. If you’re reading datetime values from the results, they will be naive instead of aware. You can compensate as follows: from django.utils import timezone value = timezone.make_aware(value, timezone.utc)

You don’t need any of this if you’re querying the database through the ORM, even if you’re using raw() queries. The ORM takes care of managing time zone information. Template tag modules are imported when templates are configured The DjangoTemplates backend now performs discovery on installed template tag modules when instantiated. This update enables libraries to be provided explicitly via the 'libraries' key of OPTIONS when defining a DjangoTemplates backend. Import or syntax errors in template tag modules now fail early at instantiation time rather than when a template with a {% load %} tag is first compiled. django.template.base.add_to_builtins() is removed Although it was a private API, projects commonly used add_to_builtins() to make template tags and filters available without using the {% load %} tag. This API has been formalized. Projects should now define built-in libraries via the 'builtins' key of OPTIONS when defining a DjangoTemplates backend.

9.1. Final releases

simple_tag now wraps tag output in conditional_escape In general, template tags do not autoescape their contents, and this behavior is documented. For tags like inclusion_tag, this is not a problem because the included template will perform autoescaping. For assignment_tag(), the output will be escaped when it is used as a variable in the template. For the intended use cases of simple_tag, however, it is very easy to end up with incorrect HTML and possibly an XSS exploit. For example: @register.simple_tag(takes_context=True) def greeting(context): return "Hello {0}!".format(context['request'].user.first_name)

In older versions of Django, this will be an XSS issue because user.first_name is not escaped. In Django 1.9, this is fixed: if the template context has autoescape=True set (the default), then simple_tag will wrap the output of the tag function with conditional_escape(). To fix your simple_tags, it is best to apply the following practices: • Any code that generates HTML should use either the template system or format_html(). • If the output of a simple_tag needs escaping, use escape() or conditional_escape(). • If you are absolutely certain that you are outputting HTML from a trusted source (e.g. a CMS field that stores HTML entered by admins), you can mark it as such using mark_safe(). Tags that follow these rules will be correct and safe whether they are run on Django 1.9+ or earlier. Paginator.page_range Paginator.page_range is now an iterator instead of a list. In versions of Django previous to 1.8, Paginator.page_range returned a list in Python 2 and a range in Python 3. Django 1.8 consistently returned a list, but an iterator is more efficient. Existing code that depends on list specific features, such as indexing, can be ported by converting the iterator into a list using list(). Implicit QuerySet __in lookup removed In earlier versions, queries such as: Model.objects.filter(related_id=RelatedModel.objects.all())

would implicitly convert to: Model.objects.filter(related_id__in=RelatedModel.objects.all())

resulting in SQL like "related_id IN (SELECT id FROM ...)". This implicit __in no longer happens so the “IN” SQL is now “=”, and if the subquery returns multiple results, at least some databases will throw an error.

Chapter 9. Release notes

contrib.admin browser support The admin no longer supports Internet Explorer 8 and below, as these browsers have reached end-of-life. CSS and images to support Internet Explorer 6 and 7 have been removed. PNG and GIF icons have been replaced with SVG icons, which are not supported by Internet Explorer 8 and earlier. The jQuery library embedded in the admin has been upgraded from version 1.11.2 to 2.1.4. jQuery 2.x has the same API as jQuery 1.x, but does not support Internet Explorer 6, 7, or 8, allowing for better performance and a smaller file size. If you need to support IE8 and must also use the latest version of Django, you can override the admin’s copy of jQuery with your own by creating a Django application with this structure: app/static/admin/js/vendor/ jquery.js jquery.min.js

SyntaxError when installing Django setuptools 5.5.x When installing Django 1.9 or 1.9.1 with setuptools 5.5.x, you’ll see: Compiling django/conf/app_template/apps.py ... File "django/conf/app_template/apps.py", line 4 class {{ camel_case_app_name }}Config(AppConfig): ^ SyntaxError: invalid syntax Compiling django/conf/app_template/models.py ... File "django/conf/app_template/models.py", line 1 {{ unicode_literals }}from django.db import models ^ SyntaxError: invalid syntax

It’s safe to ignore these errors (Django will still install just fine), but you can avoid them by upgrading setuptools to a more recent version. If you’re using pip, you can upgrade pip using pip install -U pip which will also upgrade setuptools. This is resolved in later versions of Django as described in the Django 1.9.2 release notes. Miscellaneous • The jQuery static files in contrib.admin have been moved into a vendor/jquery subdirectory. • The text displayed for null columns in the admin changelist list_display cells has changed from (None) (or its translated equivalent) to - (a dash). • django.http.responses.REASON_PHRASES and django.core.handlers.wsgi. STATUS_CODE_TEXT have been removed. Use Python’s stdlib instead: http.client.responses for Python 3 and httplib.responses for Python 2. • ValuesQuerySet and ValuesListQuerySet have been removed. • The admin/base.html template no longer sets window.__admin_media_prefix__ or window. __admin_utc_offset__. Image references in JavaScript that used that value to construct absolute URLs have been moved to CSS for easier customization. The UTC offset is stored on a data attribute of the tag. • CommaSeparatedIntegerField validation has been refined to forbid values like ',', ',1', and '1,, 2'.

9.1. Final releases

• Form initialization was moved from the ProcessFormView.get() method to the new FormMixin. get_context_data() method. This may be backwards incompatible if you have overridden the get_context_data() method without calling super(). • Support for PostGIS 1.5 has been dropped. • The django.contrib.sites.models.Site.domain field was changed to be unique. • In order to enforce test isolation, database queries are not allowed by default in SimpleTestCase tests anymore. You can disable this behavior by setting the allow_database_queries class attribute to True on your test class. • ResolverMatch.app_name was changed to contain the full namespace path in the case of nested namespaces. For consistency with ResolverMatch.namespace, the empty value is now an empty string instead of None. • For security hardening, session keys must be at least 8 characters. • Private function django.utils.functional.total_ordering() has been removed. It contained a workaround for a functools.total_ordering() bug in Python versions older than 2.7.3. • XML serialization (either through dumpdata or the syndication framework) used to output any characters it received. Now if the content to be serialized contains any control characters not allowed in the XML 1.0 standard, the serialization will fail with a ValueError. • CharField now strips input of leading and trailing whitespace by default. This can be disabled by setting the new strip argument to False. • Template text that is translated and uses two or more consecutive percent signs, e.g. "%%", may have a new msgid after makemessages is run (most likely the translation will be marked fuzzy). The new msgid will be marked "#, python-format". • If neither request.current_app nor Context.current_app are set, the url template tag will now use the namespace of the current request. Set request.current_app to None if you don’t want to use a namespace hint. • The SILENCED_SYSTEM_CHECKS setting now silences messages of all levels. Previously, messages of ERROR level or higher were printed to the console. • The FlatPage.enable_comments field is removed from the FlatPageAdmin as it’s unused by the application. If your project or a third-party app makes use of it, create a custom ModelAdmin to add it back. • The return value of setup_databases() and the first argument of teardown_databases() changed. They used to be (old_names, mirrors) tuples. Now they’re just the first item, old_names. • By default LiveServerTestCase attempts to find an available port in the 8081-8179 range instead of just trying port 8081. • The system checks for ModelAdmin now check instances rather than classes. • The private API to apply mixed migration plans has been dropped for performance reasons. Mixed plans consist of a list of migrations where some are being applied and others are being unapplied. • The related model object descriptor classes in django.db.models.fields.related (private API) are moved from the related module to related_descriptors and renamed as follows: – ReverseSingleRelatedObjectDescriptor is ForwardManyToOneDescriptor – SingleRelatedObjectDescriptor is ReverseOneToOneDescriptor – ForeignRelatedObjectsDescriptor is ReverseManyToOneDescriptor – ManyRelatedObjectsDescriptor is ManyToManyDescriptor

Chapter 9. Release notes

• If you implement a custom handler404 view, it must return a response with an HTTP 404 status code. Use HttpResponseNotFound or pass status=404 to the HttpResponse. Otherwise, APPEND_SLASH won’t work correctly with DEBUG=False. Features deprecated in 1.9 assignment_tag() Django 1.4 added the assignment_tag helper to ease the creation of template tags that store results in a template variable. The simple_tag() helper has gained this same ability, making the assignment_tag obsolete. Tags that use assignment_tag should be updated to use simple_tag. {% cycle %} syntax with comma-separated arguments The cycle tag supports an inferior old syntax from previous Django versions: {% cycle row1,row2,row3 %}

Its parsing caused bugs with the current syntax, so support for the old syntax will be removed in Django 1.10 following an accelerated deprecation. ForeignKey and OneToOneField on_delete argument In order to increase awareness about cascading model deletion, the on_delete argument of ForeignKey and OneToOneField will be required in Django 2.0. Update models and existing migrations to explicitly set the argument. Since the default is models.CASCADE, add on_delete=models.CASCADE to all ForeignKey and OneToOneFields that don’t use a different option. You can also pass it as the second positional argument if you don’t care about compatibility with older versions of Django. Field.rel changes Field.rel and its methods and attributes have changed to match the related fields API. The Field.rel attribute is renamed to remote_field and many of its methods and attributes are either changed or renamed. The aim of these changes is to provide a documented API for relation fields. GeoManager and GeoQuerySet custom methods All custom GeoQuerySet methods (area(), distance(), gml(), ...) have been replaced by equivalent geographic expressions in annotations (see in new features). Hence the need to set a custom GeoManager to GIS-enabled models is now obsolete. As soon as your code doesn’t call any of the deprecated methods, you can simply remove the objects = GeoManager() lines from your models.

9.1. Final releases

Template loader APIs have changed Django template loaders have been updated to allow recursive template extending. This change necessitated a new template loader API. The old load_template() and load_template_sources() methods are now deprecated. Details about the new API can be found in the template loader documentation. Passing a 3-tuple or an app_name to include() The instance namespace part of passing a tuple as an argument to include() has been replaced by passing the namespace argument to include(). For example: polls_patterns = [ url(...), ] urlpatterns = [ url(r'^polls/', include((polls_patterns, 'polls', 'author-polls'))), ]

becomes: polls_patterns = ([ url(...), ], 'polls') # 'polls' is the app_name urlpatterns = [ url(r'^polls/', include(polls_patterns, namespace='author-polls')), ]

The app_name argument to include() has been replaced by passing a 2-tuple (as above), or passing an object or module with an app_name attribute (as below). If the app_name is set in this new way, the namespace argument is no longer required. It will default to the value of app_name. For example, the URL patterns in the tutorial are changed from: mysite/urls.py urlpatterns = [ url(r'^polls/', include('polls.urls', namespace="polls")), ... ]

This change also means that the old way of including an AdminSite instance is deprecated. Instead, pass admin. site.urls directly to url(): urls.py

Chapter 9. Release notes

from django.conf.urls import url from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), ]

URL application namespace required if setting an instance namespace In the past, an instance namespace without an application namespace would serve the same purpose as the application namespace, but it was impossible to reverse the patterns if there was an application namespace with the same name. Includes that specify an instance namespace require that the included URLconf sets an application namespace. current_app parameter to contrib.auth views All views in django.contrib.auth.views have the following structure: def view(request, ..., current_app=None, ...): ... if current_app is not None: request.current_app = current_app return TemplateResponse(request, template_name, context)

As of Django 1.8, current_app is set on the request object. For consistency, these views will require the caller to set current_app on the request instead of passing it in a separate argument. django.contrib.gis.geoip The django.contrib.gis.geoip2 module supersedes django.contrib.gis.geoip. The new module provides a similar API except that it doesn’t provide the legacy GeoIP-Python API compatibility methods. Miscellaneous • The weak argument to django.dispatch.signals.Signal.disconnect() has been deprecated as it has no effect. • The check_aggregate_support() method of django.db.backends.base. BaseDatabaseOperations has been deprecated and will be removed in Django 2.0. The more general check_expression_support() should be used instead. • django.forms.extras is deprecated. You can find SelectDateWidget in django.forms. widgets (or simply django.forms) instead. • Private API django.db.models.fields.add_lazy_relation() is deprecated. • The django.contrib.auth.tests.utils.skipIfCustomUser() decorator is deprecated. With the test discovery changes in Django 1.6, the tests for django.contrib apps are no longer run as part of the user’s project. Therefore, the @skipIfCustomUser decorator is no longer needed to decorate tests in django.contrib.auth.

9.1. Final releases

• If you customized some error handlers, the view signatures with only one request parameter are deprecated. The views should now also accept a second exception positional parameter. • The django.utils.feedgenerator.Atom1Feed.mime_type and django.utils. feedgenerator.RssFeed.mime_type attributes are deprecated in favor of content_type. • Signer now issues a warning if an invalid separator is used. This will become an exception in Django 1.10. • django.db.models.Field._get_val_from_obj() value_from_object().

Field.

• django.template.loaders.eggs.Loader is deprecated as distributing applications as eggs is not recommended. • The callable_obj keyword argument to SimpleTestCase.assertRaisesMessage() is deprecated. Pass the callable as a positional argument instead. • The allow_tags attribute on methods of ModelAdmin has been deprecated. Use format_html(), format_html_join(), or mark_safe() when constructing the method’s return value instead. • The enclosure keyword argument to SyndicationFeed.add_item() is deprecated. Use the new enclosures argument which accepts a list of Enclosure objects instead of a single one. • The django.template.loader.LoaderOrigin and django.template.base.StringOrigin aliases for django.template.base.Origin are deprecated. Features removed in 1.9 These features have reached the end of their deprecation cycle and are removed in Django 1.9. See Features deprecated in 1.7 for details, including how to remove usage of these features. • django.utils.dictconfig is removed. • django.utils.importlib is removed. • django.utils.tzinfo is removed. • django.utils.unittest is removed. • The syncdb command is removed. • django.db.models.signals.pre_syncdb and django.db.models.signals.post_syncdb is removed. • Support for allow_syncdb on database routers is removed. • Automatic syncing of apps without migrations is removed. Migrations are compulsory for all apps unless you pass the migrate --run-syncdb option. • The SQL management commands for apps without migrations, sqldropindexes, and sqlindexes, are removed.

• Support for automatic loading of initial_data fixtures and initial SQL data is removed. • All models need to be defined inside an installed application or declare an explicit app_label. Furthermore, it isn’t possible to import them before their application is loaded. In particular, it isn’t possible to import models inside the root package of an application. • The model and form IPAddressField is removed. A stub field remains for compatibility with historical migrations. • AppCommand.handle_app() is no longer supported.

Chapter 9. Release notes

• RequestSite and get_current_site() are no longer importable from django.contrib.sites. models. • FastCGI support via the runfcgi management command is removed. • django.utils.datastructures.SortedDict is removed. • ModelAdmin.declared_fieldsets is removed. • The util modules that provided backwards compatibility are removed: – django.contrib.admin.util – django.contrib.gis.db.backends.util – django.db.backends.util – django.forms.util • ModelAdmin.get_formsets is removed. • The backward compatible shims introduced to rename the BaseMemcachedCache. _get_memcache_timeout() method to get_backend_timeout() is removed. • The --natural and -n options for dumpdata are removed. • The use_natural_keys argument for serializers.serialize() is removed. • Private API django.forms.forms.get_declared_fields() is removed. • The ability to use a SplitDateTimeWidget with DateTimeField is removed. • The WSGIRequest.REQUEST property is removed. • The class django.utils.datastructures.MergeDict is removed. • The zh-cn and zh-tw language codes are removed. • The internal django.utils.functional.memoize() is removed. • django.core.cache.get_cache is removed. • django.db.models.loading is removed. • Passing callable arguments to querysets is no longer possible. • BaseCommand.requires_model_validation is removed requires_system_checks. Admin validators is replaced by admin checks.

• The ModelAdmin.validator_class and default_validator_class attributes are removed. • ModelAdmin.validate() is removed. • django.db.backends.DatabaseValidation.validate_field is removed in favor of the check_field method. • The validate management command is removed. • django.utils.module_loading.import_by_path is removed in favor of django.utils. module_loading.import_string. • ssi and url template tags are removed from the future template tag library. • django.utils.text.javascript_quote() is removed. • Database test settings as independent entries in the database settings, prefixed by TEST_, are no longer supported. • The cache_choices option to ModelChoiceField and ModelMultipleChoiceField is removed.

9.1. Final releases

• The default value of the RedirectView.permanent attribute has changed from True to False. • django.contrib.sitemaps.FlatPageSitemap is removed in favor of django.contrib. flatpages.sitemaps.FlatPageSitemap. • Private API django.test.utils.TestTemplateLoader is removed. • The django.contrib.contenttypes.generic module is removed.

9.1.6 1.8 release Django 1.8.18 release notes April 4, 2017 Django 1.8.18 fixes two security issues in 1.8.17. CVE-2017-7233: Open redirect and possible XSS attack via user-supplied numeric redirect URLs Django relies on user input in some cases (e.g. django.contrib.auth.views.login() and i18n) to redirect the user to an “on success” URL. The security check for these redirects (namely django.utils.http. is_safe_url()) considered some numeric URLs (e.g. http:999999999) “safe” when they shouldn’t be. Also, if a developer relies on is_safe_url() to provide safe redirect targets and puts such a URL into a link, they could suffer from an XSS attack. CVE-2017-7234: Open redirect vulnerability in django.views.static.serve() A maliciously crafted URL to a Django site using the serve() view could redirect to any other domain. The view no longer does any redirects as they don’t provide any known, useful functionality. Note, however, that this view has always carried a warning that it is not hardened for production use and should be used only as a development aid. Django 1.8.17 release notes December 1, 2016 Django 1.8.17 fixes a regression in 1.8.16. Bugfixes • Quoted the Oracle test user’s password in queries to fix the “ORA-00922: missing or invalid option” error when the password starts with a number or special character (#27420). Django 1.8.16 release notes November 1, 2016 Django 1.8.16 fixes two security issues in 1.8.15.

Chapter 9. Release notes

User with hardcoded password created when running tests on Oracle When running tests with an Oracle database, Django creates a temporary database user. In older versions, if a password isn’t manually specified in the database settings TEST dictionary, a hardcoded password is used. This could allow an attacker with network access to the database server to connect. This user is usually dropped after the test suite completes, but not when using the manage.py test --keepdb option or if the user has an active session (such as an attacker’s connection). A randomly generated password is now used for each test run. DNS rebinding vulnerability when DEBUG=True Older versions of Django don’t validate the Host header against settings.ALLOWED_HOSTS when settings. DEBUG=True. This makes them vulnerable to a DNS rebinding attack. While Django doesn’t ship a module that allows remote code execution, this is at least a cross-site scripting vector, which could be quite serious if developers load a copy of the production database in development or connect to some production services for which there’s no development instance, for example. If a project uses a package like the django-debug-toolbar, then the attacker could execute arbitrary SQL, which could be especially bad if the developers connect to the database with a superuser account. settings.ALLOWED_HOSTS is now validated regardless of DEBUG. For convenience, if ALLOWED_HOSTS is empty and DEBUG=True, the following variations of localhost are allowed ['localhost', '127.0.0.1', '::1']. If your local settings file has your production ALLOWED_HOSTS value, you must now omit it to get those fallback values. Django 1.8.15 release notes September 26, 2016 Django 1.8.15 fixes a security issue in 1.8.14. CSRF protection bypass on a site with Google Analytics An interaction between Google Analytics and Django’s cookie parsing could allow an attacker to set arbitrary cookies leading to a bypass of CSRF protection. The parser for request.COOKIES is simplified to better match the behavior of browsers and to mitigate this attack. request.COOKIES may now contain cookies that are invalid according to RFC 6265 but are possible to set via document.cookie. Django 1.8.14 release notes July 18, 2016 Django 1.8.14 fixes a security issue and a bug in 1.8.13. XSS in admin’s add/change related popup Unsafe usage of JavaScript’s Element.innerHTML could result in XSS in the admin’s add/change related popup. Element.textContent is now used to prevent execution of the data.

9.1. Final releases

The debug view also used innerHTML. Although a security issue wasn’t identified there, out of an abundance of caution it’s also updated to use textContent. Bugfixes • Fixed missing varchar/text_pattern_ops index on CharField and TextField respectively when using AddField on PostgreSQL (#26889). Django 1.8.13 release notes May 2, 2016 Django 1.8.13 fixes several bugs in 1.8.12. Bugfixes • Fixed TimeField microseconds round-tripping on MySQL and SQLite (#26498). • Restored conversion of an empty string to null when saving values of GenericIPAddressField on SQLite and MySQL (#26557). Django 1.8.12 release notes April 1, 2016 Django 1.8.12 fixes several bugs in 1.8.11. Bugfixes • Made MultiPartParser ignore filenames that normalize to an empty string to fix crash in MemoryFileUploadHandler on specially crafted user input (#26325). • Fixed data loss on SQLite where DurationField values with fractional seconds could be saved as None (#26324). • Restored the functionality of the admin’s raw_id_fields in list_editable (#26387). Django 1.8.11 release notes March 5, 2016 Django 1.8.11 fixes a regression on Python 2 in the 1.8.10 security release where utils.http.is_safe_url() crashes on bytestring URLs (#26308). Django 1.8.10 release notes March 1, 2016 Django 1.8.10 fixes two security issues and several bugs in 1.8.9.

Chapter 9. Release notes

CVE-2016-2512: Malicious redirect and possible XSS attack via user-supplied redirect URLs containing basic auth Django relies on user input in some cases (e.g. django.contrib.auth.views.login() and i18n) to redirect the user to an “on success” URL. The security check for these redirects (namely django.utils.http. is_safe_url()) considered some URLs with basic authentication credentials “safe” when they shouldn’t be. For example, a URL like http://mysite.example.com\@attacker.com would be considered safe if the request’s host is http://mysite.example.com, but redirecting to this URL sends the user to attacker.com. Also, if a developer relies on is_safe_url() to provide safe redirect targets and puts such a URL into a link, they could suffer from an XSS attack. CVE-2016-2513: User enumeration through timing difference on password hasher work factor upgrade In each major version of Django since 1.6, the default number of iterations for the PBKDF2PasswordHasher and its subclasses has increased. This improves the security of the password as the speed of hardware increases, however, it also creates a timing difference between a login request for a user with a password encoded in an older number of iterations and login request for a nonexistent user (which runs the default hasher’s default number of iterations since Django 1.6). This only affects users who haven’t logged in since the iterations were increased. The first time a user logs in after an iterations increase, their password is updated with the new iterations and there is no longer a timing difference. The new BasePasswordHasher.harden_runtime() method allows hashers to bridge the runtime gap between the work factor (e.g. iterations) supplied in existing encoded passwords and the default work factor of the hasher. This method is implemented for PBKDF2PasswordHasher and BCryptPasswordHasher. The number of rounds for the latter hasher hasn’t changed since Django 1.4, but some projects may subclass it and increase the work factor as needed. A warning will be emitted for any third-party password hashers that don’t implement a harden_runtime() method. If you have different password hashes in your database (such as SHA1 hashes from users who haven’t logged in since the default hasher switched to PBKDF2 in Django 1.4), the timing difference on a login request for these users may be even greater and this fix doesn’t remedy that difference (or any difference when changing hashers). You may be able to upgrade those hashes to prevent a timing attack for that case. Bugfixes • Fixed a crash on PostgreSQL that prevented using TIME_ZONE=None and USE_TZ=False (#26177). • Added system checks for query name clashes of hidden relationships (#26162). • Made forms.FileField and utils.translation.lazy_number() picklable (#26212). • Fixed RangeField and ArrayField serialization with None values (#26215). • Reallowed dashes in top-level domain names of URLs checked by URLValidator to fix a regression in Django 1.8 (#26204). • Fixed BoundField to reallow slices of subwidgets (#26267). • Prevented ContentTypeManager instances from sharing their cache (#26286).

9.1. Final releases

Django 1.8.9 release notes February 1, 2016 Django 1.8.9 fixes several bugs in 1.8.8. Bugfixes • Fixed a regression that caused the “user-tools” items to display on the admin’s logout page (#26035). • Fixed a crash in the translations system when the current language has no translations (#26046). • Fixed a regression that caused the incorrect day to be selected when opening the admin calendar widget for timezones from GMT+0100 to GMT+1200 (#24980). • Fixed a regression in 1.8.8 causing incorrect index handling in migrations on PostgreSQL when adding db_index=True or unique=True to a CharField or TextField that already had the other specified, or when removing one of them from a field that had both, or when adding unique=True to a field already listed in unique_together (#26034). • Fixed a crash when using an __in lookup inside a Case expression (#26071). • Fixed a crash when using a reverse OneToOneField in ModelAdmin.readonly_fields (#26060). • Fixed a regression in Django 1.8.5 that broke copying a SimpleLazyObject with copy.copy() (#26122). • Fixed the contrib.gis map widgets when using USE_THOUSAND_SEPARATOR=True (#20415). Django 1.8.8 release notes January 2, 2016 Django 1.8.8 fixes several bugs in 1.8.7. Python 3.2 users, please be advised that we’ve decided to drop support for Python 3.2 in Django 1.8.x at the end of 2016. We won’t break things intentionally after that, but we won’t test subsequent releases against Python 3.2 either. Upstream support for Python 3.2 ends February 2016 so we don’t find much value in providing security updates for a version of Python that could be insecure. To read more about the decision and to let us know if this will be problematic for you, please read the django-developers thread. Bugfixes • Fixed incorrect unique_together field name generation by inspectdb (#25274). • Corrected __len query lookup on ArrayField for empty arrays (#25772). • Restored the ability to use custom formats from formats.py with django.utils.formats. get_format() and the date template filter (#25812). • Fixed a state bug when migrating a SeparateDatabaseAndState operation backwards (#25896). • Fixed missing varchar/text_pattern_ops index on CharField and TextField respectively when using AlterField on PostgreSQL (#25412). • Fixed a state bug when using an AlterModelManagers operation (#25852). • Fixed a regression which prevented using a language not in Django’s default language list (LANGUAGES) (#25915).

Chapter 9. Release notes

• django.views.decorators.cache.never_cache() now sends more persuasive headers (added no-cache, no-store, must-revalidate to Cache-Control) to better prevent caching (#13008). This fixes a problem where a page refresh in Firefox cleared the selected entries in the admin’s filter_horizontal and filter_vertical widgets, which could result in inadvertent data loss if a user didn’t notice that and then submitted the form (#22955). • Fixed a regression in the admin which ignored line breaks in read-only fields instead of converting them to
(#25465). • Made loaddata skip disabling and enabling database constraints when it doesn’t load any fixtures (#23372). • Fixed a crash in QuerySet.values()/values_list() after an annotate() and order_by() when values()/values_list() includes a field not in the order_by() (#25316). Django 1.8.7 release notes November 24, 2015 Django 1.8.7 fixes a security issue and several bugs in 1.8.6. Additionally, Django’s vendored version of six, django.utils.six, has been upgraded to the latest release (1.10.0). Fixed settings leak possibility in date template filter If an application allows users to specify an unvalidated format for dates and passes this format to the date filter, e.g. {{ last_updated|date:user_date_format }}, then a malicious user could obtain any secret in the application’s settings by specifying a settings key instead of a date format. e.g. "SECRET_KEY" instead of "j/m/ Y". To remedy this, the underlying function used by the date template filter, django.utils.formats. get_format(), now only allows accessing the date/time formatting settings. Bugfixes • Fixed a crash of the debug view during the autumn DST change when USE_TZ is False and pytz is installed. • Fixed a regression in 1.8.6 that caused database routers without an allow_migrate() method to crash (#25686). • Fixed a regression in 1.8.6 by restoring the ability to use Manager objects for the queryset argument of ModelChoiceField (#25683). • Fixed a regression in 1.8.6 that caused an application with South migrations in the migrations directory to fail (#25618). • Fixed a data loss possibility with Prefetch if to_attr is set to a ManyToManyField (#25693). • Fixed a regression in 1.8 by making gettext() once again return UTF-8 bytestrings on Python 2 if the input is a bytestring (#25720). • Fixed serialization of DateRangeField and DateTimeRangeField (#24937). • Fixed the exact lookup of ArrayField (#25666). • Fixed Model.refresh_from_db() updating of ForeignKey fields with on_delete=models. SET_NULL (#25715). • Fixed a duplicate query regression in 1.8 on proxied model deletion (#25685). 9.1. Final releases

• Fixed set_FOO_order() crash when the ForeignKey of a model with order_with_respect_to references a model with a OneToOneField primary key (#25786). • Fixed incorrect validation for PositiveIntegerField and PositiveSmallIntegerField on MySQL resulting in values greater than 4294967295 or 65535, respectively, passing validation and being silently truncated by the database (#25767). Django 1.8.6 release notes November 4, 2015 Django 1.8.6 adds official support for Python 3.5 and fixes several bugs in 1.8.5. Bugfixes • Fixed a regression causing ModelChoiceField to ignore prefetch_related() on its queryset (#25496). • Allowed “mode=memory” in SQLite test database name if supported (#12118). • Fixed system check crash on ForeignKey to abstract model (#25503). • Fixed incorrect queries when you have multiple ManyToManyFields on different models that have the same field name, point to the same model, and have their reverse relations disabled (#25545). • Allowed filtering over a RawSQL annotation (#25506). • Made the Concat database function idempotent on SQLite (#25517). • Avoided a confusing stack trace when starting runserver with an invalid INSTALLED_APPS setting (#25510). This regression appeared in 1.8.5 as a side effect of fixing #24704. • Made deferred models use their proxied model’s _meta.apps for caching and retrieval (#25563). This prevents any models generated in data migrations using QuerySet.defer() from leaking to test and application code. • Fixed a typo in the name of the strictly_above PostGIS lookup (#25592). • Fixed crash with contrib.postgres.forms.SplitArrayField and IntegerField on invalid value (#25597). • Added a helpful error message when Django and South migrations exist in the same directory (#25618). • Fixed a regression in URLValidator that allowed URLs with consecutive dots in the domain section (like http://example..com/) to pass (#25620). • Fixed a crash with GenericRelation and BaseModelAdmin.to_field_allowed (#25622). Django 1.8.5 release notes October 3, 2015 Django 1.8.5 fixes several bugs in 1.8.4. Bugfixes • Made the development server’s autoreload more robust (#24704).

Chapter 9. Release notes

• Fixed AssertionError in some delete queries with a model containing a field that is both a foreign and primary key (#24951). • Fixed AssertionError in some complex queries (#24525). • Fixed a migrations crash with GenericForeignKey (#25040). • Made translation.override() clear the overridden language when a translation isn’t initially active (#25295). • Fixed crash when using a value in ModelAdmin.list_display that clashed with a reverse field on the model (#25299). • Fixed autocompletion for options of non-argparse management commands (#25372). • Alphabetized ordering of imports in from django.db import migrations, models statement in newly created migrations (#25384). • Fixed migrations crash on MySQL when adding a text or a blob field with an unhashable default (#25393). • Changed Count queries to execute COUNT(*) instead of COUNT('*') as versions of Django before 1.8 did (#25377). This may fix a performance regression on some databases. • Fixed custom queryset chaining with values() and values_list() (#20625). • Moved the unsaved model instance assignment data loss check on reverse relations to Model.save() (#25160). • Readded inline foreign keys to form instances when validating model formsets (#25431). • Allowed using ORM write methods after disabling autocommit with set_autocommit(False) (#24921). • Fixed the manage.py test --keepdb option on Oracle (#25421). • Fixed incorrect queries with multiple many-to-many fields on a model with the same ‘to’ model and with related_name set to ‘+’ (#24505, #25486). • Fixed pickling a SimpleLazyObject wrapping a model (#25389). Django 1.8.4 release notes August 18, 2015 Django 1.8.4 fixes a security issue and several bugs in 1.8.3. Denial-of-service possibility in logout() view by filling session store Previously, a session could be created when anonymously accessing the django.contrib.auth.views. logout() view (provided it wasn’t decorated with login_required() as done in the admin). This could allow an attacker to easily create many new session records by sending repeated requests, potentially filling up the session store or causing other users’ session records to be evicted. The SessionMiddleware has been modified to no longer create empty session records, including when SESSION_SAVE_EVERY_REQUEST is active. Bugfixes • Added the ability to serialize values from the newly added UUIDField (#25019).

9.1. Final releases

• Added a system check warning if the old TEMPLATE_* settings are defined in addition to the new TEMPLATES setting. • Fixed QuerySet.raw() so InvalidQuery is not raised when using the db_column name of a ForeignKey field with primary_key=True (#12768). • Prevented an exception in TestCase.setUpTestData() from leaking the transaction (#25176). • Fixed has_changed() method in contrib.postgres.forms.HStoreField (#25215, #25233). • Fixed the recording of squashed migrations when running the migrate command (#25231). • Moved the unsaved model instance assignment data loss check to Model.save() to allow easier usage of in-memory models (#25160). • Prevented varchar_patterns_ops and text_patterns_ops indexes for ArrayField (#25180). Django 1.8.3 release notes July 8, 2015 Django 1.8.3 fixes several security issues and bugs in 1.8.2. Also, django.utils.deprecation.RemovedInDjango20Warning was renamed to RemovedInDjango110Warning as the version roadmap was revised to 1.9, 1.10, 1.11 (LTS), 2.0 (drops Python 2 support). For backwards compatibility, RemovedInDjango20Warning remains as an importable alias. Denial-of-service possibility by filling session store In previous versions of Django, the session backends created a new empty record in the session storage anytime request.session was accessed and there was a session key provided in the request cookies that didn’t already have a session record. This could allow an attacker to easily create many new session records simply by sending repeated requests with unknown session keys, potentially filling up the session store or causing other users’ session records to be evicted. The built-in session backends now create a session record only if the session is actually modified; empty session records are not created. Thus this potential DoS is now only possible if the site chooses to expose a session-modifying view to anonymous users. As each built-in session backend was fixed separately (rather than a fix in the core sessions framework), maintainers of third-party session backends should check whether the same vulnerability is present in their backend and correct it if so. Header injection possibility since validators accept newlines in input Some of Django’s built-in validators (EmailValidator, most seriously) didn’t prohibit newline characters (due to the usage of $ instead of \Z in the regular expressions). If you use values with newlines in HTTP response or email headers, you can suffer from header injection attacks. Django itself isn’t vulnerable because HttpResponse and the mail sending utilities in django.core.mail prohibit newlines in HTTP and SMTP headers, respectively. While the validators have been fixed in Django, if you’re creating HTTP responses or email messages in other ways, it’s a good idea to ensure that those methods prohibit newlines as well. You might also want to validate that any existing data in your application doesn’t contain unexpected newlines. validate_ipv4_address(), validate_slug(), and URLValidator are also affected, however, as of Django 1.6 the GenericIPAddresseField, IPAddressField, SlugField, and URLField form fields which use these validators all strip the input, so the possibility of newlines entering your data only exists if you are using these validators outside of the form fields. 1500

Chapter 9. Release notes

The undocumented, internally unused validate_integer() function is now stricter as it validates using a regular expression instead of simply casting the value using int() and checking if an exception was raised. Denial-of-service possibility in URL validation URLValidator included a regular expression that was extremely slow to evaluate against certain invalid inputs. This regular expression has been simplified and optimized. Bugfixes • Fixed BaseRangeField.prepare_value() to use each base_field’s prepare_value() method (#24841). • Fixed crash during makemigrations if a migrations module either is missing __init__.py or is a file (#24848). • Fixed QuerySet.exists() returning incorrect results after annotation with Count() (#24835). • Corrected HStoreField.has_changed() (#24844). • Reverted an optimization to the CSRF template context processor which caused a regression (#24836). • Fixed a regression which caused template context processors to overwrite variables set on a RequestContext after it’s created (#24847). • Prevented the loss of null/not null column properties during field renaming of MySQL databases (#24817). • Fixed a crash when using a reverse one-to-one relation in ModelAdmin.list_display (#24851). • Fixed quoting of SQL when renaming a field to AutoField in PostgreSQL (#24892). • Fixed lack of unique constraint when changing a field from primary_key=True to unique=True (#24893). • Fixed queryset pickling when using prefetch_related() after deleting objects (#24831). • Allowed using choices longer than 1 day with DurationField (#24897). • Fixed a crash when loading squashed migrations from two apps with a dependency between them, where the dependent app’s replaced migrations are partially applied (#24895). • Fixed recording of applied status for squashed (replacement) migrations (#24628). • Fixed queryset annotations when using Case expressions with exclude() (#24833). • Corrected join promotion for multiple Case expressions. Annotating a query with multiple Case expressions could unexpectedly filter out results (#24924). • Fixed usage of transforms in subqueries (#24744). • Fixed SimpleTestCase.assertRaisesMessage() on Python 2.7.10 (#24903). • Provided better backwards compatibility for the verbosity argument in optparse management commands by casting it to an integer (#24769). • Fixed prefetch_related() on databases other than PostgreSQL for models using UUID primary keys (#24912). • Fixed removing unique_together constraints on MySQL (#24972).

9.1. Final releases

• Fixed crash when uploading images with MIME types that Pillow doesn’t detect, such as bitmap, in forms. ImageField (#24948). • Fixed a regression when deleting a model through the admin that has a GenericRelation with a related_query_name (#24940). • Reallowed non-ASCII values for ForeignKey.related_name on Python 3 by fixing the false positive system check (#25016). • Fixed inline forms that use a parent object that has a UUIDField primary key and a child object that has an AutoField primary key (#24958). • Fixed a regression in the unordered_list template filter on certain inputs (#25031). • Fixed a regression in URLValidator that invalidated Punycode TLDs (#25059). • Improved pyinotify runserver polling (#23882). Django 1.8.2 release notes May 20, 2015 Django 1.8.2 fixes a security issue and several bugs in 1.8.1. Fixed session flushing in the cached_db backend A change to session.flush() in the cached_db session backend in Django 1.8 mistakenly sets the session key to an empty string rather than None. An empty string is treated as a valid session key and the session cookie is set accordingly. Any users with an empty string in their session cookie will use the same session store. session.flush() is called by django.contrib.auth.logout() and, more seriously, by django. contrib.auth.login() when a user switches accounts. If a user is logged in and logs in again to a different account (without logging out) the session is flushed to avoid reuse. After the session is flushed (and its session key becomes '') the account details are set on the session and the session is saved. Any users with an empty string in their session cookie will now be logged into that account. Bugfixes • Fixed check for template engine alias uniqueness (#24685). • Fixed crash when reusing the same Case instance in a query (#24752). • Corrected join promotion for Case expressions. For example, annotating a query with a Case expression could unexpectedly filter out results (#24766). • Fixed negated Q objects in expressions. Cases like Case(When(~Q(friends__age__lte=30))) tried to generate a subquery which resulted in a crash (#24705). • Fixed incorrect GROUP BY clause generation on MySQL when the query’s model has a self-referential foreign key (#24748). • Implemented ForeignKey.get_db_prep_value() so that ForeignKeys pointing to UUIDField and inheritance on models with UUIDField primary keys work correctly (#24698, #24712). • Fixed isnull lookup for HStoreField (#24751). • Fixed a MySQL crash when a migration removes a combined index (unique_together or index_together) containing a foreign key (#24757). • Fixed session cookie deletion when using SESSION_COOKIE_DOMAIN (#24799). 1502

Chapter 9. Release notes

• On PostgreSQL, when no access is granted for the postgres database, Django now falls back to the default database when it normally requires a “no database” connection (#24791). • Fixed display of contrib.admin’s ForeignKey widget when it’s used in a row with other fields (#24784). Django 1.8.1 release notes May 1, 2015 Django 1.8.1 fixes several bugs in 1.8 and includes some optimizations in the migrations framework. Bugfixes • Added support for serializing timedelta objects in migrations (#24566). • Restored proper parsing of the testserver command’s positional arguments (fixture names) (#24571). • Prevented TypeError in translation functions check_for_language() and get_language_bidi() when translations are deactivated (#24569). • Fixed squashmigrations command when using SeparateDatabaseAndState (#24278). • Stripped microseconds from datetime values when using an older version of the MySQLdb DB API driver as it does not support fractional seconds (#24584). • Fixed a migration crash when altering ManyToManyFields (#24513). • Fixed a crash with QuerySet.update() on foreign keys to one-to-one fields (#24578). • Fixed a regression in the model detail view of admindocs when a model has a reverse foreign key relation (#24624). • Prevented arbitrary file inclusions in admindocs (#24625). • Fixed a crash with QuerySet.update() on foreign keys to instances with uuid primary keys (#24611). • Fixed database introspection with SQLite 3.8.9 (released April 8, 2015) (#24637). • Updated urlpatterns examples generated by startproject to remove usage of referencing views by dotted path in url() which is deprecated in Django 1.8 (#24635). • Fixed queries where an expression was referenced in order_by(), but wasn’t part of the select clause. An example query is qs.annotate(foo=F('field')).values('pk').order_by('foo')) (#24615). • Fixed a database table name quoting regression (#24605). • Prevented the loss of null/not null column properties during field alteration of MySQL databases (#24595). • Fixed JavaScript path of contrib.admin’s related field widget when using alternate static file storages (#24655). • Fixed a migration crash when adding new relations to models (#24573). • Fixed a migration crash when applying migrations with model managers on Python 3 that were generated on Python 2 (#24701). • Restored the ability to use iterators as queryset filter arguments (#24719). • Fixed a migration crash when renaming the target model of a many-to-many relation (#24725). • Removed flushing of the test database with test --keepdb, which prevented apps with data migrations from using the option (#24729).

9.1. Final releases

• Fixed makemessages crash in some locales (#23271). • Fixed help text positioning of contrib.admin fields that use the ModelAdmin.filter_horizontal and filter_vertical options (#24676). • Fixed AttributeError: function ‘GDALAllRegister’ not found error when initializing contrib.gis on Windows. Optimizations • Changed ModelState to deepcopy fields instead of deconstructing and reconstructing (#24591). This speeds up the rendering of model states and reduces memory usage when running manage.py migrate (although other changes in this release may negate any performance benefits). Django 1.8 release notes April 1, 2015 Welcome to Django 1.8! These release notes cover the new features, as well as some backwards incompatible changes you’ll want to be aware of when upgrading from Django 1.7 or older versions. We’ve also begun the deprecation process for some features, and some features have reached the end of their deprecation process and have been removed. See the Upgrading Django to a newer version guide if you’re updating an existing project. Django 1.8 has been designated as Django’s second long-term support release. It will receive security updates for at least three years after its release. Support for the previous LTS, Django 1.4, will end 6 months from the release date of Django 1.8. Python compatibility Django 1.8 requires Python 2.7, 3.2, 3.3, 3.4, or 3.5. We highly recommend and only officially support the latest release of each series. Django 1.8 is the first release to support Python 3.5. Due to the end of upstream support for Python 3.2 in February 2016, we won’t test Django 1.8.x on Python 3.2 after the end of 2016. What’s new in Django 1.8 Model._meta API Django now has a formalized API for Model._meta, providing an officially supported way to retrieve fields and filter fields based on their attributes. The Model._meta object has been part of Django since the days of pre-0.96 “Magic Removal” – it just wasn’t an official, stable API. In recognition of this, we’ve endeavored to maintain backwards-compatibility with the old API endpoint where possible. However, API endpoints that aren’t part of the new official API have been deprecated and will eventually be removed. A guide to migrating from the old API to the new API has been provided.

Chapter 9. Release notes

Multiple template engines Django 1.8 defines a stable API for integrating template backends. It includes built-in support for the Django template language and for Jinja2. It supports rendering templates with multiple engines within the same project. Learn more about the new features in the topic guide and check the upgrade instructions in older versions of the documentation. Security enhancements Several features of the django-secure third-party library have been integrated into Django. django.middleware. security.SecurityMiddleware provides several security enhancements to the request/response cycle. The new check --deploy option allows you to check your production settings file for ways to increase the security of your site. New PostgreSQL specific functionality Django now has a module with extensions for PostgreSQL specific features, such as ArrayField, HStoreField, Range Fields, and unaccent lookup. A full breakdown of the features is available in the documentation. New data types • Django now has a UUIDField for storing universally unique identifiers. It is stored as the native uuid data type on PostgreSQL and as a fixed length character field on other backends. There is a corresponding form field. • Django now has a DurationField for storing periods of time - modeled in Python by timedelta. It is stored in the native interval data type on PostgreSQL, as a INTERVAL DAY(9) TO SECOND(6) on Oracle, and as a bigint of microseconds on other backends. Date and time related arithmetic has also been improved on all backends. There is a corresponding form field. Query Expressions, Conditional Expressions, and Database Functions Query Expressions allow you to create, customize, and compose complex SQL expressions. This has enabled annotate to accept expressions other than aggregates. Aggregates are now able to reference multiple fields, as well as perform arithmetic, similar to F() objects. order_by() has also gained the ability to accept expressions. Conditional Expressions allow you to use if ... elif ... else logic within queries. A collection of database functions is also included with functionality such as Coalesce, Concat, and Substr. TestCase data setup TestCase has been refactored to allow for data initialization at the class level using transactions and savepoints. Database backends which do not support transactions, like MySQL with the MyISAM storage engine, will still be able to run these tests but won’t benefit from the improvements. Tests are now run within two nested atomic() blocks: one for the whole class and one for each test. • The class method TestCase.setUpTestData() adds the ability to setup test data at the class level. Using this technique can speed up the tests as compared to using setUp(). • Fixture loading within TestCase is now performed once for the whole TestCase.

9.1. Final releases

Minor features django.contrib.admin • ModelAdmin now has a has_module_permission() method to allow limiting access to the module on the admin index page. • InlineModelAdmin now has an attribute show_change_link that supports showing a link to an inline object’s change form. • Use the new django.contrib.admin.RelatedOnlyFieldListFilter in ModelAdmin. list_filter to limit the list_filter choices to foreign objects which are attached to those from the ModelAdmin. • The ModelAdmin.delete_view() displays a summary of objects to be deleted on the deletion confirmation page. • The jQuery library embedded in the admin has been upgraded to version 1.11.2. • You can now specify AdminSite.site_url in order to display a link to the front-end site. • You can now specify ModelAdmin.show_full_result_count to control whether or not the full count of objects should be displayed on a filtered admin page. • The AdminSite.password_change() method now has an extra_context parameter. • You can now control who may login to the admin site by overriding only AdminSite.has_permission() and AdminSite.login_form. The base.html template has a new block usertools which contains the user-specific header. A new context variable has_permission, which gets its value from has_permission(), indicates whether the user may access the site. • Foreign key dropdowns now have buttons for changing or deleting related objects using a popup. django.contrib.admindocs • reStructuredText is now parsed in model docstrings. django.contrib.auth • Authorization backends can now raise PermissionDenied has_module_perms() to short-circuit permission checking.

• PasswordResetForm now has a method send_email() that can be overridden to customize the mail to be sent. • The max_length of Permission.name has been increased from 50 to 255 characters. Please run the database migration. • USERNAME_FIELD and REQUIRED_FIELDS now supports ForeignKeys. • The default iteration count for the PBKDF2 password hasher has been increased by 33%. This backwards compatible change will not affect users who have subclassed django.contrib.auth.hashers. PBKDF2PasswordHasher to change the default value.

Chapter 9. Release notes

django.contrib.gis • A new GeoJSON serializer is now available. • It is now allowed to include a subquery as a geographic lookup argument, for example City. objects.filter(point__within=Country.objects.filter(continent='Africa'). values('mpoly')). • The SpatiaLite backend now supports Collect and Extent aggregates when the database version is 3.0 or later. • The PostGIS 2 CREATE EXTENSION postgis and the SpatiaLite SELECT InitSpatialMetaData initialization commands are now automatically run by migrate. • The GDAL interface now supports retrieving properties of raster (image) data file. • Compatibility shims for SpatialRefSys and GeometryColumns changed in Django 1.2 have been removed. • All GDAL-related exceptions are now raised with GDALException. The former OGRException has been kept for backwards compatibility but should not be used any longer. django.contrib.sessions • Session cookie is now deleted after flush() is called. django.contrib.sitemaps • The new Sitemap.i18n attribute allows you to generate a sitemap based on the LANGUAGES setting. django.contrib.sites • get_current_site() will now lookup the current site based on request.get_host() if the SITE_ID setting is not defined. • The default Site created when running migrate now respects the SITE_ID setting (instead of always using pk=1). Cache • The incr() method of the django.core.cache.backends.locmem.LocMemCache backend is now thread-safe. Cryptography • The max_age parameter of the django.core.signing.TimestampSigner.unsign() method now also accepts a datetime.timedelta object.

9.1. Final releases

Database backends • The MySQL backend no longer strips microseconds from datetime values as MySQL 5.6.4 and up supports fractional seconds depending on the declaration of the datetime field (when DATETIME includes fractional precision greater than 0). New datetime database columns created with Django 1.8 and MySQL 5.6.4 and up will support microseconds. See the MySQL database notes for more details. • The MySQL backend no longer creates explicit indexes for foreign keys when using the InnoDB storage engine, as MySQL already creates them automatically. • The Oracle backend no longer defines the connection_persists_old_columns feature as True. Instead, Oracle will now include a cache busting clause when getting the description of a table. Email • Email backends now support the context manager protocol for opening and closing connections. • The SMTP email backend now supports keyfile and certfile authentication with the EMAIL_SSL_CERTFILE and EMAIL_SSL_KEYFILE settings. • The SMTP EmailBackend now supports setting the timeout parameter with the EMAIL_TIMEOUT setting. • EmailMessage and EmailMultiAlternatives now support the reply_to parameter. File Storage • Storage.get_available_name() and Storage.save() now take a max_length argument to implement storage-level maximum filename length constraints. Filenames exceeding this argument will get truncated. This prevents a database error when appending a unique suffix to a long filename that already exists on the storage. See the deprecation note about adding this argument to your custom storage classes. Forms • Form widgets now render attributes with a value of True or False as HTML5 boolean attributes. • The new has_error() method allows checking if a specific error has happened. • If required_css_class is defined on a form, then the tags for required fields will have this class present in its attributes. • The rendering of non-field errors in unordered lists (

) now includes nonfield in its list of classes to distinguish them from field-specific errors. • Field now accepts a label_suffix argument, which will override the form’s label_suffix. This enables customizing the suffix on a per-field basis — previously it wasn’t possible to override a form’s label_suffix while using shortcuts such as {{ form.as_p }} in templates. • SelectDateWidget now accepts an empty_label argument, which will override the top list choice label when DateField is not required. • After an ImageField has been cleaned and validated, the UploadedFile object will have an additional image attribute containing the Pillow Image instance used to check if the file was a valid image. It will also update UploadedFile.content_type with the image’s content type as determined by Pillow. • You can now pass a callable that returns an iterable of choices when instantiating a ChoiceField.

1508

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Generic Views • Generic views that use MultipleObjectMixin may now specify the ordering applied to the queryset by setting ordering or overriding get_ordering(). • The new SingleObjectMixin.query_pk_and_slug attribute allows changing the behavior of get_object() so that it’ll perform its lookup using both the primary key and the slug. • The get_form() method doesn’t require a form_class to be provided anymore. form_class defaults to get_form_class().

If not provided

• Placeholders in ModelFormMixin.success_url now support the Python str.format() syntax. The legacy %()s syntax is still supported but will be removed in Django 1.10. Internationalization • FORMAT_MODULE_PATH can now be a list of strings representing module paths. This allows importing several format modules from different reusable apps. It also allows overriding those custom formats in your main Django project. Logging • The django.utils.log.AdminEmailHandler class now has a send_mail() method to make it more subclass friendly. Management Commands • Database connections are now always closed after a management command called from the command line has finished doing its job. • Commands from alternate package formats like eggs are now also discovered. • The new dumpdata --output option allows specifying a file to which the serialized data is written. • The new makemessages --exclude and compilemessages --exclude options allow excluding specific locales from processing. • compilemessages now has a --use-fuzzy or -f option which includes fuzzy translations into compiled files. • The loaddata --ignorenonexistent option now ignores data for models that no longer exist. • runserver now uses daemon threads for faster reloading. • inspectdb now outputs Meta.unique_together. It is also able to introspect AutoField for MySQL and PostgreSQL databases. • When calling management commands with options using call_command(), the option name can match the command line option name (without the initial dashes) or the final option destination variable name, but in either case, the resulting option received by the command is now always the dest name specified in the command option definition (as long as the command uses the argparse module). • The dbshell command now supports MySQL’s optional SSL certificate authority setting (--ssl-ca). • The new makemigrations --name allows giving the migration(s) a custom name instead of a generated one.

9.1. Final releases

1509

Django Documentation, Release 2.1.dev20171115023625

• The loaddata command now prevents repeated fixture loading. If FIXTURE_DIRS contains duplicates or a default fixture directory path (app_name/fixtures), an exception is raised. • The new makemigrations --exit option allows exiting with an error code if no migrations are created. • The new showmigrations command allows listing all migrations and their dependencies in a project. Middleware • The CommonMiddleware.response_redirect_class attribute allows you to customize the redirects issued by the middleware. • A debug message will be logged to the django.request logger when a middleware raises a MiddlewareNotUsed exception in DEBUG mode. Migrations • The RunSQL operation can now handle parameters passed to the SQL statements. • It is now possible to have migrations (most probably data migrations) for applications without models. • Migrations can now serialize model managers as part of the model state. • A generic mechanism to handle the deprecation of model fields was added. • The RunPython.noop() and RunSQL.noop class method/attribute were added to ease in making RunPython and RunSQL operations reversible. • The migration operations RunPython and RunSQL now call the allow_migrate() method of database routers. The router can use the newly introduced app_label and hints arguments to make a routing decision. To take advantage of this feature you need to update the router to the new allow_migrate signature, see the deprecation section for more details. Models • Django now logs at most 9000 queries in connections.queries, in order to prevent excessive memory usage in long-running processes in debug mode. • There is now a model Meta option to define a default related name for all relational fields of a model. • Pickling models and querysets across different versions of Django isn’t officially supported (it may work, but there’s no guarantee). An extra variable that specifies the current Django version is now added to the pickled state of models and querysets, and Django raises a RuntimeWarning when these objects are unpickled in a different version than the one in which they were pickled. • Added Model.from_db() which Django uses whenever objects are loaded using the ORM. The method allows customizing model loading behavior. • extra(select={...}) now allows you to escape a literal %s sequence using %%s. • Custom Lookups can now be registered using a decorator pattern. • The new Transform.bilateral attribute allows creating bilateral transformations. These transformations are applied to both lhs and rhs when used in a lookup expression, providing opportunities for more sophisticated lookups.

1510

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

• SQL special characters (, %, _) are now escaped properly when a pattern lookup (e.g. contains, startswith, etc.) is used with an F() expression as the right-hand side. In those cases, the escaping is performed by the database, which can lead to somewhat complex queries involving nested REPLACE function calls. • You can now refresh model instances by using Model.refresh_from_db(). • You can now get the set of deferred fields for a model using Model.get_deferred_fields(). • Model field default’s are now used when primary key field’s are set to None. Signals • Exceptions from the (receiver, exception) tuples returned by Signal.send_robust() now have their traceback attached as a __traceback__ attribute. • The environ argument, which contains the WSGI environment structure from the request, was added to the request_started signal. • You can now import the setting_changed() signal from django.core.signals to avoid loading django.test in non-test situations. Django no longer does so itself. System Check Framework • register can now be used as a function. Templates • urlize now supports domain-only links that include characters after the top-level domain (e.g. djangoproject.com/ and djangoproject.com/download/). • urlize doesn’t treat exclamation marks at the end of a domain or its query string as part of the URL (the URL in e.g. 'djangoproject.com! is djangoproject.com) • Added a locmem.Loader class that loads Django templates from a Python dictionary. • The now tag can now store its output in a context variable with the usual syntax: {% now 'j n Y' as varname %}. Requests and Responses • WSGIRequest now respects paths starting with //. • The HttpRequest.build_absolute_uri() method now handles paths starting with // correctly. • If DEBUG is True and a request raises a SuspiciousOperation, the response will be rendered with a detailed error page. • The query_string argument of QueryDict is now optional, defaulting to None, so a blank QueryDict can now be instantiated with QueryDict() instead of QueryDict(None) or QueryDict(''). • The GET and POST attributes of an HttpRequest object are now QueryDicts rather than dictionaries, and the FILES attribute is now a MultiValueDict. This brings this class into line with the documentation and with WSGIRequest. • The HttpResponse.charset attribute was added.

9.1. Final releases

1511

Django Documentation, Release 2.1.dev20171115023625

• WSGIRequestHandler now follows RFC in converting URI to IRI, using uri_to_iri(). • The HttpRequest.get_full_path() method now escapes unsafe characters from the path portion of a Uniform Resource Identifier (URI) properly. • HttpResponse now implements a few additional methods like getvalue() so that instances can be used as stream objects. • The new HttpResponse.setdefault() method allows setting a header unless it has already been set. • You can use the new FileResponse to stream files. • The condition() decorator for conditional view processing now supports the If-unmodified-since header. Tests • The RequestFactory.trace() and Client.trace() methods were implemented, allowing you to create TRACE requests in your tests. • The count argument was added to assertTemplateUsed(). This allows you to assert that a template was rendered a specific number of times. • The new assertJSONNotEqual() assertion allows you to test that two JSON fragments are not equal. • Added options to the test command to preserve the test database (--keepdb), to run the test cases in reverse order (--reverse), and to enable SQL logging for failing tests (--debug-sql). • Added the resolver_match attribute to test client responses. • Added several settings that allow customization of test tablespace parameters for Oracle: DATAFILE, DATAFILE_TMP, DATAFILE_MAXSIZE and DATAFILE_TMP_MAXSIZE. • The override_settings() decorator can now affect the master router in DATABASE_ROUTERS. • Added test client support for file uploads with file-like objects. • A shared cache is now used when testing with an SQLite in-memory database when using Python 3.4+ and SQLite 3.7.13+. This allows sharing the database between threads. Validators • URLValidator now supports IPv6 addresses, unicode domains, and URLs containing authentication data. Backwards incompatible changes in 1.8

Warning: In addition to the changes outlined in this section, be sure to review the deprecation plan for any features that have been removed. If you haven’t updated your code within the deprecation timeline for a given feature, its removal may appear as a backwards incompatible change. Related object operations are run in a transaction Some operations on related objects such as add() or direct assignment ran multiple data modifying queries without wrapping them in transactions. To reduce the risk of data corruption, all data modifying methods that affect multiple

1512

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

related objects (i.e. add(), remove(), clear(), and direct assignment) now perform their data modifying queries from within a transaction, provided your database supports transactions. This has one backwards incompatible side effect, signal handlers triggered from these methods are now executed within the method’s transaction and any exception in a signal handler will prevent the whole operation. Assigning unsaved objects to relations raises an error

Note: To more easily allow in-memory usage of models, this change was reverted in Django 1.8.4 and replaced with a check during model.save(). For example: >>> book = Book.objects.create(name="Django") >>> book.author = Author(name="John") >>> book.save() Traceback (most recent call last): ... ValueError: save() prohibited to prevent data loss due to unsaved related object ˓→'author'.

A similar check on assignment to reverse one-to-one relations was removed in Django 1.8.5. Assigning unsaved objects to a ForeignKey, GenericForeignKey, and OneToOneField now raises a ValueError. Previously, the assignment of an unsaved object would be silently ignored. For example: >>> >>> >>> >>>

book = Book.objects.create(name="Django") book.author = Author(name="John") book.author.save() book.save()

>>> Book.objects.get(name="Django") >>> book.author >>>

Now, an error will be raised to prevent data loss: >>> book.author = Author(name="john") Traceback (most recent call last): ... ValueError: Cannot assign "": "Author" instance isn't saved in the ˓→database.

If you require allowing the assignment of unsaved instances (the old behavior) and aren’t concerned about the data loss possibility (e.g. you never save the objects to the database), you can disable this check by using the ForeignKey. allow_unsaved_instance_assignment attribute. (This attribute was removed in 1.8.4 as it’s no longer relevant.) Management commands that only accept positional arguments If you have written a custom management command that only accepts positional arguments and you didn’t specify the args command variable, you might get an error like Error: unrecognized arguments: ..., as variable parsing is now based on argparse which doesn’t implicitly accept positional arguments. You can make your command backwards compatible by simply setting the args class variable. However, if you don’t have to keep 9.1. Final releases

1513

Django Documentation, Release 2.1.dev20171115023625

compatibility with older Django versions, it’s better to implement the new add_arguments() method as described in Writing custom django-admin commands. Custom test management command arguments through test runner The method to add custom arguments to the test management command through the test runner has changed. Previously, you could provide an option_list class variable on the test runner to add more arguments (à la optparse). Now to implement the same behavior, you have to create an add_arguments(cls, parser) class method on the test runner and call parser.add_argument to add any custom arguments, as parser is now an argparse. ArgumentParser instance. Model check ensures auto-generated column names are within limits specified by database A field name that’s longer than the column name length supported by a database can create problems. For example, with MySQL you’ll get an exception trying to create the column, and with PostgreSQL the column name is truncated by the database (you may see a warning in the PostgreSQL logs). A model check has been introduced to better alert users to this scenario before the actual creation of database tables. If you have an existing model where this check seems to be a false positive, for example on PostgreSQL where the name was already being truncated, simply use db_column to specify the name that’s being used. The check also applies to the columns generated in an implicit ManyToManyField.through model. If you run into an issue there, use through to create an explicit model and then specify db_column on its column(s) as needed. Query relation lookups now check object types Querying for model lookups now checks if the object passed is of correct type and raises a ValueError if not. Previously, Django didn’t care if the object was of correct type; it just used the object’s related field attribute (e.g. id) for the lookup. Now, an error is raised to prevent incorrect lookups: >>> book = Book.objects.create(name="Django") >>> book = Book.objects.filter(author=book) Traceback (most recent call last): ... ValueError: Cannot query "": Must be "Author" instance.

select_related() now checks given fields select_related() now validates that the given fields actually exist. Previously, nonexistent fields were silently ignored. Now, an error is raised: >>> book = Book.objects.select_related('nonexistent_field') Traceback (most recent call last): ... FieldError: Invalid field name(s) given in select_related: 'nonexistent_field'

The validation also makes sure that the given field is relational:

1514

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

>>> book = Book.objects.select_related('name') Traceback (most recent call last): ... FieldError: Non-relational field given in select_related: 'name'

Default EmailField.max_length increased to 254 The old default 75 character max_length was not capable of storing all possible RFC3696/5321-compliant email addresses. In order to store all possible valid email addresses, the max_length has been increased to 254 characters. You will need to generate and apply database migrations for your affected models (or add max_length=75 if you wish to keep the length on your current fields). A migration for django.contrib.auth.models.User. email is included. Support for PostgreSQL versions older than 9.0 The end of upstream support periods was reached in July 2014 for PostgreSQL 8.4. As a consequence, Django 1.8 sets 9.0 as the minimum PostgreSQL version it officially supports. This also includes dropping support for PostGIS 1.3 and 1.4 as these versions are not supported on versions of PostgreSQL later than 8.4. Django also now requires the use of Psycopg2 version 2.4.5 or higher (or 2.5+ if you want to use django.contrib. postgres). Support for MySQL versions older than 5.5 The end of upstream support periods was reached in January 2012 for MySQL 5.0 and December 2013 for MySQL 5.1. As a consequence, Django 1.8 sets 5.5 as the minimum MySQL version it officially supports. Support for Oracle versions older than 11.1 The end of upstream support periods was reached in July 2010 for Oracle 9.2, January 2012 for Oracle 10.1, and July 2013 for Oracle 10.2. As a consequence, Django 1.8 sets 11.1 as the minimum Oracle version it officially supports. Specific privileges used instead of roles for tests on Oracle Earlier versions of Django granted the CONNECT and RESOURCE roles to the test user on Oracle. These roles have been deprecated, so Django 1.8 uses the specific underlying privileges instead. This changes the privileges required of the main user for running tests (unless the project is configured to avoid creating a test user). The exact privileges required now are detailed in Oracle notes. AbstractUser.last_login allows null values The AbstractUser.last_login field now allows null values. Previously, it defaulted to the time when the user was created which was misleading if the user never logged in. If you are using the default user (django.contrib. auth.models.User), run the database migration included in contrib.auth.

9.1. Final releases

1515

Django Documentation, Release 2.1.dev20171115023625

If you are using a custom user model that inherits from AbstractUser, you’ll need to run makemigrations and generate a migration for your app that contains that model. Also, if wish to set last_login to NULL for users who haven’t logged in, you can run this query: from django.db import models from django.contrib.auth import get_user_model from django.contrib.auth.models import AbstractBaseUser UserModel = get_user_model() if issubclass(UserModel, AbstractBaseUser): UserModel._default_manager.filter( last_login=models.F('date_joined') ).update(last_login=None)

django.contrib.gis • Support for GEOS 3.1 and GDAL 1.6 has been dropped. • Support for SpatiaLite < 2.4 has been dropped. • GIS-specific lookups have been refactored to use the django.db.models.Lookup API. • The default str representation of GEOSGeometry objects has been changed from WKT to EWKT format (including the SRID). As this representation is used in the serialization framework, that means that dumpdata output will now contain the SRID value of geometry objects. Priority of context processors for TemplateResponse brought in line with render The TemplateResponse constructor is designed to be a drop-in replacement for the render() function. However, it had a slight incompatibility, in that for TemplateResponse, context data from the passed in context dictionary could be shadowed by context data returned from context processors, whereas for render it was the other way around. This was a bug, and the behavior of render is more appropriate, since it allows the globally defined context processors to be overridden locally in the view. If you were relying on the fact context data in a TemplateResponse could be overridden using a context processor, you will need to change your code. Overriding setUpClass / tearDownClass in test cases The decorators override_settings() and modify_settings() now act at the class level when used as class decorators. As a consequence, when overriding setUpClass() or tearDownClass(), the super implementation should always be called. Removal of django.contrib.formtools The formtools contrib app has been moved to a separate package and the relevant documentation pages have been updated or removed. The new package is available on GitHub and on PyPI.

1516

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Database connection reloading between tests Django previously closed database connections between each test within a TestCase. This is no longer the case as Django now wraps the whole TestCase within a transaction. If some of your tests relied on the old behavior, you should have them inherit from TransactionTestCase instead. Cleanup of the django.template namespace If you’ve been relying on private APIs exposed in the django.template module, you may have to import them from django.template.base instead. Also private APIs django.template.base.compile_string(), django.template.loader. find_template(), and django.template.loader.get_template_from_string() were removed. model attribute on private model relations In earlier versions of Django, on a model with a reverse foreign key relationship (for example), model. _meta.get_all_related_objects() returned the relationship as a django.db.models.related. RelatedObject with the model attribute set to the source of the relationship. Now, this method returns the relationship as django.db.models.fields.related.ManyToOneRel (private API RelatedObject has been removed), and the model attribute is set to the target of the relationship instead of the source. The source model is accessible on the related_model attribute instead. Consider this example from the tutorial in Django 1.8: >>> p = Poll.objects.get(pk=1) >>> p._meta.get_all_related_objects() [] >>> p._meta.get_all_related_objects()[0].model >>> p._meta.get_all_related_objects()[0].related_model

and compare it to the behavior on older versions: >>> p._meta.get_all_related_objects() [] >>> p._meta.get_all_related_objects()[0].model

To access the source model, you can use a pattern like this to write code that will work with both Django 1.8 and older versions: for relation in opts.get_all_related_objects(): to_model = getattr(relation, 'related_model', relation.model)

Also note that get_all_related_objects() is deprecated in 1.8. See the upgrade guide for the new API. Database backend API The following changes to the database backend API are documented to assist those writing third-party backends in updating their code:

9.1. Final releases

1517

Django Documentation, Release 2.1.dev20171115023625

• BaseDatabaseXXX classes have been moved to django.db.backends.base. Please import them from the new locations: from from from from from from from from from

django.db.backends.base.base import BaseDatabaseWrapper django.db.backends.base.client import BaseDatabaseClient django.db.backends.base.creation import BaseDatabaseCreation django.db.backends.base.features import BaseDatabaseFeatures django.db.backends.base.introspection import BaseDatabaseIntrospection django.db.backends.base.introspection import FieldInfo, TableInfo django.db.backends.base.operations import BaseDatabaseOperations django.db.backends.base.schema import BaseDatabaseSchemaEditor django.db.backends.base.validation import BaseDatabaseValidation

• The data_types, data_types_suffix, and data_type_check_constraints attributes have moved from the DatabaseCreation class to DatabaseWrapper. • The SQLCompiler.as_sql() method now takes a subquery parameter (#24164). • The BaseDatabaseOperations.date_interval_sql() method now only takes a timedelta parameter. django.contrib.admin • AdminSite no longer takes an app_name argument and its app_name attribute has been removed. The application name is always admin (as opposed to the instance name which you can still customize using AdminSite(name="..."). • The ModelAdmin.get_object() method (private API) now takes a third argument named from_field in order to specify which field should match the provided object_id. • The ModelAdmin.response_delete() method now takes a second argument named obj_id which is the serialized identifier used to retrieve the object before deletion. Default autoescaping of functions in django.template.defaultfilters In order to make built-in template filters that output HTML “safe by default” when calling them in Python code, the following functions in django.template.defaultfilters have been changed to automatically escape their input value: • join • linebreaksbr • linebreaks_filter • linenumbers • unordered_list • urlize • urlizetrunc You can revert to the old behavior by specifying autoescape=False if you are passing trusted content. This change doesn’t have any effect when using the corresponding filters in templates.

1518

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Miscellaneous • connections.queries is now a read-only attribute. • Database connections are considered equal only if they’re the same object. They aren’t hashable any more. • GZipMiddleware used to disable compression for some content types when the request is from Internet Explorer, in order to work around a bug in IE6 and earlier. This behavior could affect performance on IE7 and later. It was removed. • URLField.to_python no longer adds a trailing slash to pathless URLs. • The length template filter now returns 0 for an undefined variable, rather than an empty string. • ForeignKey.default_error_message['invalid'] has been changed from '%(model)s instance with pk %(pk)r does not exist.' to '%(model)s instance with %(field)s %(value)r does not exist.' If you are using this message in your own code, please update the list of interpolated parameters. Internally, Django will continue to provide the pk parameter in params for backwards compatibility. • UserCreationForm.error_messages['duplicate_username'] is no longer used. If you wish to customize that error message, override it on the form using the 'unique' key in Meta. error_messages['username'] or, if you have a custom form field for 'username', using the the 'unique' key in its error_messages argument. • The block usertools in the base.html template of django.contrib.admin now requires the has_permission context variable to be set. If you have any custom admin views that use this template, update them to pass AdminSite.has_permission() as this new variable’s value or simply include AdminSite.each_context(request) in the context. • Internal changes were made to the ClearableFileInput widget to allow more customization. The undocumented url_markup_template attribute was removed in favor of template_with_initial. • For consistency with other major vendors, the en_GB locale now has Monday as the first day of the week. • Seconds have been removed from any locales that had them in TIME_FORMAT, DATETIME_FORMAT, or SHORT_DATETIME_FORMAT. • The default max size of the Oracle test tablespace has increased from 300M (or 200M, before 1.7.2) to 500M. • reverse() and reverse_lazy() now return Unicode strings instead of byte strings. • The CacheClass shim has been removed from all cache backends. These aliases were provided for backwards compatibility with Django 1.3. If you are still using them, please update your project to use the real class name found in the BACKEND key of the CACHES setting. • By default, call_command() now always skips the check framework (unless you pass it skip_checks=False). • When iterating over lines, File now uses universal newlines. The following are recognized as ending a line: the Unix end-of-line convention '\n', the Windows convention '\r\n', and the old Macintosh convention '\r'. • The Memcached cache backends MemcachedCache and PyLibMCCache will delete a key if set() fails. This is necessary to ensure the cache_db session store always fetches the most current session data. • Private APIs override_template_loaders and override_with_test_loader in django. test.utils were removed. Override TEMPLATES with override_settings instead. • Warnings from the MySQL database backend are no longer converted to exceptions when DEBUG is True. • HttpRequest now has a simplified repr (e.g. ). This won’t change the behavior of the SafeExceptionReporterFilter class.

9.1. Final releases

1519

Django Documentation, Release 2.1.dev20171115023625

• Class-based views that use ModelFormMixin will raise an ImproperlyConfigured exception when both the fields and form_class attributes are specified. Previously, fields was silently ignored. • When following redirects, the test client now raises RedirectCycleError if it detects a loop or hits a maximum redirect limit (rather than passing silently). • Translatable strings set as the default parameter of the field are cast to concrete strings later, so the return type of Field.get_default() is different in some cases. There is no change to default values which are the result of a callable. • GenericIPAddressField.empty_strings_allowed is now False. Database backends that interpret empty strings as null (only Oracle among the backends that Django includes) will no longer convert null values back to an empty string. This is consistent with other backends. • When the leave_locale_alone attribute is False, translations are now deactivated instead of forcing the “en-us” locale. In the case your models contained non-English strings and you counted on English translations to be activated in management commands, this will not happen any longer. It might be that new database migrations are generated (once) after migrating to 1.8. • django.utils.translation.get_language() now returns None instead of LANGUAGE_CODE when translations are temporarily deactivated. • When a translation doesn’t exist for a specific literal, the fallback is now taken from the LANGUAGE_CODE language (instead of from the untranslated msgid message). • The name field of django.contrib.contenttypes.models.ContentType has been removed by a migration and replaced by a property. That means it’s not possible to query or filter a ContentType by this field any longer. Be careful if you upgrade to Django 1.8 and skip Django 1.7. If you run manage.py migrate --fake, this migration will be skipped and you’ll see a RuntimeError: Error creating new content types. exception because the name column won’t be dropped from the database. Use manage.py migrate --fake-initial to fake only the initial migration instead. • The new migrate --fake-initial option allows faking initial migrations. In 1.7, initial migrations were always automatically faked if all tables created in an initial migration already existed. • An app without migrations with a ForeignKey to an app with migrations may now result in a foreign key constraint error when migrating the database or running tests. In Django 1.7, this could fail silently and result in a missing constraint. To resolve the error, add migrations to the app without them. Features deprecated in 1.8 Selected methods in django.db.models.options.Options As part of the formalization of the Model._meta API (from the django.db.models.options.Options class), a number of methods have been deprecated and will be removed in Django 1.10: • get_all_field_names() • get_all_related_objects() • get_all_related_objects_with_model() • get_all_related_many_to_many_objects() • get_all_related_m2m_objects_with_model() • get_concrete_fields_with_model() • get_field_by_name()

1520

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

• get_fields_with_model() • get_m2m_with_model() A migration guide has been provided to assist in converting your code from the old API to the new, official API. Loading cycle and firstof template tags from future library Django 1.6 introduced {% load cycle from future %} and {% load firstof from future %} syntax for forward compatibility of the cycle and firstof template tags. This syntax is now deprecated and will be removed in Django 1.10. You can simply remove the {% load ... from future %} tags. django.conf.urls.patterns() In the olden days of Django, it was encouraged to reference views as strings in urlpatterns: urlpatterns = patterns('', url('^$', 'myapp.views.myview'), )

and Django would magically import myapp.views.myview internally and turn the string into a real function reference. In order to reduce repetition when referencing many views from the same module, the patterns() function takes a required initial prefix argument which is prepended to all views-as-strings in that set of urlpatterns: urlpatterns = patterns('myapp.views', url('^$', 'myview'), url('^other/$', 'otherview'), )

In the modern era, we have updated the tutorial to instead recommend importing your views module and referencing your view functions (or classes) directly. This has a number of advantages, all deriving from the fact that we are using normal Python in place of “Django String Magic”: the errors when you mistype a view name are less obscure, IDEs can help with autocompletion of view names, etc. So these days, the above use of the prefix arg is much more likely to be written (and is better written) as: from myapp import views urlpatterns = patterns('', url('^$', views.myview), url('^other/$', views.otherview), )

Thus patterns() serves little purpose and is a burden when teaching new users (answering the newbie’s question “why do I need this empty string as the first argument to patterns()?”). For these reasons, we are deprecating it. Updating your code is as simple as ensuring that urlpatterns is a list of django.conf.urls.url() instances. For example: from django.conf.urls import url from myapp import views urlpatterns = [ url('^$', views.myview), url('^other/$', views.otherview), ]

9.1. Final releases

1521

Django Documentation, Release 2.1.dev20171115023625

Passing a string as view to url() Related to the previous item, referencing views as strings in the url() function is deprecated. Pass the callable view as described in the previous section instead. Template-related settings As a consequence of the multiple template engines refactor, several settings are deprecated in favor of TEMPLATES: • ALLOWED_INCLUDE_ROOTS • TEMPLATE_CONTEXT_PROCESSORS • TEMPLATE_DEBUG • TEMPLATE_DIRS • TEMPLATE_LOADERS • TEMPLATE_STRING_IF_INVALID django.core.context_processors Built-in template context processors have been moved to django.template.context_processors. django.test.SimpleTestCase.urls The attribute SimpleTestCase.urls for specifying URLconf configuration in tests has been deprecated and will be removed in Django 1.10. Use @override_settings(ROOT_URLCONF=...) instead. prefix argument to i18n_patterns() Related to the previous item, the prefix argument to django.conf.urls.i18n.i18n_patterns() has been deprecated. Simply pass a list of django.conf.urls.url() instances instead. Using an incorrect count of unpacked values in the for template tag Using an incorrect count of unpacked values in for tag will raise an exception rather than fail silently in Django 1.10. Passing a dotted path to reverse() and url Reversing URLs by Python path is an expensive operation as it causes the path being reversed to be imported. This behavior has also resulted in a security issue. Use named URL patterns for reversing instead. If you are using django.contrib.sitemaps, add the name argument to the url that references django. contrib.sitemaps.views.sitemap(): from django.contrib.sitemaps.views import sitemap url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap')

1522

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

to ensure compatibility when reversing by Python path is removed in Django 1.10. Similarly for GIS sitemaps, add name='django.contrib.gis.sitemaps.views.kml' name='django.contrib.gis.sitemaps.views.kmz'.

or

If you are using a Python path for the LOGIN_URL or LOGIN_REDIRECT_URL setting, use the name of the url() instead. Aggregate methods and modules The django.db.models.sql.aggregates and django.contrib.gis.db.models.sql. aggregates modules (both private API), have been deprecated as django.db.models.aggregates and django.contrib.gis.db.models.aggregates are now also responsible for SQL generation. The old modules will be removed in Django 1.10. If you were using the old modules, see Query Expressions for instructions on rewriting custom aggregates using the new stable API. The following methods and properties of django.db.models.sql.query.Query have also been deprecated and the backwards compatibility shims will be removed in Django 1.10: • Query.aggregates, replaced by annotations. • Query.aggregate_select, replaced by annotation_select. • Query.add_aggregate(), replaced by add_annotation(). • Query.set_aggregate_mask(), replaced by set_annotation_mask(). • Query.append_aggregate_mask(), replaced by append_annotation_mask(). Extending management command arguments through Command.option_list Management commands now use argparse instead of optparse to parse command-line arguments passed to commands. This also means that the way to add custom arguments to commands has changed: instead of extending the option_list class list, you should now override the add_arguments() method and add arguments through argparse.add_argument(). See this example for more details. django.core.management.NoArgsCommand The class NoArgsCommand is now deprecated and will be removed in Django 1.10. Use BaseCommand instead, which takes no arguments by default. Listing all migrations in a project The --list option of the migrate management command is deprecated and will be removed in Django 1.10. Use showmigrations instead. cache_choices option of ModelChoiceField and ModelMultipleChoiceField ModelChoiceField and ModelMultipleChoiceField took an undocumented, untested option cache_choices. This cached querysets between multiple renderings of the same Form object. This option is subject to an accelerated deprecation and will be removed in Django 1.9.

9.1. Final releases

1523

Django Documentation, Release 2.1.dev20171115023625

django.template.resolve_variable() The function has been informally marked as “Deprecated” for some time. Replace resolve_variable(path, context) with django.template.Variable(path).resolve(context). django.contrib.webdesign It provided the lorem template tag which is now included in the built-in tags. Simply remove 'django.contrib. webdesign' from INSTALLED_APPS and {% load webdesign %} from your templates. error_message argument to django.forms.RegexField It provided backwards compatibility for pre-1.0 code, but its functionality is redundant. error_messages['invalid'] instead.

Use Field.

Old unordered_list syntax An older (pre-1.0), more restrictive and verbose input format for the unordered_list template filter has been deprecated: ['States', [['Kansas', [['Lawrence', []], ['Topeka', []]]], ['Illinois', []]]]

Using the new syntax, this becomes: ['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]

django.forms.Field._has_changed() Rename this method to has_changed() by removing the leading underscore. The old name will still work until Django 1.10. django.utils.html.remove_tags() and removetags template filter django.utils.html.remove_tags() as well as the template filter removetags have been deprecated as they cannot guarantee safe output. Their existence is likely to lead to their use in security-sensitive contexts where they are not actually safe. The unused and undocumented django.utils.html.strip_entities() function has also been deprecated. is_admin_site argument to django.contrib.auth.views.password_reset() It’s a legacy option that should no longer be necessary.

1524

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

SubfieldBase django.db.models.fields.subclassing.SubfieldBase has been deprecated and will be removed in Django 1.10. Historically, it was used to handle fields where type conversion was needed when loading from the database, but it was not used in .values() calls or in aggregates. It has been replaced with from_db_value(). The new approach doesn’t call the to_python() method on assignment as was the case with SubfieldBase. If you need that behavior, reimplement the Creator class from Django’s source code in your project. django.utils.checksums The django.utils.checksums module has been deprecated and will be removed in Django 1.10. The functionality it provided (validating checksum using the Luhn algorithm) was undocumented and not used in Django. The module has been moved to the django-localflavor package (version 1.1+). InlineAdminForm.original_content_type_id The original_content_type_id attribute on InlineAdminForm has been deprecated and will be removed in Django 1.10. Historically, it was used to construct the “view on site” URL. This URL is now accessible using the absolute_url attribute of the form. django.views.generic.edit.FormMixin.get_form()’s form_class argument FormMixin subclasses that override the get_form() method should make sure to provide a default value for the form_class argument since it’s now optional. Rendering templates loaded by get_template() with a Context The return type of get_template() has changed in Django 1.8: instead of a django.template.Template, it returns a Template instance whose exact type depends on which backend loaded it. Both classes provide a render() method, however, the former takes a django.template.Context as an argument while the latter expects a dict. This change is enforced through a deprecation path for Django templates. All this also applies to select_template(). Template and Context classes in template responses Some methods of SimpleTemplateResponse and TemplateResponse accepted django.template. Context and django.template.Template objects as arguments. They should now receive dict and backend-dependent template objects respectively. This also applies to the return types if you have subclassed either template response class. Check the template response API documentation for details. current_app argument of template-related APIs The following functions and classes will no longer accept a current_app parameter to set an URL namespace in Django 1.10:

9.1. Final releases

1525

Django Documentation, Release 2.1.dev20171115023625

• django.shortcuts.render() • django.template.Context() • django.template.RequestContext() • django.template.response.TemplateResponse() Set request.current_app instead, where request is the first argument to these functions or classes. If you’re using a plain Context, use a RequestContext instead. dictionary and context_instance arguments of rendering functions The following functions will no longer accept the dictionary and context_instance parameters in Django 1.10: • django.shortcuts.render() • django.shortcuts.render_to_response() • django.template.loader.render_to_string() Use the context parameter instead. When dictionary is passed as a positional argument, which is the most common idiom, no changes are needed. If you’re passing a Context in context_instance, pass a dict in the context parameter instead. If you’re passing a RequestContext, pass the request separately in the request parameter. dirs argument of template-finding functions The following functions will no longer accept a dirs parameter to override TEMPLATE_DIRS in Django 1.10: • django.template.loader.get_template() • django.template.loader.select_template() • django.shortcuts.render() • django.shortcuts.render_to_response() The parameter didn’t work consistently across different template loaders and didn’t work for included templates. django.template.loader.BaseLoader django.template.loader.BaseLoader was renamed to django.template.loaders.base. Loader. If you’ve written a custom template loader that inherits BaseLoader, you must inherit Loader instead. django.test.utils.TestTemplateLoader Private API django.test.utils.TestTemplateLoader is deprecated in favor of django.template. loaders.locmem.Loader and will be removed in Django 1.9.

1526

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Support for the max_length argument on custom Storage classes Storage subclasses should add max_length=None as a parameter to get_available_name() and/or save() if they override either method. Support for storages that do not accept this argument will be removed in Django 1.10. qn replaced by compiler In previous Django versions, various internal ORM methods (mostly as_sql methods) accepted a qn (for “quote name”) argument, which was a reference to a function that quoted identifiers for sending to the database. In Django 1.8, that argument has been renamed to compiler and is now a full SQLCompiler instance. For backwardscompatibility, calling a SQLCompiler instance performs the same name-quoting that the qn function used to. However, this backwards-compatibility shim is immediately deprecated: you should rename your qn arguments to compiler, and call compiler.quote_name_unless_alias(...) where you previously called qn(...). Default value of RedirectView.permanent The default value of the RedirectView.permanent attribute will change from True to False in Django 1.9. Using AuthenticationMiddleware without SessionAuthenticationMiddleware django.contrib.auth.middleware.SessionAuthenticationMiddleware was added in Django 1.7. In Django 1.7.2, its functionality was moved to auth.get_user() and, for backwards compatibility, enabled only if 'django.contrib.auth.middleware.SessionAuthenticationMiddleware' appears in MIDDLEWARE_CLASSES. In Django 1.10, session verification will be enabled regardless of whether or not SessionAuthenticationMiddleware is enabled (at which point SessionAuthenticationMiddleware will have no significance). You can add it to your MIDDLEWARE_CLASSES sometime before then to opt-in. Please read the upgrade considerations first. django.contrib.sitemaps.FlatPageSitemap django.contrib.sitemaps.FlatPageSitemap has moved to django.contrib.flatpages. sitemaps.FlatPageSitemap. The old import location is deprecated and will be removed in Django 1.9. Model Field.related Private attribute django.db.models.Field.related is deprecated in favor of Field.rel. The latter is an instance of django.db.models.fields.related.ForeignObjectRel which replaces django.db. models.related.RelatedObject. The django.db.models.related module has been removed and the Field.related attribute will be removed in Django 1.10. ssi template tag The ssi template tag allows files to be included in a template by absolute path. This is of limited use in most deployment situations, and the include tag often makes more sense. This tag is now deprecated and will be removed in Django 1.10.

9.1. Final releases

1527

Django Documentation, Release 2.1.dev20171115023625

= as comparison operator in if template tag Using a single equals sign with the {% if %} template tag for equality testing was undocumented and untested. It’s now deprecated in favor of ==. %()s syntax in ModelFormMixin.success_url The legacy %()s syntax in ModelFormMixin.success_url is deprecated and will be removed in Django 1.10. GeoQuerySet aggregate methods The collect(), extent(), extent3d(), make_line(), and unionagg() aggregate methods are deprecated and should be replaced by their function-based aggregate equivalents (Collect, Extent, Extent3D, MakeLine, and Union). Signature of the allow_migrate router method The signature of the allow_migrate() method of database routers has changed from allow_migrate(db, model) to allow_migrate(db, app_label, model_name=None, **hints). When model_name is set, the value that was previously given through the model positional argument may now be found inside the hints dictionary under the key 'model'. After switching to the new signature the router will also be called by the RunPython and RunSQL operations. Features removed in 1.8 These features have reached the end of their deprecation cycle and are removed in Django 1.8. See Features deprecated in 1.6 for details, including how to remove usage of these features. • django.contrib.comments is removed. • The following transaction management APIs are removed: – TransactionMiddleware – the decorators and context managers autocommit, commit_manually, defined in django.db.transaction

commit_on_success,

and

– the functions commit_unless_managed and rollback_unless_managed, also defined in django.db.transaction – the TRANSACTIONS_MANAGED setting • The cycle and firstof template tags auto-escape their arguments. • The SEND_BROKEN_LINK_EMAILS setting is removed. • django.middleware.doc.XViewMiddleware is removed. • The Model._meta.module_name alias is removed. • The backward compatible shims introduced to rename get_query_set and similar queryset methods are removed. This affects the following classes: BaseModelAdmin, ChangeList,

1528

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

BaseCommentNode, GenericForeignKey, Manager, SingleRelatedObjectDescriptor and ReverseSingleRelatedObjectDescriptor. • The backward compatible shims introduced to rename the attributes ChangeList.root_query_set and ChangeList.query_set are removed. • django.views.defaults.shortcut and django.conf.urls.shortcut are removed. • Support for the Python Imaging Library (PIL) module is removed. • The following private APIs are removed: – django.db.backend – django.db.close_connection() – django.db.backends.creation.BaseDatabaseCreation.set_autocommit() – django.db.transaction.is_managed() – django.db.transaction.managed() • django.forms.widgets.RadioInput is removed. • The module django.test.simple DjangoTestSuiteRunner are removed.

and

the

class

django.test.simple.

• The module django.test._doctest is removed. • The CACHE_MIDDLEWARE_ANONYMOUS_ONLY setting is removed. This change affects both django.middleware.cache.CacheMiddleware and django.middleware.cache. UpdateCacheMiddleware despite the lack of a deprecation warning in the latter class. • Usage of the hard-coded Hold down “Control”, or “Command” on a Mac, to select more than one. string to override or append to user-provided help_text in forms for ManyToMany model fields is not performed by Django anymore either at the model or forms layer. • The Model._meta.get_(add|change|delete)_permission methods are removed. • The session key django_language is no longer read for backwards compatibility. • Geographic Sitemaps are removed (django.contrib.gis.sitemaps.views.index and django. contrib.gis.sitemaps.views.sitemap). • django.utils.html.fix_ampersands, the fix_ampersands template filter, and django. utils.html.clean_html are removed.

9.1.7 1.7 release Django 1.7.11 release notes November 24, 2015 Django 1.7.11 fixes a security issue and a data loss bug in 1.7.10. Fixed settings leak possibility in date template filter If an application allows users to specify an unvalidated format for dates and passes this format to the date filter, e.g. {{ last_updated|date:user_date_format }}, then a malicious user could obtain any secret in the application’s settings by specifying a settings key instead of a date format. e.g. "SECRET_KEY" instead of "j/m/ Y".

9.1. Final releases

1529

Django Documentation, Release 2.1.dev20171115023625

To remedy this, the underlying function used by the date template filter, django.utils.formats. get_format(), now only allows accessing the date/time formatting settings. Bugfixes • Fixed a data loss possibility with Prefetch if to_attr is set to a ManyToManyField (#25693). Django 1.7.10 release notes August 18, 2015 Django 1.7.10 fixes a security issue in 1.7.9. Denial-of-service possibility in logout() view by filling session store Previously, a session could be created when anonymously accessing the django.contrib.auth.views. logout() view (provided it wasn’t decorated with login_required() as done in the admin). This could allow an attacker to easily create many new session records by sending repeated requests, potentially filling up the session store or causing other users’ session records to be evicted. The SessionMiddleware has been modified to no longer create empty session records, including when SESSION_SAVE_EVERY_REQUEST is active. Additionally, the contrib.sessions.backends.base.SessionBase.flush() and cache_db. SessionStore.flush() methods have been modified to avoid creating a new empty session. Maintainers of third-party session backends should check if the same vulnerability is present in their backend and correct it if so. Django 1.7.9 release notes July 8, 2015 Django 1.7.9 fixes several security issues and bugs in 1.7.8. Denial-of-service possibility by filling session store In previous versions of Django, the session backends created a new empty record in the session storage anytime request.session was accessed and there was a session key provided in the request cookies that didn’t already have a session record. This could allow an attacker to easily create many new session records simply by sending repeated requests with unknown session keys, potentially filling up the session store or causing other users’ session records to be evicted. The built-in session backends now create a session record only if the session is actually modified; empty session records are not created. Thus this potential DoS is now only possible if the site chooses to expose a session-modifying view to anonymous users. As each built-in session backend was fixed separately (rather than a fix in the core sessions framework), maintainers of third-party session backends should check whether the same vulnerability is present in their backend and correct it if so.

1530

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Header injection possibility since validators accept newlines in input Some of Django’s built-in validators (EmailValidator, most seriously) didn’t prohibit newline characters (due to the usage of $ instead of \Z in the regular expressions). If you use values with newlines in HTTP response or email headers, you can suffer from header injection attacks. Django itself isn’t vulnerable because HttpResponse and the mail sending utilities in django.core.mail prohibit newlines in HTTP and SMTP headers, respectively. While the validators have been fixed in Django, if you’re creating HTTP responses or email messages in other ways, it’s a good idea to ensure that those methods prohibit newlines as well. You might also want to validate that any existing data in your application doesn’t contain unexpected newlines. validate_ipv4_address(), validate_slug(), and URLValidator are also affected, however, as of Django 1.6 the GenericIPAddresseField, IPAddressField, SlugField, and URLField form fields which use these validators all strip the input, so the possibility of newlines entering your data only exists if you are using these validators outside of the form fields. The undocumented, internally unused validate_integer() function is now stricter as it validates using a regular expression instead of simply casting the value using int() and checking if an exception was raised. Bugfixes • Prevented the loss of null/not null column properties during field renaming of MySQL databases (#24817). • Fixed SimpleTestCase.assertRaisesMessage() on Python 2.7.10 (#24903). Django 1.7.8 release notes May 1, 2015 Django 1.7.8 fixes: • Database introspection with SQLite 3.8.9 (released April 8, 2015) (#24637). • A database table name quoting regression in 1.7.2 (#24605). • The loss of null/not null column properties during field alteration of MySQL databases (#24595). Django 1.7.7 release notes March 18, 2015 Django 1.7.7 fixes several bugs and security issues in 1.7.6. Denial-of-service possibility with strip_tags() Last year strip_tags() was changed to work iteratively. The problem is that the size of the input it’s processing can increase on each iteration which results in an infinite loop in strip_tags(). This issue only affects versions of Python that haven’t received a bugfix in HTMLParser; namely Python < 2.7.7 and 3.3.5. Some operating system vendors have also backported the fix for the Python bug into their packages of earlier versions. To remedy this issue, strip_tags() will now return the original input if it detects the length of the string it’s processing increases. Remember that absolutely NO guarantee is provided about the results of strip_tags() being HTML safe. So NEVER mark safe the result of a strip_tags() call without escaping it first, for example with escape().

9.1. Final releases

1531

Django Documentation, Release 2.1.dev20171115023625

Mitigated possible XSS attack via user-supplied redirect URLs Django relies on user input in some cases (e.g. django.contrib.auth.views.login() and i18n) to redirect the user to an “on success” URL. The security checks for these redirects (namely django. utils.http.is_safe_url()) accepted URLs with leading control characters and so considered URLs like \x08javascript:... safe. This issue doesn’t affect Django currently, since we only put this URL into the Location response header and browsers seem to ignore JavaScript there. Browsers we tested also treat URLs prefixed with control characters such as %08//example.com as relative paths so redirection to an unsafe target isn’t a problem either. However, if a developer relies on is_safe_url() to provide safe redirect targets and puts such a URL into a link, they could suffer from an XSS attack as some browsers such as Google Chrome ignore control characters at the start of a URL in an anchor href. Bugfixes • Fixed renaming of classes in migrations where renaming a subclass would cause incorrect state to be recorded for objects that referenced the superclass (#24354). • Stopped writing migration files in dry run mode when merging migration conflicts. When makemigrations --merge is called with verbosity=3 the migration file is written to stdout (#24427). Django 1.7.6 release notes March 9, 2015 Django 1.7.6 fixes a security issue and several bugs in 1.7.5. Mitigated an XSS attack via properties in ModelAdmin.readonly_fields The ModelAdmin.readonly_fields attribute in the Django admin allows displaying model fields and model attributes. While the former were correctly escaped, the latter were not. Thus untrusted content could be injected into the admin, presenting an exploitation vector for XSS attacks. In this vulnerability, every model attribute used in readonly_fields that is not an actual model field (e.g. a property) will fail to be escaped even if that attribute is not marked as safe. In this release, autoescaping is now correctly applied. Bugfixes • Fixed crash when coercing ManyRelatedManager to a string (#24352). • Fixed a bug that prevented migrations from adding a foreign key constraint when converting an existing field to a foreign key (#24447). Django 1.7.5 release notes February 25, 2015 Django 1.7.5 fixes several bugs in 1.7.4.

1532

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Bugfixes • Reverted a fix that prevented a migration crash when unapplying contrib.contenttypes’s or contrib. auth’s first migration (#24075) due to severe impact on the test performance (#24251) and problems in multidatabase setups (#24298). • Fixed a regression that prevented custom fields inheriting from ManyToManyField from being recognized in migrations (#24236). • Fixed crash in contrib.sites migrations when a default database isn’t used (#24332). • Added the ability to set the isolation level on PostgreSQL with psycopg2 ≥ 2.4.2 (#24318). It was advertised as a new feature in Django 1.6 but it didn’t work in practice. • Formats for the Azerbaijani locale (az) have been added. Django 1.7.4 release notes January 27, 2015 Django 1.7.4 fixes several bugs in 1.7.3. Bugfixes • Fixed a migration crash when unapplying contrib.contenttypes’s or contrib.auth’s first migration (#24075). • Made the migration’s RenameModel operation rename ManyToManyField tables (#24135). • Fixed a migration crash on MySQL when migrating from a OneToOneField to a ForeignKey (#24163). • Prevented the static.serve view from producing ResourceWarnings in certain circumstances (security fix regression, #24193). • Fixed schema check for ManyToManyField to look for internal type instead of checking class instance, so you can write custom m2m-like fields with the same behavior. (#24104). Django 1.7.3 release notes January 13, 2015 Django 1.7.3 fixes several security issues and bugs in 1.7.2. WSGI header spoofing via underscore/dash conflation When HTTP headers are placed into the WSGI environ, they are normalized by converting to uppercase, converting all dashes to underscores, and prepending HTTP_. For instance, a header X-Auth-User would become HTTP_X_AUTH_USER in the WSGI environ (and thus also in Django’s request.META dictionary). Unfortunately, this means that the WSGI environ cannot distinguish between headers containing dashes and headers containing underscores: X-Auth-User and X-Auth_User both become HTTP_X_AUTH_USER. This means that if a header is used in a security-sensitive way (for instance, passing authentication information along from a front-end proxy), even if the proxy carefully strips any incoming value for X-Auth-User, an attacker may be able to provide an X-Auth_User header (with underscore) and bypass this protection.

9.1. Final releases

1533

Django Documentation, Release 2.1.dev20171115023625

In order to prevent such attacks, both Nginx and Apache 2.4+ strip all headers containing underscores from incoming requests by default. Django’s built-in development server now does the same. Django’s development server is not recommended for production use, but matching the behavior of common production servers reduces the surface area for behavior changes during deployment. Mitigated possible XSS attack via user-supplied redirect URLs Django relies on user input in some cases (e.g. django.contrib.auth.views.login() and i18n) to redirect the user to an “on success” URL. The security checks for these redirects (namely django.utils. http.is_safe_url()) didn’t strip leading whitespace on the tested URL and as such considered URLs like \njavascript:... safe. If a developer relied on is_safe_url() to provide safe redirect targets and put such a URL into a link, they could suffer from a XSS attack. This bug doesn’t affect Django currently, since we only put this URL into the Location response header and browsers seem to ignore JavaScript there. Denial-of-service attack against django.views.static.serve In older versions of Django, the django.views.static.serve() view read the files it served one line at a time. Therefore, a big file with no newlines would result in memory usage equal to the size of that file. An attacker could exploit this and launch a denial-of-service attack by simultaneously requesting many large files. This view now reads the file in chunks to prevent large memory usage. Note, however, that this view has always carried a warning that it is not hardened for production use and should be used only as a development aid. Now may be a good time to audit your project and serve your files in production using a real front-end web server if you are not doing so. Database denial-of-service with ModelMultipleChoiceField Given a form that uses ModelMultipleChoiceField and show_hidden_initial=True (not a documented API), it was possible for a user to cause an unreasonable number of SQL queries by submitting duplicate values for the field’s data. The validation logic in ModelMultipleChoiceField now deduplicates submitted values to address this issue. Bugfixes • The default iteration count for the PBKDF2 password hasher has been increased by 25%. This part of the normal major release process was inadvertently omitted in 1.7. This backwards compatible change will not affect users who have subclassed django.contrib.auth.hashers.PBKDF2PasswordHasher to change the default value. • Fixed a crash in the CSRF middleware when handling non-ASCII referer header (#23815). • Fixed a crash in the django.contrib.auth.redirect_to_login view when passing a reverse_lazy() result on Python 3 (#24097). • Added correct formats for Greek (el) (#23967). • Fixed a migration crash when unapplying a migration where multiple operations interact with the same model (#24110).

1534

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Django 1.7.2 release notes January 2, 2015 Django 1.7.2 fixes several bugs in 1.7.1. Additionally, Django’s vendored version of six, django.utils.six, has been upgraded to the latest release (1.9.0). Bugfixes • Fixed migration’s renaming of auto-created many-to-many tables when changing Meta.db_table (#23630). • Fixed a migration crash when adding an explicit id field to a model on SQLite (#23702). • Added a warning for duplicate models when a module is reloaded. Previously a RuntimeError was raised every time two models clashed in the app registry. (#23621). • Prevented flush from loading initial data for migrated apps (#23699). • Fixed a makemessages regression in 1.7.1 when STATIC_ROOT has the default None value (#23717). • Added GeoDjango compatibility with mysqlclient database driver. • Fixed MySQL 5.6+ crash with GeometryFields in migrations (#23719). • Fixed a migration crash when removing a field that is referenced in AlterIndexTogether or AlterUniqueTogether (#23614). • Updated the first day of the week in the Ukrainian locale to Monday. • Added support for transactional spatial metadata initialization on SpatiaLite 4.1+ (#23152). • Fixed a migration crash that prevented changing a nullable field with a default to non-nullable with the same default (#23738). • Fixed a migration crash when adding GeometryFields with blank=True on PostGIS (#23731). • Allowed usage of DateTimeField() as Transform.output_field (#23420). • Fixed a migration serializing bug involving float("nan") and float("inf") (#23770). • Fixed a regression where custom form fields having a queryset attribute but no limit_choices_to could not be used in a ModelForm (#23795). • Fixed a custom field type validation error with MySQL backend when db_type returned None (#23761). • Fixed a migration crash when a field is renamed that is part of an index_together (#23859). • Fixed squashmigrations to respect the --no-optimize parameter (#23799). • Made RenameModel reversible (#22248) • Avoided unnecessary rollbacks of migrations from other apps when migrating backwards (#23410). • Fixed a rare query error when using deeply nested subqueries (#23605). • Fixed a crash in migrations when deleting a field that is part of a index/unique_together constraint (#23794). • Fixed django.core.files.File.__repr__() when the file’s name contains Unicode characters (#23888). • Added missing context to the admin’s delete_selected view that prevented custom site header, etc. from appearing (#23898).

9.1. Final releases

1535

Django Documentation, Release 2.1.dev20171115023625

• Fixed a regression with dynamically generated inlines and allowed field references in the admin (#23754). • Fixed an infinite loop bug for certain cyclic migration dependencies, and made the error message for cyclic dependencies much more helpful. • Added missing index_together handling for SQLite (#23880). • Fixed a crash when RunSQL SQL content was collected by the schema editor, typically when using sqlmigrate (#23909). • Fixed a regression in contrib.admin add/change views which caused some ModelAdmin methods to receive the incorrect obj value (#23934). • Fixed runserver crash when socket error message contained Unicode characters (#23946). • Fixed serialization of type when adding a deconstruct() method (#23950). • Prevented the django.contrib.auth.middleware.SessionAuthenticationMiddleware from setting a "Vary: Cookie" header on all responses (#23939). • Fixed a crash when adding blank=True to TextField() on MySQL (#23920). • Fixed index creation by the migration infrastructure, particularly when dealing with PostgreSQL specific {text|varchar}_pattern_ops indexes (#23954). • Fixed bug in makemigrations that created broken migration files when dealing with multiple table inheritance and inheriting from more than one model (#23956). • Fixed a crash when a MultiValueField has invalid data (#23674). • Fixed a crash in the admin when using “Save as new” and also deleting a related inline (#23857). • Always converted related_name to text (unicode), since that is required on Python 3 for interpolation. Removed conversion of related_name to text in migration deconstruction (#23455 and #23982). • Enlarged the sizes of tablespaces which are created by default for testing on Oracle (the main tablespace was increased from 200M to 300M and the temporary tablespace from 100M to 150M). This was required to accommodate growth in Django’s own test suite (#23969). • Fixed timesince filter translations in Korean (#23989). • Fixed the SQLite SchemaEditor to properly add defaults in the absence of a user specified default. For example, a CharField with blank=True didn’t set existing rows to an empty string which resulted in a crash when adding the NOT NULL constraint (#23987). • makemigrations no longer prompts for a default value when adding TextField() or CharField() without a default (#23405). • Fixed a migration crash when adding order_with_respect_to to a table with existing rows (#23983). • Restored the pre_migrate signal if all apps have migrations (#23975). • Made admin system checks run for custom AdminSites (#23497). • Ensured the app registry is fully populated when unpickling models. When an external script (like a queueing infrastructure) reloads pickled models, it could crash with an AppRegistryNotReady exception (#24007). • Added quoting to field indexes in the SQL generated by migrations to prevent a crash when the index name requires it (##24015). • Added datetime.time support to migrations questioner (#23998). • Fixed admindocs crash on apps installed as eggs (#23525).

1536

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

• Changed migrations autodetector to generate an AlterModelOptions operation instead of DeleteModel and CreateModel operations when changing Meta.managed. This prevents data loss when changing managed from False to True and vice versa (#24037). • Enabled the sqlsequencereset command on apps with migrations (#24054). • Added tablespace SQL to apps with migrations (#24051). • Corrected contrib.sites default site creation in a multiple database setup (#24000). • Restored support for objects that aren’t str or bytes in django.utils.safestring. mark_for_escaping() on Python 3. • Supported strings escaped by third-party libraries with the __html__ convention in the template engine (#23831). • Prevented extraneous DROP DEFAULT SQL in migrations (#23581). • Restored the ability to use more than five levels of subqueries (#23758). • Fixed crash when ValidationError is initialized with a ValidationError that is initialized with a dictionary (#24008). • Prevented a crash on apps without migrations when running migrate --list (#23366). Django 1.7.1 release notes October 22, 2014 Django 1.7.1 fixes several bugs in 1.7. Bugfixes • Allowed related many-to-many fields to be referenced in the admin (#23604). • Added a more helpful error message if you try to migrate an app without first creating the contenttypes table (#22411). • Modified migrations dependency algorithm to avoid possible infinite recursion. • Fixed a UnicodeDecodeError when the flush error message contained Unicode characters (#22882). • Reinstated missing CHECK SQL clauses which were omitted on some backends when not using migrations (#23416). • Fixed serialization of type objects in migrations (#22951). • Allowed inline and hidden references to admin fields (#23431). • The @deconstructible decorator now fails with a ValueError if the decorated object cannot automatically be imported (#23418). • Fixed a typo in an inlineformset_factory() error message that caused a crash (#23451). • Restored the ability to use ABSOLUTE_URL_OVERRIDES with the 'auth.User' model (#11775). As a side effect, the setting now adds a get_absolute_url() method to any model that appears in ABSOLUTE_URL_OVERRIDES but doesn’t define get_absolute_url(). • Avoided masking some ImportError exceptions during application loading (#22920). • Empty index_together or unique_together model options no longer results in infinite migrations (#23452).

9.1. Final releases

1537

Django Documentation, Release 2.1.dev20171115023625

• Fixed crash in contrib.sitemaps if lastmod returned a date rather than a datetime (#23403). • Allowed migrations to work with app_labels that have the same last part (e.g. django.contrib.auth and vendor.auth) (#23483). • Restored the ability to deepcopy F objects (#23492). • Formats for Welsh (cy) and several Chinese locales (zh_CN, zh_Hans, zh_Hant and zh_TW) have been added. Formats for Macedonian have been fixed (trailing dot removed, #23532). • Added quoting of constraint names in the SQL generated by migrations to prevent crash with uppercase characters in the name (#23065). • Fixed renaming of models with a self-referential many-to-many field (ManyToManyField('self')) (#23503). • Added the get_extra(), get_max_num(), GenericInlineModelAdmin (#23539).

and

get_min_num()

hooks

to

• Made migrations.RunSQL no longer require percent sign escaping. This is now consistent with cursor. execute() (#23426). • Made the SERIALIZE entry in the TEST dictionary usable (#23421). • Fixed bug in migrations that prevented foreign key constraints to unmanaged models with a custom primary key (#23415). • Added SchemaEditor for MySQL GIS backend so that spatial indexes will be created for apps with migrations (#23538). • Added SchemaEditor for Oracle GIS backend so that spatial metadata and indexes will be created for apps with migrations (#23537). • Coerced the related_name model field option to unicode during migration generation to generate migrations that work with both Python 2 and 3 (#23455). • Fixed MigrationWriter to handle builtin types without imports (#23560). • Fixed deepcopy on ErrorList (#23594). • Made the admindocs view to browse view details check if the view specified in the URL exists in the URLconf. Previously it was possible to import arbitrary packages from the Python path. This was not considered a security issue because admindocs is only accessible to staff users (#23601). • Fixed UnicodeDecodeError crash in AdminEmailHandler with non-ASCII characters in the request (#23593). • Fixed missing get_or_create IntegrityError (#23611).

and

update_or_create

(Video) Django QuickStart Web Application for Beginners

on

related

managers

causing

• Made urlsafe_base64_decode() return the proper type (byte string) on Python 3 (#23333). • makemigrations can now serialize timezone-aware values (#23365). • Added a prompt to the migrations questioner when removing the null constraint from a field to prevent an IntegrityError on existing NULL rows (#23609). • Fixed generic relations in ModelAdmin.list_filter (#23616). • Restored RFC compliance for the SMTP backend on Python 3 (#23063). • Fixed a crash while parsing cookies containing invalid content (#23638). • The system check framework now raises error models.E020 when the class method Model.check() is unreachable (#23615).

1538

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

• Made the Oracle test database creation drop the test user in the event of an unclean exit of a previous test run (#23649). • Fixed makemigrations to detect changes to Meta.db_table (#23629). • Fixed a regression when feeding the Django test client with an empty data string (#21740). • Fixed a regression in makemessages where static files were unexpectedly ignored (#23583). Django 1.7 release notes September 2, 2014 Welcome to Django 1.7! These release notes cover the new features, as well as some backwards incompatible changes you’ll want to be aware of when upgrading from Django 1.6 or older versions. We’ve begun the deprecation process for some features, and some features have reached the end of their deprecation process and have been removed. Python compatibility Django 1.7 requires Python 2.7, 3.2, 3.3, or 3.4. We highly recommend and only officially support the latest release of each series. The Django 1.6 series is the last to support Python 2.6. Django 1.7 is the first release to support Python 3.4. This change should affect only a small number of Django users, as most operating-system vendors today are shipping Python 2.7 or newer as their default version. If you’re still using Python 2.6, however, you’ll need to stick to Django 1.6 until you can upgrade your Python version. Per our support policy, Django 1.6 will continue to receive security support until the release of Django 1.8. What’s new in Django 1.7 Schema migrations Django now has built-in support for schema migrations. It allows models to be updated, changed, and deleted by creating migration files that represent the model changes and which can be run on any development, staging or production database. Migrations are covered in their own documentation, but a few of the key features are: • syncdb has been deprecated and replaced by migrate. Don’t worry - calls to syncdb will still work as before. • A new makemigrations command provides an easy way to autodetect changes to your models and make migrations for them. django.db.models.signals.pre_syncdb and django.db.models.signals.post_syncdb have been deprecated, to be replaced by pre_migrate and post_migrate respectively. These new signals have slightly different arguments. Check the documentation for details. • The allow_syncdb method on database routers is now called allow_migrate, but still performs the same function. Routers with allow_syncdb methods will still work, but that method name is deprecated and you should change it as soon as possible (nothing more than renaming is required). • initial_data fixtures are no longer loaded for apps with migrations; if you want to load initial data for an app, we suggest you create a migration for your application and define a RunPython or RunSQL operation in the operations section of the migration. 9.1. Final releases

1539

Django Documentation, Release 2.1.dev20171115023625

• Test rollback behavior is different for apps with migrations; in particular, Django will no longer emulate rollbacks on non-transactional databases or inside TransactionTestCase unless specifically requested. • It is not advised to have apps without migrations depend on (have a ForeignKey or ManyToManyField to) apps with migrations. App-loading refactor Historically, Django applications were tightly linked to models. A singleton known as the “app cache” dealt with both installed applications and models. The models module was used as an identifier for applications in many APIs. As the concept of Django applications matured, this code showed some shortcomings. It has been refactored into an “app registry” where models modules no longer have a central role and where it’s possible to attach configuration data to applications. Improvements thus far include: • Applications can run code at startup, before Django does anything else, with the ready() method of their configuration. • Application labels are assigned correctly to models even when they’re defined outside of models.py. You don’t have to set app_label explicitly any more. • It is possible to omit models.py entirely if an application doesn’t have any models. • Applications can be relabeled with the label attribute of application configurations, to work around label conflicts. • The name of applications can be customized in the admin with the verbose_name of application configurations. • The admin automatically calls autodiscover() when Django starts. You can consequently remove this line from your URLconf. • Django imports all application configurations and models as soon as it starts, through a deterministic and straightforward process. This should make it easier to diagnose import issues such as import loops. New method on Field subclasses To help power both schema migrations and to enable easier addition of composite keys in future releases of Django, the Field API now has a new required method: deconstruct(). This method takes no arguments, and returns a tuple of four items: • name: The field’s attribute name on its parent model, or None if it is not part of a model • path: A dotted, Python path to the class of this field, including the class name. • args: Positional arguments, as a list • kwargs: Keyword arguments, as a dict These four values allow any field to be serialized into a file, as well as allowing the field to be copied safely, both essential parts of these new features. This change should not affect you unless you write custom Field subclasses; if you do, you may need to reimplement the deconstruct() method if your subclass changes the method signature of __init__ in any way. If your field just inherits from a built-in Django field and doesn’t override __init__, no changes are necessary.

1540

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

If you do need to override deconstruct(), a good place to start is the built-in Django fields (django/db/ models/fields/__init__.py) as several fields, including DecimalField and DateField, override it and show how to call the method on the superclass and simply add or remove extra arguments. This also means that all arguments to fields must themselves be serializable; to see what we consider serializable, and to find out how to make your own classes serializable, read the migration serialization documentation. Calling custom QuerySet methods from the Manager Historically, the recommended way to make reusable model queries was to create methods on a custom Manager class. The problem with this approach was that after the first method call, you’d get back a QuerySet instance and couldn’t call additional custom manager methods. Though not documented, it was common to work around this issue by creating a custom QuerySet so that custom methods could be chained; but the solution had a number of drawbacks: • The custom QuerySet and its custom methods were lost after the first call to values() or values_list(). • Writing a custom Manager was still necessary to return the custom QuerySet class and all methods that were desired on the Manager had to be proxied to the QuerySet. The whole process went against the DRY principle. The QuerySet.as_manager() class method can now directly create Manager with QuerySet methods: class FoodQuerySet(models.QuerySet): def pizzas(self): return self.filter(kind='pizza') def vegetarian(self): return self.filter(vegetarian=True) class Food(models.Model): kind = models.CharField(max_length=50) vegetarian = models.BooleanField(default=False) objects = FoodQuerySet.as_manager() Food.objects.pizzas().vegetarian()

Using a custom manager when traversing reverse relations It is now possible to specify a custom manager when traversing a reverse relationship: class Blog(models.Model): pass class Entry(models.Model): blog = models.ForeignKey(Blog) objects = models.Manager() entries = EntryManager()

# Default Manager # Custom Manager

b = Blog.objects.get(id=1) b.entry_set(manager='entries').all()

9.1. Final releases

1541

Django Documentation, Release 2.1.dev20171115023625

New system check framework We’ve added a new System check framework for detecting common problems (like invalid models) and providing hints for resolving those problems. The framework is extensible so you can add your own checks for your own apps and libraries. To perform system checks, you use the check management command. This command replaces the older validate management command. New Prefetch object for advanced prefetch_related operations. The new Prefetch object allows customizing prefetch operations. You can specify the QuerySet used to traverse a given relation or customize the storage location of prefetch results. This enables things like filtering prefetched relations, calling select_related() from a prefetched relation, or prefetching the same relation multiple times with different querysets. See prefetch_related() for more details. Admin shortcuts support time zones The “today” and “now” shortcuts next to date and time input widgets in the admin are now operating in the current time zone. Previously, they used the browser time zone, which could result in saving the wrong value when it didn’t match the current time zone on the server. In addition, the widgets now display a help message when the browser and server time zone are different, to clarify how the value inserted in the field will be interpreted. Using database cursors as context managers Prior to Python 2.7, database cursors could be used as a context manager. The specific backend’s cursor defined the behavior of the context manager. The behavior of magic method lookups was changed with Python 2.7 and cursors were no longer usable as context managers. Django 1.7 allows a cursor to be used as a context manager. That is, the following can be used: with connection.cursor() as c: c.execute(...)

instead of: c = connection.cursor() try: c.execute(...) finally: c.close()

Custom lookups It is now possible to write custom lookups and transforms for the ORM. Custom lookups work just like Django’s built-in lookups (e.g. lte, icontains) while transforms are a new concept. The django.db.models.Lookup class provides a way to add lookup operators for model fields. As an example it is possible to add day_lte operator for DateFields.

1542

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

The django.db.models.Transform class allows transformations of database values prior to the final lookup. For example it is possible to write a year transform that extracts year from the field’s value. Transforms allow for chaining. After the year transform has been added to DateField it is possible to filter on the transformed value, for example qs.filter(author__birthdate__year__lte=1981). For more information about both custom lookups and transforms refer to the custom lookups documentation. Improvements to Form error handling Form.add_error() Previously there were two main patterns for handling errors in forms: • Raising a ValidationError from within certain functions (e.g. clean_(), or Form.clean() for non-field errors.)

Field.clean(), Form.

• Fiddling with Form._errors when targeting a specific field in Form.clean() or adding errors from outside of a “clean” method (e.g. directly from a view). Using the former pattern was straightforward since the form can guess from the context (i.e. which method raised the exception) where the errors belong and automatically process them. This remains the canonical way of adding errors when possible. However the latter was fiddly and error-prone, since the burden of handling edge cases fell on the user. The new add_error() method allows adding errors to specific form fields from anywhere without having to worry about the details such as creating instances of django.forms.utils.ErrorList or dealing with Form. cleaned_data. This new API replaces manipulating Form._errors which now becomes a private API. See Cleaning and validating fields that depend on each other for an example using Form.add_error(). Error metadata The ValidationError constructor accepts metadata such as error code or params which are then available for interpolating into the error message (see Raising ValidationError for more details); however, before Django 1.7 those metadata were discarded as soon as the errors were added to Form.errors. Form.errors and django.forms.utils.ErrorList now store the ValidationError instances so these metadata can be retrieved at any time through the new Form.errors.as_data method. The retrieved ValidationError instances can then be identified thanks to their error code which enables things like rewriting the error’s message or writing custom logic in a view when a given error is present. It can also be used to serialize the errors in a custom format such as XML. The new Form.errors.as_json() method is a convenience method which returns error messages along with error codes serialized as JSON. as_json() uses as_data() and gives an idea of how the new system could be extended. Error containers and backward compatibility Heavy changes to the various error containers were necessary in order to support the features above, specifically Form.errors, django.forms.utils.ErrorList, and the internal storages of ValidationError. These containers which used to store error strings now store ValidationError instances and public APIs have been adapted to make this as transparent as possible, but if you’ve been using private APIs, some of the changes are backwards incompatible; see ValidationError constructor and internal storage for more details.

9.1. Final releases

1543

Django Documentation, Release 2.1.dev20171115023625

Minor features django.contrib.admin • You can now implement site_header, site_title, and index_title attributes on a custom AdminSite in order to easily change the admin site’s page title and header text. No more needing to override templates! • Buttons in django.contrib.admin now use the border-radius CSS property for rounded corners rather than GIF background images. • Some admin templates now have app- and model- classes in their tag to allow customizing the CSS per app or per model. • The admin changelist cells now have a field- class in the HTML to enable style customizations. • The admin’s search fields can now be customized per-request thanks to the new django.contrib.admin. ModelAdmin.get_search_fields() method. • The ModelAdmin.get_fields() method may be overridden to customize the value of ModelAdmin. fields. • In addition to the existing admin.site.register syntax, you can use the new register() decorator to register a ModelAdmin. • You may specify ModelAdmin.list_display_links = None to disable links on the change list page grid. • You may now specify ModelAdmin.view_on_site to control whether or not to display the “View on site” link. • You can specify a descending ordering for a ModelAdmin.list_display value by prefixing the admin_order_field value with a hyphen. • The ModelAdmin.get_changeform_initial_data() method may be overridden to define custom behavior for setting initial change form data. django.contrib.auth • Any **kwargs passed to email_user() are passed to the underlying send_mail() call. • The permission_required() decorator can take a list of permissions as well as a single permission. • You can override the new AuthenticationForm.confirm_login_allowed() method to more easily customize the login policy. • django.contrib.auth.views.password_reset() takes an optional html_email_template_name parameter used to send a multipart HTML email for password resets. • The AbstractBaseUser.get_session_auth_hash() method was added and if your AUTH_USER_MODEL inherits from AbstractBaseUser, changing a user’s password now invalidates old sessions if the django.contrib.auth.middleware.SessionAuthenticationMiddleware is enabled. See Session invalidation on password change for more details.

1544

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

django.contrib.formtools • Calls to WizardView.done() now include a form_dict to allow easier access to forms by their step name. django.contrib.gis • The default OpenLayers library version included in widgets has been updated from 2.11 to 2.13. • Prepared geometries now also support the crosses, disjoint, overlaps, touches and within predicates, if GEOS 3.3 or later is installed. django.contrib.messages • The backends for django.contrib.messages that use cookies, SESSION_COOKIE_SECURE and SESSION_COOKIE_HTTPONLY settings. • The messages context processor DEFAULT_MESSAGE_LEVELS.

will

now

follow

the

now adds a dictionary of default levels under the name

• Message objects now have a level_tag attribute that contains the string representation of the message level. django.contrib.redirects • RedirectFallbackMiddleware has two new attributes (response_gone_class and response_redirect_class) that specify the types of HttpResponse instances the middleware returns. django.contrib.sessions • The "django.contrib.sessions.backends.cached_db" session backend SESSION_CACHE_ALIAS. In previous versions, it always used the default cache.

now

respects

django.contrib.sitemaps • The sitemap framework now makes use of lastmod to set a Last-Modified header in the response. This makes it possible for the ConditionalGetMiddleware to handle conditional GET requests for sitemaps which set lastmod. django.contrib.sites • The new django.contrib.sites.middleware.CurrentSiteMiddleware allows setting the current site on each request.

9.1. Final releases

1545

Django Documentation, Release 2.1.dev20171115023625

django.contrib.staticfiles • The static files storage classes may be subclassed to override the permissions that collected static files and directories receive by setting the file_permissions_mode and directory_permissions_mode parameters. See collectstatic for example usage. • The CachedStaticFilesStorage backend gets a sibling class called ManifestStaticFilesStorage that doesn’t use the cache system at all but instead a JSON file called staticfiles.json for storing the mapping between the original file name (e.g. css/styles. css) and the hashed file name (e.g. css/styles.55e7cbb9ba48.css). The staticfiles.json file is created when running the collectstatic management command and should be a less expensive alternative for remote storages such as Amazon S3. See the ManifestStaticFilesStorage docs for more information. • findstatic now accepts verbosity flag level 2, meaning it will show the relative paths of the directories it searched. See findstatic for example output. django.contrib.syndication • The Atom1Feed syndication feed’s updated element now utilizes updateddate instead of pubdate, allowing the published element to be included in the feed (which relies on pubdate). Cache • Access to caches configured in CACHES is now available via django.core.cache.caches. This dict-like object provides a different instance per thread. It supersedes django.core.cache.get_cache() which is now deprecated. • If you instantiate cache backends directly, be aware that they aren’t thread-safe any more, as django.core. cache.caches now yields different instances per thread. • Defining the TIMEOUT argument of the CACHES setting as None will set the cache keys as “non-expiring” by default. Previously, it was only possible to pass timeout=None to the cache backend’s set() method. Cross Site Request Forgery • The CSRF_COOKIE_AGE setting facilitates the use of session-based CSRF cookies. Email • send_mail() now accepts an html_message parameter for sending a multipart text/plain and text/html email. • The SMTP EmailBackend now accepts a timeout parameter. File Storage • File locking on Windows previously depended on the PyWin32 package; if it wasn’t installed, file locking failed silently. That dependency has been removed, and file locking is now implemented natively on both Windows and Unix.

1546

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

File Uploads • The new UploadedFile.content_type_extra attribute contains extra parameters passed to the content-type header on a file upload. • The new FILE_UPLOAD_DIRECTORY_PERMISSIONS setting controls the file system permissions of directories created during file upload, like FILE_UPLOAD_PERMISSIONS does for the files themselves. • The FileField.upload_to attribute is now optional. If it is omitted or given None or an empty string, a subdirectory won’t be used for storing the uploaded files. • Uploaded files are now explicitly closed before the response is delivered to the client. Partially uploaded files are also closed as long as they are named file in the upload handler. • Storage.get_available_name() now appends an underscore plus a random 7 character alphanumeric string (e.g. "_x3a1gho"), rather than iterating through an underscore followed by a number (e.g. "_1", "_2", etc.) to prevent a denial-of-service attack. This change was also made in the 1.6.6, 1.5.9, and 1.4.14 security releases. Forms • The and tags rendered by RadioSelect and CheckboxSelectMultiple when looping over the radio buttons or checkboxes now include for and id attributes, respectively. Each radio button or checkbox includes an id_for_label attribute to output the element’s ID. • The tags rendered by Textarea now include a maxlength attribute if the TextField model field has a max_length. • Field.choices now allows you to customize the “empty choice” label by including a tuple with an empty string or None for the key and the custom label as the value. The default blank option "----------" will be omitted in this case. • MultiValueField allows optional subfields by setting the require_all_fields argument to False. The required attribute for each individual field will be respected, and a new incomplete validation error will be raised when any required fields are empty. • The clean() method on a form no longer needs to return self.cleaned_data. If it does return a changed dictionary then that will still be used. • After a temporary regression in Django 1.6, it’s now possible again to make TypedChoiceField coerce method return an arbitrary value. • SelectDateWidget.months can be used to customize the wording of the months displayed in the select widget. • The min_num and validate_min parameters were added to formset_factory() to allow validating a minimum number of submitted forms. • The metaclasses used by Form and ModelForm have been reworked to support more inheritance scenarios. The previous limitation that prevented inheriting from both Form and ModelForm simultaneously have been removed as long as ModelForm appears first in the MRO. • It’s now possible to remove a field from a Form when subclassing by setting the name to None. • It’s now possible to customize the error messages for ModelForm’s unique, unique_for_date, and unique_together constraints. In order to support unique_together or any other NON_FIELD_ERROR, ModelForm now looks for the NON_FIELD_ERROR key in the error_messages dictionary of the ModelForm’s inner Meta class. See considerations regarding model’s error_messages for more details.

9.1. Final releases

1547

Django Documentation, Release 2.1.dev20171115023625

Internationalization • The django.middleware.locale.LocaleMiddleware.response_redirect_class attribute allows you to customize the redirects issued by the middleware. • The LocaleMiddleware now stores the user’s selected language with the session key _language. This should only be accessed using the LANGUAGE_SESSION_KEY constant. Previously it was stored with the key django_language and the LANGUAGE_SESSION_KEY constant did not exist, but keys reserved for Django should start with an underscore. For backwards compatibility django_language is still read from in 1.7. Sessions will be migrated to the new key as they are written. • The blocktrans tag now supports a trimmed option. This option will remove newline characters from the beginning and the end of the content of the {% blocktrans %} tag, replace any whitespace at the beginning and end of a line and merge all lines into one using a space character to separate them. This is quite useful for indenting the content of a {% blocktrans %} tag without having the indentation characters end up in the corresponding entry in the PO file, which makes the translation process easier. • When you run makemessages from the root directory of your project, any extracted strings will now be automatically distributed to the proper app or project message file. See Localization: how to create language files for details. • The makemessages command now always adds the --previous command line flag to the msgmerge command, keeping previously translated strings in po files for fuzzy strings. • The following settings to adjust the language cookie options were introduced: LANGUAGE_COOKIE_AGE, LANGUAGE_COOKIE_DOMAIN and LANGUAGE_COOKIE_PATH. • Added Format localization for Esperanto. Management Commands • The new --no-color option for django-admin disables the colorization of management command output. • The new dumpdata --natural-foreign and dumpdata --natural-primary options, and the new use_natural_foreign_keys and use_natural_primary_keys arguments for serializers.serialize(), allow the use of natural primary keys when serializing. • It is no longer necessary to provide the cache table name or the --database option for the createcachetable command. Django takes this information from your settings file. If you have configured multiple caches or multiple databases, all cache tables are created. • The runserver command received several improvements: – On Linux systems, if pyinotify is installed, the development server will reload immediately when a file is changed. Previously, it polled the filesystem for changes every second. That caused a small delay before reloads and reduced battery life on laptops. – In addition, the development server automatically reloads when a translation file is updated, i.e. after running compilemessages. – All HTTP requests are logged to the console, including requests for static files or favicon.ico that used to be filtered out. • Management commands can now produce syntax colored output under Windows if the ANSICON third-party tool is installed and active. • collectstatic command with symlink option is now supported on Windows NT 6 (Windows Vista and newer).

1548

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

• Initial SQL data now works better if the sqlparse Python library is installed. Note that it’s deprecated in favor of the RunSQL operation of migrations, which benefits from the improved behavior. Models • The QuerySet.update_or_create() method was added. • The new default_permissions model Meta option allows you to customize (or disable) creation of the default add, change, and delete permissions. • Explicit OneToOneField for Multi-table inheritance are now discovered in abstract classes. • It is now possible to avoid creating a backward relation for OneToOneField by setting its related_name to '+' or ending it with '+'. • F expressions support the power operator (**). • The remove() and clear() methods of the related managers created by ForeignKey and GenericForeignKey now accept the bulk keyword argument to control whether or not to perform operations in bulk (i.e. using QuerySet.update()). Defaults to True. • It is now possible to use None as a query value for the iexact lookup. • It is now possible to pass a callable as value for the attribute limit_choices_to when defining a ForeignKey or ManyToManyField. • Calling only() and defer() on the result of QuerySet.values() now raises an error (before that, it would either result in a database error or incorrect data). • You can use a single list for index_together (rather than a list of lists) when specifying a single set of fields. • Custom intermediate models having more than one foreign key to any of the models participating in a manyto-many relationship are now permitted, provided you explicitly specify which foreign keys should be used by setting the new ManyToManyField.through_fields argument. • Assigning a model instance to a non-relation field will now throw an error. Previously this used to work if the field accepted integers as input as it took the primary key. • Integer fields are now validated against database backend specific min and max values based on their internal_type. Previously model field validation didn’t prevent values out of their associated column data type range from being saved resulting in an integrity error. • It is now possible to explicitly order_by() a relation _id field by using its attribute name. Signals • The enter argument was added to the setting_changed signal. • The model signals can be now be connected to using a str of the 'app_label.ModelName' form – just like related fields – to lazily reference their senders. Templates • The Context.push() method now returns a context manager which automatically calls pop() upon exiting the with statement. Additionally, push() now accepts parameters that are passed to the dict constructor used to build the new context level. 9.1. Final releases

1549

Django Documentation, Release 2.1.dev20171115023625

• The new Context.flatten() method returns a Context‘s stack as one flat dictionary. • Context objects can now be compared for equality (internally, this uses Context.flatten() so the internal structure of each Context‘s stack doesn’t matter as long as their flattened version is identical). • The widthratio template tag now accepts an "as" parameter to capture the result in a variable. • The include template tag will now also accept anything with a render() method (such as a Template) as an argument. String arguments will be looked up using get_template() as always. • It is now possible to include templates recursively. • Template objects now have an origin attribute set when TEMPLATE_DEBUG is True. This allows template origins to be inspected and logged outside of the django.template infrastructure. • TypeError exceptions are no longer silenced when raised during the rendering of a template. • The following functions now accept a dirs parameter which is a list or tuple to override TEMPLATE_DIRS: – django.template.loader.get_template() – django.template.loader.select_template() – django.shortcuts.render() – django.shortcuts.render_to_response() • The time filter now accepts timezone-related format specifiers 'e', 'O' , 'T' and 'Z' and is able to digest time-zone-aware datetime instances performing the expected rendering. • The cache tag will now try to use the cache called “template_fragments” if it exists and fall back to using the default cache otherwise. It also now accepts an optional using keyword argument to control which cache it uses. • The new truncatechars_html filter truncates a string to be no longer than the specified number of characters, taking HTML into account. Requests and Responses • The new HttpRequest.scheme attribute specifies the scheme of the request (http or https normally). • The shortcut redirect() now supports relative URLs. • The new JsonResponse subclass of HttpResponse helps easily create JSON-encoded responses. Tests • DiscoverRunner has two new attributes, test_suite and test_runner, which facilitate overriding the way tests are collected and run. • The fetch_redirect_response argument was added to assertRedirects(). Since the test client can’t fetch externals URLs, this allows you to use assertRedirects with redirects that aren’t part of your Django app. • Correct handling of scheme when making comparisons in assertRedirects(). • The secure argument was added to all the request methods of Client. If True, the request will be made through HTTPS. • assertNumQueries() now prints out the list of executed queries if the assertion fails.

1550

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

• The WSGIRequest instance generated by the test handler is now attached to the django.test. Response.wsgi_request attribute. • The database settings for testing have been collected into a dictionary named TEST. Utilities • Improved strip_tags() accuracy (but it still cannot guarantee an HTML-safe result, as stated in the documentation). Validators • RegexValidator now accepts the optional flags and Boolean inverse_match arguments. The inverse_match attribute determines if the ValidationError should be raised when the regular expression pattern matches (True) or does not match (False, by default) the provided value. The flags attribute sets the flags used when compiling a regular expression string. • URLValidator now accepts an optional schemes argument which allows customization of the accepted URI schemes (instead of the defaults http(s) and ftp(s)). • validate_email() now accepts addresses with IPv6 literals, like [emailprotected][2001:db8::1], as specified in RFC 5321. Backwards incompatible changes in 1.7

Warning: In addition to the changes outlined in this section, be sure to review the deprecation plan for any features that have been removed. If you haven’t updated your code within the deprecation timeline for a given feature, its removal may appear as a backwards incompatible change. allow_syncdb / allow_migrate While Django will still look at allow_syncdb methods even though they should be renamed to allow_migrate, there is a subtle difference in which models get passed to these methods. For apps with migrations, allow_migrate will now get passed historical models, which are special versioned models without custom attributes, methods or managers. Make sure your allow_migrate methods are only referring to fields or other items in model._meta. initial_data Apps with migrations will not load initial_data fixtures when they have finished migrating. Apps without migrations will continue to load these fixtures during the phase of migrate which emulates the old syncdb behavior, but any new apps will not have this support. Instead, you are encouraged to load initial data in migrations if you need it (using the RunPython operation and your model classes); this has the added advantage that your initial data will not need updating every time you change the schema. Additionally, like the rest of Django’s old syncdb code, initial_data has been started down the deprecation path and will be removed in Django 1.9.

9.1. Final releases

1551

Django Documentation, Release 2.1.dev20171115023625

deconstruct() and serializability Django now requires all Field classes and all of their constructor arguments to be serializable. If you modify the constructor signature in your custom Field in any way, you’ll need to implement a deconstruct() method; we’ve expanded the custom field documentation with instructions on implementing this method. The requirement for all field arguments to be serializable means that any custom class instances being passed into Field constructors - things like custom Storage subclasses, for instance - need to have a deconstruct method defined on them as well, though Django provides a handy class decorator that will work for most applications. App-loading changes Start-up sequence Django 1.7 loads application configurations and models as soon as it starts. While this behavior is more straightforward and is believed to be more robust, regressions cannot be ruled out. See Troubleshooting for solutions to some problems you may encounter. Standalone scripts If you’re using Django in a plain Python script — rather than a management command — and you rely on the DJANGO_SETTINGS_MODULE environment variable, you must now explicitly initialize Django at the beginning of your script with: >>> import django >>> django.setup()

Otherwise, you will hit an AppRegistryNotReady exception. WSGI scripts Until Django 1.3, the recommended way to create a WSGI application was: import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler()

In Django 1.4, support for WSGI was improved and the API changed to: from django.core.wsgi import get_wsgi_application application = get_wsgi_application()

If you’re still using the former style in your WSGI script, you need to upgrade to the latter, or you will hit an AppRegistryNotReady exception. App registry consistency It is no longer possible to have multiple installed applications with the same label. In previous versions of Django, this didn’t always work correctly, but didn’t crash outright either. If you have two apps with the same label, you should create an AppConfig for one of them and override its label there. You should then adjust your code wherever it references this application or its models with the old label.

1552

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

It isn’t possible to import the same model twice through different paths any more. As of Django 1.6, this may happen only if you’re manually putting a directory and a subdirectory on PYTHONPATH. Refer to the section on the new project layout in the 1.4 release notes for migration instructions. You should make sure that: • All models are defined in applications that are listed in INSTALLED_APPS or have an explicit app_label. • Models aren’t imported as a side-effect of loading their application. Specifically, you shouldn’t import models in the root module of an application nor in the module that define its configuration class. Django will enforce these requirements as of version 1.9, after a deprecation period. Subclassing AppCommand Subclasses of AppCommand must now implement a handle_app_config() method instead of handle_app(). This method receives an AppConfig instance instead of a models module. Introspecting applications Since INSTALLED_APPS now supports application configuration classes in addition to application modules, you should review code that accesses this setting directly and use the app registry (django.apps.apps) instead. The app registry has preserved some features of the old app cache. Even though the app cache was a private API, obsolete methods and arguments will be removed through a standard deprecation path, with the exception of the following changes that take effect immediately: • get_model raises LookupError instead of returning None when no model is found. • The only_installed argument of get_model and get_models no longer exists, nor does the seed_cache argument of get_model. Management commands and order of INSTALLED_APPS When several applications provide management commands with the same name, Django loads the command from the application that comes first in INSTALLED_APPS. Previous versions loaded the command from the application that came last. This brings discovery of management commands in line with other parts of Django that rely on the order of INSTALLED_APPS, such as static files, templates, and translations. ValidationError constructor and internal storage The behavior of the ValidationError constructor has changed when it receives a container of errors as an argument (e.g. a list or an ErrorList): • It converts any strings it finds to instances of ValidationError before adding them to its internal storage. • It doesn’t store the given container but rather copies its content to its own internal storage; previously the container itself was added to the ValidationError instance and used as internal storage. This means that if you access the ValidationError internal storages, such as error_list; error_dict; or the return value of update_error_dict() you may find instances of ValidationError where you would have previously found strings.

9.1. Final releases

1553

Django Documentation, Release 2.1.dev20171115023625

Also if you directly assigned the return value of update_error_dict() to Form._errors you may inadvertently add list instances where ErrorList instances are expected. This is a problem because unlike a simple list, an ErrorList knows how to handle instances of ValidationError. Most use-cases that warranted using these private APIs are now covered by the newly introduced Form. add_error() method: # Old pattern: try: # ... except ValidationError as e: self._errors = e.update_error_dict(self._errors) # New pattern: try: # ... except ValidationError as e: self.add_error(None, e)

If you need both Django = 1.6, models.Manager provides a get_query_set fallback # that emits a warning when used.

If you are writing a library that needs to call the get_queryset method and must support old Django versions, you should write: get_queryset = (some_manager.get_query_set if hasattr(some_manager, 'get_query_set') else some_manager.get_queryset) return get_queryset() # etc

In the general case of a custom manager that both implements its own get_queryset method and calls that method, and needs to work with older Django versions, and libraries that have not been updated yet, it is useful to define a get_queryset_compat method as below and use it internally to your manager: class YourCustomManager(models.Manager): def get_queryset(self): return YourCustomQuerySet() # for example if django.VERSION < (1, 6): get_query_set = get_queryset def active(self): # for example return self.get_queryset_compat().filter(active=True) def get_queryset_compat(self): get_queryset = (self.get_query_set if hasattr(self, 'get_query_set') else self.get_queryset) return get_queryset()

This helps to minimize the changes that are needed, but also works correctly in the case of subclasses (such as RelatedManagers from Django 1.5) which might override either get_query_set or get_queryset. shortcut view and URLconf The shortcut view was moved from django.views.defaults to django.contrib.contenttypes. views shortly after the 1.0 release, but the old location was never deprecated. This oversight was corrected in Django 1.6 and you should now use the new location. The URLconf django.conf.urls.shortcut was also deprecated. If you’re including it in an URLconf, simply replace: (r'^prefix/', include('django.conf.urls.shortcut')),

with: (r'^prefix/(?P\d+)/(?P.*)/$', 'django.contrib. ˓→contenttypes.views.shortcut'),

1588

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

ModelForm without fields or exclude Previously, if you wanted a ModelForm to use all fields on the model, you could simply omit the Meta.fields attribute, and all fields would be used. This can lead to security problems where fields are added to the model and, unintentionally, automatically become editable by end users. In some cases, particular with boolean fields, it is possible for this problem to be completely invisible. This is a form of Mass assignment vulnerability. For this reason, this behavior is deprecated, and using the Meta.exclude option is strongly discouraged. Instead, all fields that are intended for inclusion in the form should be listed explicitly in the fields attribute. If this security concern really does not apply in your case, there is a shortcut to explicitly indicate that all fields should be used - use the special value "__all__" for the fields attribute: class MyModelForm(ModelForm): class Meta: fields = "__all__" model = MyModel

If you have custom ModelForms that only need to be used in the admin, there is another option. The admin has its own methods for defining fields (fieldsets etc.), and so adding a list of fields to the ModelForm is redundant. Instead, simply omit the Meta inner class of the ModelForm, or omit the Meta.model attribute. Since the ModelAdmin subclass knows which model it is for, it can add the necessary attributes to derive a functioning ModelForm. This behavior also works for earlier Django versions. UpdateView and CreateView without explicit fields The generic views CreateView and UpdateView, and anything else derived from ModelFormMixin, are vulnerable to the security problem described in the section above, because they can automatically create a ModelForm that uses all fields for a model. For this reason, if you use these views for editing models, you must also supply the fields attribute (new in Django 1.6), which is a list of model fields and works in the same way as the ModelForm Meta.fields attribute. Alternatively, you can set the form_class attribute to a ModelForm that explicitly defines the fields to be used. Defining an UpdateView or CreateView subclass to be used with a model but without an explicit list of fields is deprecated. Munging of help text of model form fields for ManyToManyField fields All special handling of the help_text attribute of ManyToManyField model fields performed by standard model or model form fields as described in Help text of model form fields for ManyToManyField fields above is deprecated and will be removed in Django 1.8. Help text of these fields will need to be handled either by applications, custom form fields or widgets, just like happens with the rest of the model field types.

9.1.9 1.5 release Django 1.5.12 release notes January 2, 2015 Django 1.5.12 fixes a regression in the 1.5.9 security release.

9.1. Final releases

1589

Django Documentation, Release 2.1.dev20171115023625

Bugfixes • Fixed a regression with dynamically generated inlines and allowed field references in the admin (#23754). Django 1.5.11 release notes October 22, 2014 Django 1.5.11 fixes a couple regressions in the 1.5.9 security release. Bugfixes • Allowed related many-to-many fields to be referenced in the admin (#23604). • Allowed inline and hidden references to admin fields (#23431). Django 1.5.10 release notes September 2, 2014 Django 1.5.10 fixes a regression in the 1.5.9 security release. Bugfixes • Allowed inherited and m2m fields to be referenced in the admin (#22486) Django 1.5.9 release notes August 20, 2014 Django 1.5.9 fixes several security issues in 1.5.8. reverse() could generate URLs pointing to other hosts In certain situations, URL reversing could generate scheme-relative URLs (URLs starting with two slashes), which could unexpectedly redirect a user to a different host. An attacker could exploit this, for example, by redirecting users to a phishing site designed to ask for user’s passwords. To remedy this, URL reversing now ensures that no URL starts with two slashes (//), replacing the second slash with its URL encoded counterpart (%2F). This approach ensures that semantics stay the same, while making the URL relative to the domain and not to the scheme. File upload denial-of-service Before this release, Django’s file upload handing in its default configuration may degrade to producing a huge number of os.stat() system calls when a duplicate filename is uploaded. Since stat() may invoke IO, this may produce a huge data-dependent slowdown that slowly worsens over time. The net result is that given enough time, a user with the ability to upload files can cause poor performance in the upload handler, eventually causing it to become very slow simply by uploading 0-byte files. At this point, even a slow network connection and few HTTP requests would be all that is necessary to make a site unavailable.

1590

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

We’ve remedied the issue by changing the algorithm for generating file names if a file with the uploaded name already exists. Storage.get_available_name() now appends an underscore plus a random 7 character alphanumeric string (e.g. "_x3a1gho"), rather than iterating through an underscore followed by a number (e.g. "_1", "_2", etc.). RemoteUserMiddleware session hijacking When using the RemoteUserMiddleware and the RemoteUserBackend, a change to the REMOTE_USER header between requests without an intervening logout could result in the prior user’s session being co-opted by the subsequent user. The middleware now logs the user out on a failed login attempt. Data leakage via query string manipulation in contrib.admin In older versions of Django it was possible to reveal any field’s data by modifying the “popup” and “to_field” parameters of the query string on an admin change form page. For example, requesting a URL like /admin/auth/user/ ?pop=1&t=password and viewing the page’s HTML allowed viewing the password hash of each user. While the admin requires users to have permissions to view the change form pages in the first place, this could leak data if you rely on users having access to view only certain fields on a model. To address the issue, an exception will now be raised if a to_field value that isn’t a related field to a model that has been registered with the admin is specified. Django 1.5.8 release notes May 14, 2014 Django 1.5.8 fixes two security issues in 1.5.8. Caches may incorrectly be allowed to store and serve private data In certain situations, Django may allow caches to store private data related to a particular session and then serve that data to requests with a different session, or no session at all. This can lead to information disclosure and can be a vector for cache poisoning. When using Django sessions, Django will set a Vary: Cookie header to ensure caches do not serve cached data to requests from other sessions. However, older versions of Internet Explorer (most likely only Internet Explorer 6, and Internet Explorer 7 if run on Windows XP or Windows Server 2003) are unable to handle the Vary header in combination with many content types. Therefore, Django would remove the header if the request was made by Internet Explorer. To remedy this, the special behavior for these older Internet Explorer versions has been removed, and the Vary header is no longer stripped from the response. In addition, modifications to the Cache-Control header for all Internet Explorer requests with a Content-Disposition header have also been removed as they were found to have similar issues. Malformed redirect URLs from user input not correctly validated The validation for redirects did not correctly validate some malformed URLs, which are accepted by some browsers. This allows a user to be redirected to an unsafe URL unexpectedly. Django relies on user input in some cases (e.g. django.contrib.auth.views.login(), django. contrib.comments, and i18n) to redirect the user to an “on success” URL. The security checks for these redirects 9.1. Final releases

1591

Django Documentation, Release 2.1.dev20171115023625

(namely django.utils.http.is_safe_url()) did not correctly validate some malformed URLs, such as http:\\\djangoproject.com, which are accepted by some browsers with more liberal URL parsing. To remedy this, the validation in is_safe_url() has been tightened to be able to handle and correctly validate these malformed URLs. Django 1.5.7 release notes April 28, 2014 Django 1.5.7 fixes a regression in the 1.5.6 security release. Bugfixes • Restored the ability to reverse() views created using functools.partial() (#22486). Django 1.5.6 release notes April 21, 2014 Django 1.5.6 fixes several bugs in 1.5.5, including three security issues. Unexpected code execution using reverse() Django’s URL handling is based on a mapping of regex patterns (representing the URLs) to callable views, and Django’s own processing consists of matching a requested URL against those patterns to determine the appropriate view to invoke. Django also provides a convenience function – reverse() – which performs this process in the opposite direction. The reverse() function takes information about a view and returns a URL which would invoke that view. Use of reverse() is encouraged for application developers, as the output of reverse() is always based on the current URL patterns, meaning developers do not need to change other code when making changes to URLs. One argument signature for reverse() is to pass a dotted Python path to the desired view. In this situation, Django will import the module indicated by that dotted path as part of generating the resulting URL. If such a module has import-time side effects, those side effects will occur. Thus it is possible for an attacker to cause unexpected code execution, given the following conditions: 1. One or more views are present which construct a URL based on user input (commonly, a “next” parameter in a querystring indicating where to redirect upon successful completion of an action). 2. One or more modules are known to an attacker to exist on the server’s Python import path, which perform code execution with side effects on importing. To remedy this, reverse() will now only accept and import dotted paths based on the view-containing modules listed in the project’s URL pattern configuration, so as to ensure that only modules the developer intended to be imported in this fashion can or will be imported. Caching of anonymous pages could reveal CSRF token Django includes both a caching framework and a system for preventing cross-site request forgery (CSRF) attacks. The CSRF-protection system is based on a random nonce sent to the client in a cookie which must be sent by the client on future requests and, in forms, a hidden value which must be submitted back with the form.

1592

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

The caching framework includes an option to cache responses to anonymous (i.e., unauthenticated) clients. When the first anonymous request to a given page is by a client which did not have a CSRF cookie, the cache framework will also cache the CSRF cookie and serve the same nonce to other anonymous clients who do not have a CSRF cookie. This can allow an attacker to obtain a valid CSRF cookie value and perform attacks which bypass the check for the cookie. To remedy this, the caching framework will no longer cache such responses. The heuristic for this will be: 1. If the incoming request did not submit any cookies, and 2. If the response did send one or more cookies, and 3. If the Vary:

Cookie header is set on the response, then the response will not be cached.

MySQL typecasting The MySQL database is known to “typecast” on certain queries; for example, when querying a table which contains string values, but using a query which filters based on an integer value, MySQL will first silently coerce the strings to integers and return a result based on that. If a query is performed without first converting values to the appropriate type, this can produce unexpected results, similar to what would occur if the query itself had been manipulated. Django’s model field classes are aware of their own types and most such classes perform explicit conversion of query arguments to the correct database-level type before querying. However, three model field classes did not correctly convert their arguments: • FilePathField • GenericIPAddressField • IPAddressField These three fields have been updated to convert their arguments to the correct types before querying. Additionally, developers of custom model fields are now warned via documentation to ensure their custom field classes will perform appropriate type conversions, and users of the raw() and extra() query methods – which allow the developer to supply raw SQL or SQL fragments – will be advised to ensure they perform appropriate manual type conversions prior to executing queries. Bugfixes • Fixed ModelBackend raising UnboundLocalError if get_user_model() raised an error (#21439). Additionally, Django’s vendored version of six, django.utils.six, has been upgraded to the latest release (1.6.1). Django 1.5.5 release notes October 23, 2013 Django 1.5.5 fixes a couple security-related bugs and several other bugs in the 1.5 series.

9.1. Final releases

1593

Django Documentation, Release 2.1.dev20171115023625

Readdressed denial-of-service via password hashers Django 1.5.4 imposes a 4096-byte limit on passwords in order to mitigate a denial-of-service attack through submission of bogus but extremely large passwords. In Django 1.5.5, we’ve reverted this change and instead improved the speed of our PBKDF2 algorithm by not rehashing the key on every iteration. Properly rotate CSRF token on login This behavior introduced as a security hardening measure in Django 1.5.2 did not work properly and is now fixed. Bugfixes • Fixed a data corruption bug with datetime_safe.datetime.combine (#21256). • Fixed a Python 3 incompatibility in django.utils.text.unescape_entities() (#21185). • Fixed a couple data corruption issues with QuerySet edge cases under Oracle and MySQL (#21203, #21126). • Fixed crashes when using combinations of annotate(), select_related(), and only() (#16436). Backwards incompatible changes • The undocumented django.core.servers.basehttp.WSGIServerException has been removed. Use socket.error provided by the standard library instead. Django 1.5.4 release notes September 14, 2013 This is Django 1.5.4, the fourth release in the Django 1.5 series. It addresses two security issues and one bug. Denial-of-service via password hashers In previous versions of Django, no limit was imposed on the plaintext length of a password. This allowed a denial-ofservice attack through submission of bogus but extremely large passwords, tying up server resources performing the (expensive, and increasingly expensive with the length of the password) calculation of the corresponding hash. As of 1.5.4, Django’s authentication framework imposes a 4096-byte limit on passwords, and will fail authentication with any submitted password of greater length. Corrected usage of sensitive_post_parameters() in django.contrib.auth’s admin The decoration of the add_view and user_change_password user admin views with sensitive_post_parameters() did not include method_decorator() (required since the views are methods) resulting in the decorator not being properly applied. This usage has been fixed and sensitive_post_parameters() will now throw an exception if it’s improperly used.

1594

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Bugfixes • Fixed a bug that prevented a QuerySet that uses prefetch_related() from being pickled and unpickled more than once (the second pickling attempt raised an exception) (#21102). Django 1.5.3 release notes September 10, 2013 This is Django 1.5.3, the third release in the Django 1.5 series. It addresses one security issue and also contains an opt-in feature to enhance the security of django.contrib.sessions. Directory traversal vulnerability in ssi template tag In previous versions of Django it was possible to bypass the ALLOWED_INCLUDE_ROOTS setting used for security with the ssi template tag by specifying a relative path that starts with one of the allowed roots. For example, if ALLOWED_INCLUDE_ROOTS = ("/var/www",) the following would be possible: {% ssi "/var/www/../../etc/passwd" %}

In practice this is not a very common problem, as it would require the template author to put the ssi file in a usercontrolled variable, but it’s possible in principle. Mitigating a remote-code execution vulnerability in django.contrib.sessions django.contrib.sessions currently uses pickle to serialize session data before storing it in the backend. If you’re using the signed cookie session backend and SECRET_KEY is known by an attacker (there isn’t an inherent vulnerability in Django that would cause it to leak), the attacker could insert a string into his session which, when unpickled, executes arbitrary code on the server. The technique for doing so is simple and easily available on the internet. Although the cookie session storage signs the cookie-stored data to prevent tampering, a SECRET_KEY leak immediately escalates to a remote code execution vulnerability. This attack can be mitigated by serializing session data using JSON rather than pickle. To facilitate this, Django 1.5.3 introduces a new setting, SESSION_SERIALIZER, to customize the session serialization format. For backwards compatibility, this setting defaults to using pickle. While JSON serialization does not support all Python objects like pickle does, we highly recommend switching to JSON-serialized values. Also, as JSON requires string keys, you will likely run into problems if you are using non-string keys in request.session. See the Session serialization documentation for more details. Django 1.5.2 release notes August 13, 2013 This is Django 1.5.2, a bugfix and security release for Django 1.5. Mitigated possible XSS attack via user-supplied redirect URLs Django relies on user input in some cases (e.g. django.contrib.auth.views.login(), django. contrib.comments, and i18n) to redirect the user to an “on success” URL. The security checks for these redirects (namely django.utils.http.is_safe_url()) didn’t check if the scheme is http(s) and as such allowed javascript:... URLs to be entered. If a developer relied on is_safe_url() to provide safe redirect targets

9.1. Final releases

1595

Django Documentation, Release 2.1.dev20171115023625

and put such a URL into a link, they could suffer from a XSS attack. This bug doesn’t affect Django currently, since we only put this URL into the Location response header and browsers seem to ignore JavaScript there. XSS vulnerability in django.contrib.admin If a URLField is used in Django 1.5, it displays the current value of the field and a link to the target on the admin change page. The display routine of this widget was flawed and allowed for XSS. Bugfixes • Fixed a crash with prefetch_related() (#19607) as well as some pickle regressions with prefetch_related (#20157 and #20257). • Fixed a regression in django.contrib.gis in the Google Map output on Python 3 (#20773). • Made DjangoTestSuiteRunner.setup_databases properly handle aliases for the default database (#19940) and prevented teardown_databases from attempting to tear down aliases (#20681). • Fixed the django.core.cache.backends.memcached.MemcachedCache get_many() method on Python 3 (#20722).

backend’s

• Fixed django.contrib.humanize translation syntax errors. Affected languages: Mexican Spanish, Mongolian, Romanian, Turkish (#20695). • Added support for wheel packages (#19252). • The CSRF token now rotates when a user logs in. • Some Python 3 compatibility fixes including #20212 and #20025. • Fixed some rare cases where get() exceptions recursed infinitely (#20278). • makemessages no longer crashes with UnicodeDecodeError (#20354). • Fixed geojson detection with SpatiaLite. • assertContains() once again works with binary content (#20237). • Fixed ManyToManyField if it has a unicode name parameter (#20207). • Ensured that the WSGI request’s path is correctly based on the SCRIPT_NAME environment variable or the FORCE_SCRIPT_NAME setting, regardless of whether or not either has a trailing slash (#20169). • Fixed an obscure bug with the override_settings() decorator. If you hit an AttributeError: 'Settings' object has no attribute '_original_allowed_hosts' exception, it’s probably fixed (#20636). Django 1.5.1 release notes March 28, 2013 This is Django 1.5.1, a bugfix release for Django 1.5. It’s completely backwards compatible with Django 1.5, but includes a handful of fixes. The biggest fix is for a memory leak introduced in Django 1.5. Under certain circumstances, repeated iteration over querysets could leak memory - sometimes quite a bit of it. If you’d like more information, the details are in our ticket tracker (and in a related issue in Python itself). If you’ve noticed memory problems under Django 1.5, upgrading to 1.5.1 should fix those issues.

1596

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Django 1.5.1 also includes a couple smaller fixes: • Module-level warnings emitted during tests are no longer silently hidden (#18985). • Prevented filtering on password hashes in the user admin (#20078). Django 1.5 release notes February 26, 2013 Welcome to Django 1.5! These release notes cover the new features, as well as some backwards incompatible changes you’ll want to be aware of when upgrading from Django 1.4 or older versions. We’ve also dropped some features, which are detailed in our deprecation plan, and we’ve begun the deprecation process for some features. Overview The biggest new feature in Django 1.5 is the configurable User model. Before Django 1.5, applications that wanted to use Django’s auth framework (django.contrib.auth) were forced to use Django’s definition of a “user”. In Django 1.5, you can now swap out the User model for one that you write yourself. This could be a simple extension to the existing User model – for example, you could add a Twitter or Facebook ID field – or you could completely replace the User with one totally customized for your site. Django 1.5 is also the first release with Python 3 support! We’re labeling this support “experimental” because we don’t yet consider it production-ready, but everything’s in place for you to start porting your apps to Python 3. Our next release, Django 1.6, will support Python 3 without reservations. Other notable new features in Django 1.5 include: • Support for saving a subset of model’s fields - Model.save() now accepts an update_fields argument, letting you specify which fields are written back to the database when you call save(). This can help in high-concurrency operations, and can improve performance. • Better support for streaming responses via the new StreamingHttpResponse response class. • GeoDjango now supports PostGIS 2.0. • ... and more; see below. Wherever possible we try to introduce new features in a backwards-compatible manner per our API stability policy. However, as with previous releases, Django 1.5 ships with some minor backwards incompatible changes; people upgrading from previous versions of Django should read that list carefully. One deprecated feature worth noting is the shift to “new-style” url tag. Prior to Django 1.3, syntax like {% url myview %} was interpreted incorrectly (Django considered "myview" to be a literal name of a view, not a template variable named myview). Django 1.3 and above introduced the {% load url from future %} syntax to bring in the corrected behavior where myview was seen as a variable. The upshot of this is that if you are not using {% load url from future %} in your templates, you’ll need to change tags like {% url myview %} to {% url "myview" %}. If you were using {% load url from future %} you can simply remove that line under Django 1.5 Python compatibility Django 1.5 requires Python 2.6.5 or above, though we highly recommend Python 2.7.3 or above. Support for Python 2.5 and below has been dropped.

9.1. Final releases

1597

Django Documentation, Release 2.1.dev20171115023625

This change should affect only a small number of Django users, as most operating-system vendors today are shipping Python 2.6 or newer as their default version. If you’re still using Python 2.5, however, you’ll need to stick to Django 1.4 until you can upgrade your Python version. Per our support policy, Django 1.4 will continue to receive security support until the release of Django 1.6. Django 1.5 does not run on a Jython final release, because Jython’s latest release doesn’t currently support Python 2.6. However, Jython currently does offer an alpha release featuring 2.7 support, and Django 1.5 supports that alpha release. Python 3 support Django 1.5 introduces support for Python 3 - specifically, Python 3.2 and above. This comes in the form of a single codebase; you don’t need to install a different version of Django on Python 3. This means that you can write applications targeted for just Python 2, just Python 3, or single applications that support both platforms. However, we’re labeling this support “experimental” for now: although it’s received extensive testing via our automated test suite, it’s received very little real-world testing. We’ve done our best to eliminate bugs, but we can’t be sure we covered all possible uses of Django. Some features of Django aren’t available because they depend on third-party software that hasn’t been ported to Python 3 yet, including: • the MySQL database backend (depends on MySQLdb) • ImageField (depends on PIL) • LiveServerTestCase (depends on Selenium WebDriver) Further, Django’s more than a web framework; it’s an ecosystem of pluggable components. At this point, very few third-party applications have been ported to Python 3, so it’s unlikely that a real-world application will have all its dependencies satisfied under Python 3. Thus, we’re recommending that Django 1.5 not be used in production under Python 3. Instead, use this opportunity to begin porting applications to Python 3. If you’re an author of a pluggable component, we encourage you to start porting now. We plan to offer first-class, production-ready support for Python 3 in our next release, Django 1.6. What’s new in Django 1.5 Configurable User model In Django 1.5, you can now use your own model as the store for user-related data. If your project needs a username with more than 30 characters, or if you want to store user’s names in a format other than first name/last name, or you want to put custom profile information onto your User object, you can now do so. If you have a third-party reusable application that references the User model, you may need to make some changes to the way you reference User instances. You should also document any specific features of the User model that your application relies upon. See the documentation on custom user models for more details. Support for saving a subset of model’s fields The method Model.save() has a new keyword argument update_fields. By using this argument it is possible to save only a select list of model’s fields. This can be useful for performance reasons or when trying to avoid

1598

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

overwriting concurrent changes. Deferred instances (those loaded by .only() or .defer()) will automatically save just the loaded fields. If any field is set manually after load, that field will also get updated on save. See the Model.save() documentation for more details. Caching of related model instances When traversing relations, the ORM will avoid re-fetching objects that were previously loaded. For example, with the tutorial’s models: >>> first_poll = Poll.objects.all()[0] >>> first_choice = first_poll.choice_set.all()[0] >>> first_choice.poll is first_poll True

In Django 1.5, the third line no longer triggers a new SQL query to fetch first_choice.poll; it was set by the second line. For one-to-one relationships, both sides can be cached. For many-to-one relationships, only the single side of the relationship can be cached. This is particularly helpful in combination with prefetch_related. Explicit support for streaming responses Before Django 1.5, it was possible to create a streaming response by passing an iterator to HttpResponse. But this was unreliable: any middleware that accessed the content attribute would consume the iterator prematurely. You can now explicitly generate a streaming response with the new StreamingHttpResponse class. This class exposes a streaming_content attribute which is an iterator. Since StreamingHttpResponse does not have a content attribute, middleware that needs access to the response content must test for streaming responses and behave accordingly. {% verbatim %} template tag To make it easier to deal with JavaScript templates which collide with Django’s syntax, you can now use the verbatim block tag to avoid parsing the tag’s content. Retrieval of ContentType instances associated with proxy models The methods ContentTypeManager.get_for_model() and ContentTypeManager. get_for_models() have a new keyword argument – respectively for_concrete_model and for_concrete_models. By passing False using this argument it is now possible to retrieve the ContentType associated with proxy models. New view variable in class-based views context In all generic class-based views (or any class-based view inheriting from ContextMixin), the context dictionary contains a view variable that points to the View instance.

9.1. Final releases

1599

Django Documentation, Release 2.1.dev20171115023625

GeoDjango • LineString and MultiLineString GEOS objects now support the interpolate() and project() methods (so-called linear referencing). • The wkb and hex properties of GEOSGeometry objects preserve the Z dimension. • Support for PostGIS 2.0 has been added and support for GDAL < 1.5 has been dropped. New tutorials Additions to the docs include a revamped Tutorial 3 and a new tutorial on testing. A new section, “Advanced Tutorials”, offers How to write reusable apps as well as a step-by-step guide for new contributors in Writing your first patch for Django. Minor features Django 1.5 also includes several smaller improvements worth noting: • The template engine now interprets True, False and None as the corresponding Python objects. • django.utils.timezone provides a helper for converting aware datetimes between time zones. See localtime(). • The generic views support OPTIONS requests. • Management commands do not raise SystemExit any more when called by code from call_command(). Any exception raised by the command (mostly CommandError) is propagated. Moreover, when you output errors or messages in your custom commands, you should now use self. stdout.write('message') and self.stderr.write('error') (see the note on management commands output). • The dumpdata management command outputs one row at a time, preventing out-of-memory errors when dumping large datasets. • In the localflavor for Canada, “pq” was added to the acceptable codes for Quebec. It’s an old abbreviation. • The receiver decorator is now able to connect to more than one signal by supplying a list of signals. • In the admin, you can now filter users by groups which they are members of. • QuerySet.bulk_create() now has a batch_size argument. By default the batch_size is unlimited except for SQLite where single batch is limited so that 999 parameters per query isn’t exceeded. • The LOGIN_URL and LOGIN_REDIRECT_URL settings now also accept view function names and named URL patterns. This allows you to reduce configuration duplication. More information can be found in the login_required() documentation. • Django now provides a mod_wsgi auth handler. • The QuerySet.delete() and Model.delete() can now take fast-path in some cases. The fast-path allows for less queries and less objects fetched into memory. See QuerySet.delete() for details. • An instance of ResolverMatch is stored on the request as resolver_match. • By default, all logging messages reaching the django logger when DEBUG is True are sent to the console (unless you redefine the logger in your LOGGING setting). • When using RequestContext, it is now possible to look up permissions by using {% if 'someapp. someperm' in perms %} in templates. 1600

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

• It’s not required any more to have 404.html and 500.html templates in the root templates directory. Django will output some basic error messages for both situations when those templates are not found. Of course, it’s still recommended as good practice to provide those templates in order to present pretty error pages to the user. • django.contrib.auth provides a new signal that is emitted whenever a user fails to login successfully. See user_login_failed • The new loaddata --ignorenonexistent option ignore data for fields that no longer exist. • assertXMLEqual() and assertXMLNotEqual() new assertions allow you to test equality for XML content at a semantic level, without caring for syntax differences (spaces, attribute order, etc.). • RemoteUserMiddleware now forces logout when the REMOTE_USER header disappears during the same browser session. • The cache-based session backend can store session data in a non-default cache. • Multi-column indexes can now be created on models. Read the index_together documentation for more information. • During Django’s logging configuration verbose Deprecation warnings are enabled and warnings are captured into the logging system. Logged warnings are routed through the console logging handler, which by default requires DEBUG to be True for output to be generated. The result is that DeprecationWarnings should be printed to the console in development environments the way they have been in Python versions < 2.7. • The API for django.contrib.admin.ModelAdmin.message_user() method has been modified to accept additional arguments adding capabilities similar to django.contrib.messages. add_message(). This is useful for generating error messages from admin actions. • The admin’s list filters can now be customized per-request thanks to the new django.contrib.admin. ModelAdmin.get_list_filter() method. Backwards incompatible changes in 1.5

Warning: In addition to the changes outlined in this section, be sure to review the deprecation plan for any features that have been removed. If you haven’t updated your code within the deprecation timeline for a given feature, its removal may appear as a backwards incompatible change. ALLOWED_HOSTS required in production The new ALLOWED_HOSTS setting validates the request’s Host header and protects against host-poisoning attacks. This setting is now required whenever DEBUG is False, or else django.http.HttpRequest.get_host() will raise SuspiciousOperation. For more details see the full documentation for the new setting. Managers on abstract models Abstract models are able to define a custom manager, and that manager will be inherited by any concrete models extending the abstract model. However, if you try to use the abstract model to call a method on the manager, an exception will now be raised. Previously, the call would have been permitted, but would have failed as soon as any database operation was attempted (usually with a “table does not exist” error from the database). If you have functionality on a manager that you have been invoking using the abstract class, you should migrate that logic to a Python staticmethod or classmethod on the abstract class.

9.1. Final releases

1601

Django Documentation, Release 2.1.dev20171115023625

Context in year archive class-based views For consistency with the other date-based generic views, YearArchiveView now passes year in the context as a datetime.date rather than a string. If you are using {{ year }} in your templates, you must replace it with {{ year|date:"Y" }}. next_year and previous_year were also added in the context. allow_empty and allow_future.

They are calculated according to

Context in year and month archive class-based views YearArchiveView and MonthArchiveView were documented to provide a date_list sorted in ascending order in the context, like their function-based predecessors, but it actually was in descending order. In 1.5, the documented order was restored. You may want to add (or remove) the reversed keyword when you’re iterating on date_list in a template: {% for date in date_list reversed %}

ArchiveIndexView still provides a date_list in descending order. Context in TemplateView For consistency with the design of the other generic views, TemplateView no longer passes a params dictionary into the context, instead passing the variables from the URLconf directly into the context. Non-form data in HTTP requests request.POST will no longer include data posted via HTTP requests with non form-specific content-types in the header. In prior versions, data posted with content-types other than multipart/form-data or application/ x-www-form-urlencoded would still end up represented in the request.POST attribute. Developers wishing to access the raw POST data for these cases, should use the request.body attribute instead. request_finished signal Django used to send the request_finished signal as soon as the view function returned a response. This interacted badly with streaming responses that delay content generation. This signal is now sent after the content is fully consumed by the WSGI gateway. This might be backwards incompatible if you rely on the signal being fired before sending the response content to the client. If you do, you should consider using middleware instead. Note: Some WSGI servers and middleware do not always call close on the response object after handling a request, most notably uWSGI prior to 1.2.6 and Sentry’s error reporting middleware up to 2.0.7. In those cases the request_finished signal isn’t sent at all. This can result in idle connections to database and memcache servers.

1602

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

OPTIONS, PUT and DELETE requests in the test client Unlike GET and POST, these HTTP methods aren’t implemented by web browsers. Rather, they’re used in APIs, which transfer data in various formats such as JSON or XML. Since such requests may contain arbitrary data, Django doesn’t attempt to decode their body. However, the test client used to build a query string for OPTIONS and DELETE requests like for GET, and a request body for PUT requests like for POST. This encoding was arbitrary and inconsistent with Django’s behavior when it receives the requests, so it was removed in Django 1.5. If you were using the data parameter in an OPTIONS or a DELETE request, you must convert it to a query string and append it to the path parameter. If you were using the data parameter in a PUT request without a content_type, you must encode your data before passing it to the test client and set the content_type argument. System version of simplejson no longer used As explained below, Django 1.5 deprecates django.utils.simplejson in favor of Python 2.6’s built-in json module. In theory, this change is harmless. Unfortunately, because of incompatibilities between versions of simplejson, it may trigger errors in some circumstances. JSON-related features in Django 1.4 always used django.utils.simplejson. This module was actually: • A system version of simplejson, if one was available (ie. import simplejson works), if it was more recent than Django’s built-in copy or it had the C speedups, or • The json module from the standard library, if it was available (ie. Python 2.6 or greater), or • A built-in copy of version 2.0.7 of simplejson. In Django 1.5, those features use Python’s json module, which is based on version 2.0.9 of simplejson. There are no known incompatibilities between Django’s copy of version 2.0.7 and Python’s copy of version 2.0.9. However, there are some incompatibilities between other versions of simplejson: • While the simplejson API is documented as always returning unicode strings, the optional C implementation can return a byte string. This was fixed in Python 2.7. • simplejson.JSONEncoder gained a namedtuple_as_object keyword argument in version 2.2. More information on these incompatibilities is available in ticket #18023. The net result is that, if you have installed simplejson and your code uses Django’s serialization internals directly – for instance django.core.serializers.json.DjangoJSONEncoder, the switch from simplejson to json could break your code. (In general, changes to internals aren’t documented; we’re making an exception here.) At this point, the maintainers of Django believe that using json from the standard library offers the strongest guarantee of backwards-compatibility. They recommend to use it from now on. String types of hasher method parameters If you have written a custom password hasher, your encode(), verify() or safe_summary() methods should accept Unicode parameters (password, salt or encoded). If any of the hashing methods need byte strings, you can use the force_bytes() utility to encode the strings.

9.1. Final releases

1603

Django Documentation, Release 2.1.dev20171115023625

Validation of previous_page_number and next_page_number When using object pagination, the previous_page_number() and next_page_number() methods of the Page object did not check if the returned number was inside the existing page range. It does check it now and raises an InvalidPage exception when the number is either too low or too high. Behavior of autocommit database option on PostgreSQL changed PostgreSQL’s autocommit option didn’t work as advertised previously. It did work for single transaction block, but after the first block was left the autocommit behavior was never restored. This bug is now fixed in 1.5. While this is only a bug fix, it is worth checking your applications behavior if you are using PostgreSQL together with the autocommit option. Session not saved on 500 responses Django’s session middleware will skip saving the session data if the response’s status code is 500. Email checks on failed admin login Prior to Django 1.5, if you attempted to log into the admin interface and mistakenly used your email address instead of your username, the admin interface would provide a warning advising that your email address was not your username. In Django 1.5, the introduction of custom user models has required the removal of this warning. This doesn’t change the login behavior of the admin site; it only affects the warning message that is displayed under one particular mode of login failure. Changes in tests execution Some changes have been introduced in the execution of tests that might be backward-incompatible for some testing setups: Database flushing in django.test.TransactionTestCase Previously, the test database was truncated before each test run in a TransactionTestCase. In order to be able to run unit tests in any order and to make sure they are always isolated from each other, TransactionTestCase will now reset the database after each test run instead. No more implicit DB sequences reset TransactionTestCase tests used to reset primary key sequences automatically together with the database flushing actions described above. This has been changed so no sequences are implicitly reset. This can cause TransactionTestCase tests that depend on hard-coded primary key values to break. The new reset_sequences attribute can be used to force the old behavior for TransactionTestCase that might need it.

1604

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Ordering of tests In order to make sure all TestCase code starts with a clean database, tests are now executed in the following order: • First, all unittests (including unittest.TestCase, SimpleTestCase, TestCase TransactionTestCase) are run with no particular ordering guaranteed nor enforced among them.

and

• Then any other tests (e.g. doctests) that may alter the database without restoring it to its original state are run. This should not cause any problems unless you have existing doctests which assume a TransactionTestCase executed earlier left some database state behind or unit tests that rely on some form of state being preserved after the execution of other tests. Such tests are already very fragile, and must now be changed to be able to run independently. cleaned_data dictionary kept for invalid forms The cleaned_data dictionary is now always present after form validation. When the form doesn’t validate, it contains only the fields that passed validation. You should test the success of the validation with the is_valid() method and not with the presence or absence of the cleaned_data attribute on the form. Behavior of syncdb with multiple databases syncdb now queries the database routers to determine if content types (when contenttypes is enabled) and permissions (when auth is enabled) should be created in the target database. Previously, it created them in the default database, even when another database was specified with the --database option. If you use syncdb on multiple databases, you should ensure that your routers allow synchronizing content types and permissions to only one of them. See the docs on the behavior of contrib apps with multiple databases for more information. XML deserializer will not parse documents with a DTD In order to prevent exposure to denial-of-service attacks related to external entity references and entity expansion, the XML model deserializer now refuses to parse XML documents containing a DTD (DOCTYPE definition). Since the XML serializer does not output a DTD, this will not impact typical usage, only cases where custom-created XML documents are passed to Django’s model deserializer. Formsets default max_num A (default) value of None for the max_num argument to a formset factory no longer defaults to allowing any number of forms in the formset. Instead, in order to prevent memory-exhaustion attacks, it now defaults to a limit of 1000 forms. This limit can be raised by explicitly setting a higher value for max_num. Miscellaneous • django.forms.ModelMultipleChoiceField now returns an empty QuerySet as the empty value instead of an empty list. • int_to_base36() properly raises a TypeError instead of ValueError for non-integer inputs. • The slugify template filter is now available as a standard python function at django.utils.text. slugify(). Similarly, remove_tags is available at django.utils.html.remove_tags().

9.1. Final releases

1605

Django Documentation, Release 2.1.dev20171115023625

• Uploaded files are no longer created as executable by default. If you need them to be executable change FILE_UPLOAD_PERMISSIONS to your needs. The new default value is 0o666 (octal) and the current umask value is first masked out. • The F expressions supported bitwise operators by & and |. These operators are now available using . bitand() and .bitor() instead. The removal of & and | was done to be consistent with Q() expressions and QuerySet combining where the operators are used as boolean AND and OR operators. • In a filter() call, when F expressions contained lookups spanning multi-valued relations, they didn’t always reuse the same relations as other lookups along the same chain. This was changed, and now F() expressions will always use the same relations as other lookups within the same filter() call. • The csrf_token template tag is no longer enclosed in a div. If you need HTML validation against preHTML5 Strict DTDs, you should add a div around it in your pages. • The template tags library adminmedia, which only contained the deprecated template tag {% admin_media_prefix %}, was removed. Attempting to load it with {% load adminmedia %} will fail. If your templates still contain that line you must remove it. • Because of an implementation oversight, it was possible to use django.contrib.redirects without enabling django.contrib.sites. This isn’t allowed any longer. If you’re using django.contrib.redirects, make sure INSTALLED_APPS contains django.contrib.sites. • BoundField.label_tag now escapes its contents argument. To avoid the HTML escaping, use django.utils.safestring.mark_safe() on the argument before passing it. • Accessing reverse one-to-one relations fetched via select_related() now raises DoesNotExist instead of returning None. Features deprecated in 1.5 django.contrib.localflavor The localflavor contrib app has been split into separate packages. django.contrib.localflavor itself will be removed in Django 1.6, after an accelerated deprecation. The new packages are available on GitHub. The core team cannot efficiently maintain these packages in the long term — it spans just a dozen countries at this time; similar to translations, maintenance will be handed over to interested members of the community. django.contrib.markup The markup contrib module has been deprecated and will follow an accelerated deprecation schedule. Direct use of Python markup libraries or 3rd party tag libraries is preferred to Django maintaining this functionality in the framework. AUTH_PROFILE_MODULE With the introduction of custom user models, there is no longer any need for a built-in mechanism to store user profile data. You can still define user profiles models that have a one-to-one relation with the User model - in fact, for many applications needing to associate data with a User account, this will be an appropriate design pattern to follow. However, the AUTH_PROFILE_MODULE setting, and the django.contrib.auth.models.User.get_profile() method for accessing the user profile model, should not be used any longer.

1606

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Streaming behavior of HttpResponse Django 1.5 deprecates the ability to stream a response by passing an iterator to HttpResponse. If you rely on this behavior, switch to StreamingHttpResponse. See Explicit support for streaming responses above. In Django 1.7 and above, the iterator will be consumed immediately by HttpResponse. django.utils.simplejson Since Django 1.5 drops support for Python 2.5, we can now rely on the json module being available in Python’s standard library, so we’ve removed our own copy of simplejson. You should now import json instead of django. utils.simplejson. Unfortunately, this change might have unwanted side-effects, because of incompatibilities between versions of simplejson – see the backwards-incompatible changes section. If you rely on features added to simplejson after it became Python’s json, you should import simplejson explicitly. django.utils.encoding.StrAndUnicode The django.utils.encoding.StrAndUnicode mix-in has been deprecated. Define a __str__ method and apply the python_2_unicode_compatible() decorator instead. django.utils.itercompat.product The django.utils.itercompat.product function has been deprecated. Use the built-in itertools. product() instead. cleanup management command The cleanup management command has been deprecated and replaced by clearsessions. daily_cleanup.py script The undocumented daily_cleanup.py script has been deprecated. Use the clearsessions management command instead. depth keyword argument in select_related The depth keyword argument in select_related() has been deprecated. You should use field names instead.

9.1.10 1.4 release Django 1.4.22 release notes August 18, 2015 Django 1.4.22 fixes a security issue in 1.4.21.

9.1. Final releases

1607

Django Documentation, Release 2.1.dev20171115023625

It also fixes support with pip 7+ by disabling wheel support. Older versions of 1.4 would silently build a broken wheel when installed with those versions of pip. Denial-of-service possibility in logout() view by filling session store Previously, a session could be created when anonymously accessing the django.contrib.auth.views. logout() view (provided it wasn’t decorated with login_required() as done in the admin). This could allow an attacker to easily create many new session records by sending repeated requests, potentially filling up the session store or causing other users’ session records to be evicted. The SessionMiddleware has been modified to no longer create empty session records, including when SESSION_SAVE_EVERY_REQUEST is active. Additionally, the contrib.sessions.backends.base.SessionBase.flush() and cache_db. SessionStore.flush() methods have been modified to avoid creating a new empty session. Maintainers of third-party session backends should check if the same vulnerability is present in their backend and correct it if so. Django 1.4.21 release notes July 8, 2015 Django 1.4.21 fixes several security issues in 1.4.20. Denial-of-service possibility by filling session store In previous versions of Django, the session backends created a new empty record in the session storage anytime request.session was accessed and there was a session key provided in the request cookies that didn’t already have a session record. This could allow an attacker to easily create many new session records simply by sending repeated requests with unknown session keys, potentially filling up the session store or causing other users’ session records to be evicted. The built-in session backends now create a session record only if the session is actually modified; empty session records are not created. Thus this potential DoS is now only possible if the site chooses to expose a session-modifying view to anonymous users. As each built-in session backend was fixed separately (rather than a fix in the core sessions framework), maintainers of third-party session backends should check whether the same vulnerability is present in their backend and correct it if so. Header injection possibility since validators accept newlines in input Some of Django’s built-in validators (EmailValidator, most seriously) didn’t prohibit newline characters (due to the usage of $ instead of \Z in the regular expressions). If you use values with newlines in HTTP response or email headers, you can suffer from header injection attacks. Django itself isn’t vulnerable because HttpResponse and the mail sending utilities in django.core.mail prohibit newlines in HTTP and SMTP headers, respectively. While the validators have been fixed in Django, if you’re creating HTTP responses or email messages in other ways, it’s a good idea to ensure that those methods prohibit newlines as well. You might also want to validate that any existing data in your application doesn’t contain unexpected newlines. validate_ipv4_address(), validate_slug(), and URLValidator and their usage in the corresponding form fields GenericIPAddresseField, IPAddressField, SlugField, and URLField are also affected.

1608

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

The undocumented, internally unused validate_integer() function is now stricter as it validates using a regular expression instead of simply casting the value using int() and checking if an exception was raised. Django 1.4.20 release notes March 18, 2015 Django 1.4.20 fixes one security issue in 1.4.19. Mitigated possible XSS attack via user-supplied redirect URLs Django relies on user input in some cases (e.g. django.contrib.auth.views.login() and i18n) to redirect the user to an “on success” URL. The security checks for these redirects (namely django. utils.http.is_safe_url()) accepted URLs with leading control characters and so considered URLs like \x08javascript:... safe. This issue doesn’t affect Django currently, since we only put this URL into the Location response header and browsers seem to ignore JavaScript there. Browsers we tested also treat URLs prefixed with control characters such as %08//example.com as relative paths so redirection to an unsafe target isn’t a problem either. However, if a developer relies on is_safe_url() to provide safe redirect targets and puts such a URL into a link, they could suffer from an XSS attack as some browsers such as Google Chrome ignore control characters at the start of a URL in an anchor href. Django 1.4.19 release notes January 27, 2015 Django 1.4.19 fixes a regression in the 1.4.18 security release. Bugfixes • GZipMiddleware now supports streaming responses. As part of the 1.4.18 security release, the django.views.static.serve() function was altered to stream the files it serves. Unfortunately, the GZipMiddleware consumed the stream prematurely and prevented files from being served properly (#24158). Django 1.4.18 release notes January 13, 2015 Django 1.4.18 fixes several security issues in 1.4.17 as well as a regression on Python 2.5 in the 1.4.17 release. WSGI header spoofing via underscore/dash conflation When HTTP headers are placed into the WSGI environ, they are normalized by converting to uppercase, converting all dashes to underscores, and prepending HTTP_. For instance, a header X-Auth-User would become HTTP_X_AUTH_USER in the WSGI environ (and thus also in Django’s request.META dictionary). Unfortunately, this means that the WSGI environ cannot distinguish between headers containing dashes and headers containing underscores: X-Auth-User and X-Auth_User both become HTTP_X_AUTH_USER. This means that if a header is used in a security-sensitive way (for instance, passing authentication information along from a front-end

9.1. Final releases

1609

Django Documentation, Release 2.1.dev20171115023625

proxy), even if the proxy carefully strips any incoming value for X-Auth-User, an attacker may be able to provide an X-Auth_User header (with underscore) and bypass this protection. In order to prevent such attacks, both Nginx and Apache 2.4+ strip all headers containing underscores from incoming requests by default. Django’s built-in development server now does the same. Django’s development server is not recommended for production use, but matching the behavior of common production servers reduces the surface area for behavior changes during deployment. Mitigated possible XSS attack via user-supplied redirect URLs Django relies on user input in some cases (e.g. django.contrib.auth.views.login() and i18n) to redirect the user to an “on success” URL. The security checks for these redirects (namely django.utils. http.is_safe_url()) didn’t strip leading whitespace on the tested URL and as such considered URLs like \njavascript:... safe. If a developer relied on is_safe_url() to provide safe redirect targets and put such a URL into a link, they could suffer from a XSS attack. This bug doesn’t affect Django currently, since we only put this URL into the Location response header and browsers seem to ignore JavaScript there. Denial-of-service attack against django.views.static.serve In older versions of Django, the django.views.static.serve() view read the files it served one line at a time. Therefore, a big file with no newlines would result in memory usage equal to the size of that file. An attacker could exploit this and launch a denial-of-service attack by simultaneously requesting many large files. This view now reads the file in chunks to prevent large memory usage. Note, however, that this view has always carried a warning that it is not hardened for production use and should be used only as a development aid. Now may be a good time to audit your project and serve your files in production using a real front-end web server if you are not doing so. Bugfixes • To maintain compatibility with Python 2.5, Django’s vendored version of six, django.utils.six, has been downgraded to 1.8.0 which is the last version to support Python 2.5. Django 1.4.17 release notes January 2, 2015 Django 1.4.17 fixes a regression in the 1.4.14 security release. Additionally, Django’s vendored version of six, django.utils.six, has been upgraded to the latest release (1.9.0). Bugfixes • Fixed a regression with dynamically generated inlines and allowed field references in the admin (#23754). Django 1.4.16 release notes October 22, 2014

1610

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Django 1.4.16 fixes a couple regressions in the 1.4.14 security release and a bug preventing the use of some GEOS versions with GeoDjango. Bugfixes • Allowed related many-to-many fields to be referenced in the admin (#23604). • Allowed inline and hidden references to admin fields (#23431). • Fixed parsing of the GEOS version string (#20036). Django 1.4.15 release notes September 2, 2014 Django 1.4.15 fixes a regression in the 1.4.14 security release. Bugfixes • Allowed inherited and m2m fields to be referenced in the admin (#22486) Django 1.4.14 release notes August 20, 2014 Django 1.4.14 fixes several security issues in 1.4.13. reverse() could generate URLs pointing to other hosts In certain situations, URL reversing could generate scheme-relative URLs (URLs starting with two slashes), which could unexpectedly redirect a user to a different host. An attacker could exploit this, for example, by redirecting users to a phishing site designed to ask for user’s passwords. To remedy this, URL reversing now ensures that no URL starts with two slashes (//), replacing the second slash with its URL encoded counterpart (%2F). This approach ensures that semantics stay the same, while making the URL relative to the domain and not to the scheme. File upload denial-of-service Before this release, Django’s file upload handing in its default configuration may degrade to producing a huge number of os.stat() system calls when a duplicate filename is uploaded. Since stat() may invoke IO, this may produce a huge data-dependent slowdown that slowly worsens over time. The net result is that given enough time, a user with the ability to upload files can cause poor performance in the upload handler, eventually causing it to become very slow simply by uploading 0-byte files. At this point, even a slow network connection and few HTTP requests would be all that is necessary to make a site unavailable. We’ve remedied the issue by changing the algorithm for generating file names if a file with the uploaded name already exists. Storage.get_available_name() now appends an underscore plus a random 7 character alphanumeric string (e.g. "_x3a1gho"), rather than iterating through an underscore followed by a number (e.g. "_1", "_2", etc.).

9.1. Final releases

1611

Django Documentation, Release 2.1.dev20171115023625

RemoteUserMiddleware session hijacking When using the RemoteUserMiddleware and the RemoteUserBackend, a change to the REMOTE_USER header between requests without an intervening logout could result in the prior user’s session being co-opted by the subsequent user. The middleware now logs the user out on a failed login attempt. Data leakage via query string manipulation in contrib.admin In older versions of Django it was possible to reveal any field’s data by modifying the “popup” and “to_field” parameters of the query string on an admin change form page. For example, requesting a URL like /admin/auth/user/ ?pop=1&t=password and viewing the page’s HTML allowed viewing the password hash of each user. While the admin requires users to have permissions to view the change form pages in the first place, this could leak data if you rely on users having access to view only certain fields on a model. To address the issue, an exception will now be raised if a to_field value that isn’t a related field to a model that has been registered with the admin is specified. Django 1.4.13 release notes May 14, 2014 Django 1.4.13 fixes two security issues in 1.4.12. Caches may incorrectly be allowed to store and serve private data In certain situations, Django may allow caches to store private data related to a particular session and then serve that data to requests with a different session, or no session at all. This can lead to information disclosure and can be a vector for cache poisoning. When using Django sessions, Django will set a Vary: Cookie header to ensure caches do not serve cached data to requests from other sessions. However, older versions of Internet Explorer (most likely only Internet Explorer 6, and Internet Explorer 7 if run on Windows XP or Windows Server 2003) are unable to handle the Vary header in combination with many content types. Therefore, Django would remove the header if the request was made by Internet Explorer. To remedy this, the special behavior for these older Internet Explorer versions has been removed, and the Vary header is no longer stripped from the response. In addition, modifications to the Cache-Control header for all Internet Explorer requests with a Content-Disposition header have also been removed as they were found to have similar issues. Malformed redirect URLs from user input not correctly validated The validation for redirects did not correctly validate some malformed URLs, which are accepted by some browsers. This allows a user to be redirected to an unsafe URL unexpectedly. Django relies on user input in some cases (e.g. django.contrib.auth.views.login(), django. contrib.comments, and i18n) to redirect the user to an “on success” URL. The security checks for these redirects (namely django.utils.http.is_safe_url()) did not correctly validate some malformed URLs, such as http:\\\djangoproject.com, which are accepted by some browsers with more liberal URL parsing. To remedy this, the validation in is_safe_url() has been tightened to be able to handle and correctly validate these malformed URLs.

1612

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Django 1.4.12 release notes April 28, 2014 Django 1.4.12 fixes a regression in the 1.4.11 security release. Bugfixes • Restored the ability to reverse() views created using functools.partial() (#22486). Django 1.4.11 release notes April 21, 2014 Django 1.4.11 fixes three security issues in 1.4.10. Additionally, Django’s vendored version of six, django.utils. six, has been upgraded to the latest release (1.6.1). Unexpected code execution using reverse() Django’s URL handling is based on a mapping of regex patterns (representing the URLs) to callable views, and Django’s own processing consists of matching a requested URL against those patterns to determine the appropriate view to invoke. Django also provides a convenience function – reverse() – which performs this process in the opposite direction. The reverse() function takes information about a view and returns a URL which would invoke that view. Use of reverse() is encouraged for application developers, as the output of reverse() is always based on the current URL patterns, meaning developers do not need to change other code when making changes to URLs. One argument signature for reverse() is to pass a dotted Python path to the desired view. In this situation, Django will import the module indicated by that dotted path as part of generating the resulting URL. If such a module has import-time side effects, those side effects will occur. Thus it is possible for an attacker to cause unexpected code execution, given the following conditions: 1. One or more views are present which construct a URL based on user input (commonly, a “next” parameter in a querystring indicating where to redirect upon successful completion of an action). 2. One or more modules are known to an attacker to exist on the server’s Python import path, which perform code execution with side effects on importing. To remedy this, reverse() will now only accept and import dotted paths based on the view-containing modules listed in the project’s URL pattern configuration, so as to ensure that only modules the developer intended to be imported in this fashion can or will be imported. Caching of anonymous pages could reveal CSRF token Django includes both a caching framework and a system for preventing cross-site request forgery (CSRF) attacks. The CSRF-protection system is based on a random nonce sent to the client in a cookie which must be sent by the client on future requests and, in forms, a hidden value which must be submitted back with the form. The caching framework includes an option to cache responses to anonymous (i.e., unauthenticated) clients. When the first anonymous request to a given page is by a client which did not have a CSRF cookie, the cache framework will also cache the CSRF cookie and serve the same nonce to other anonymous clients who do not have a CSRF

9.1. Final releases

1613

Django Documentation, Release 2.1.dev20171115023625

cookie. This can allow an attacker to obtain a valid CSRF cookie value and perform attacks which bypass the check for the cookie. To remedy this, the caching framework will no longer cache such responses. The heuristic for this will be: 1. If the incoming request did not submit any cookies, and 2. If the response did send one or more cookies, and 3. If the Vary:

Cookie header is set on the response, then the response will not be cached.

MySQL typecasting The MySQL database is known to “typecast” on certain queries; for example, when querying a table which contains string values, but using a query which filters based on an integer value, MySQL will first silently coerce the strings to integers and return a result based on that. If a query is performed without first converting values to the appropriate type, this can produce unexpected results, similar to what would occur if the query itself had been manipulated. Django’s model field classes are aware of their own types and most such classes perform explicit conversion of query arguments to the correct database-level type before querying. However, three model field classes did not correctly convert their arguments: • FilePathField • GenericIPAddressField • IPAddressField These three fields have been updated to convert their arguments to the correct types before querying. Additionally, developers of custom model fields are now warned via documentation to ensure their custom field classes will perform appropriate type conversions, and users of the raw() and extra() query methods – which allow the developer to supply raw SQL or SQL fragments – will be advised to ensure they perform appropriate manual type conversions prior to executing queries. Django 1.4.10 release notes November 6, 2013 Django 1.4.10 fixes a Python-compatibility bug in the 1.4 series. Python compatibility Django 1.4.9 inadvertently introduced issues with Python 2.5 compatibility. Django 1.4.10 restores Python 2.5 compatibility. This was issue #21362 in Django’s Trac. Django 1.4.9 release notes October 23, 2013 Django 1.4.9 fixes a security-related bug in the 1.4 series and one other data corruption bug.

1614

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Readdressed denial-of-service via password hashers Django 1.4.8 imposes a 4096-byte limit on passwords in order to mitigate a denial-of-service attack through submission of bogus but extremely large passwords. In Django 1.4.9, we’ve reverted this change and instead improved the speed of our PBKDF2 algorithm by not rehashing the key on every iteration. Bugfixes • Fixed a data corruption bug with datetime_safe.datetime.combine (#21256). Django 1.4.8 release notes September 14, 2013 Django 1.4.8 fixes two security issues present in previous Django releases in the 1.4 series. Denial-of-service via password hashers In previous versions of Django, no limit was imposed on the plaintext length of a password. This allowed a denial-ofservice attack through submission of bogus but extremely large passwords, tying up server resources performing the (expensive, and increasingly expensive with the length of the password) calculation of the corresponding hash. As of 1.4.8, Django’s authentication framework imposes a 4096-byte limit on passwords and will fail authentication with any submitted password of greater length. Corrected usage of sensitive_post_parameters() in django.contrib.auth’s admin The decoration of the add_view and user_change_password user admin views with sensitive_post_parameters() did not include method_decorator() (required since the views are methods) resulting in the decorator not being properly applied. This usage has been fixed and sensitive_post_parameters() will now throw an exception if it’s improperly used. Django 1.4.7 release notes September 10, 2013 Django 1.4.7 fixes one security issue present in previous Django releases in the 1.4 series. Directory traversal vulnerability in ssi template tag In previous versions of Django it was possible to bypass the ALLOWED_INCLUDE_ROOTS setting used for security with the ssi template tag by specifying a relative path that starts with one of the allowed roots. For example, if ALLOWED_INCLUDE_ROOTS = ("/var/www",) the following would be possible: {% ssi "/var/www/../../etc/passwd" %}

In practice this is not a very common problem, as it would require the template author to put the ssi file in a usercontrolled variable, but it’s possible in principle.

9.1. Final releases

1615

Django Documentation, Release 2.1.dev20171115023625

Django 1.4.6 release notes August 13, 2013 Django 1.4.6 fixes one security issue present in previous Django releases in the 1.4 series, as well as one other bug. This is the sixth bugfix/security release in the Django 1.4 series. Mitigated possible XSS attack via user-supplied redirect URLs Django relies on user input in some cases (e.g. django.contrib.auth.views.login(), django. contrib.comments, and i18n) to redirect the user to an “on success” URL. The security checks for these redirects (namely django.utils.http.is_safe_url()) didn’t check if the scheme is http(s) and as such allowed javascript:... URLs to be entered. If a developer relied on is_safe_url() to provide safe redirect targets and put such a URL into a link, they could suffer from a XSS attack. This bug doesn’t affect Django currently, since we only put this URL into the Location response header and browsers seem to ignore JavaScript there. Bugfixes • Fixed an obscure bug with the override_settings() decorator. If you hit an AttributeError: 'Settings' object has no attribute '_original_allowed_hosts' exception, it’s probably fixed (#20636). Django 1.4.5 release notes February 20, 2013 Django 1.4.5 corrects a packaging problem with yesterday’s 1.4.4 release. The release contained stray .pyc files that caused “bad magic number” errors when running with some versions of Python. This releases corrects this, and also fixes a bad documentation link in the project template settings.py file generated by manage.py startproject. Django 1.4.4 release notes February 19, 2013 Django 1.4.4 fixes four security issues present in previous Django releases in the 1.4 series, as well as several other bugs and numerous documentation improvements. This is the fourth bugfix/security release in the Django 1.4 series. Host header poisoning Some parts of Django – independent of end-user-written applications – make use of full URLs, including domain name, which are generated from the HTTP Host header. Django’s documentation has for some time contained notes advising users on how to configure Web servers to ensure that only valid Host headers can reach the Django application. However, it has been reported to us that even with the recommended Web server configurations there are still techniques available for tricking many common Web servers into supplying the application with an incorrect and possibly malicious Host header. For this reason, Django 1.4.4 adds a new setting, ALLOWED_HOSTS, containing an explicit list of valid host/domain names for this site. A request with a Host header not matching an entry in this list will raise

1616

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

SuspiciousOperation if request.get_host() is called. For full details see the documentation for the ALLOWED_HOSTS setting. The default value for this setting in Django 1.4.4 is ['*'] (matching any host), for backwards-compatibility, but we strongly encourage all sites to set a more restrictive value. This host validation is disabled when DEBUG is True or when running tests. XML deserialization The XML parser in the Python standard library is vulnerable to a number of attacks via external entities and entity expansion. Django uses this parser for deserializing XML-formatted database fixtures. This deserializer is not intended for use with untrusted data, but in order to err on the side of safety in Django 1.4.4 the XML deserializer refuses to parse an XML document with a DTD (DOCTYPE definition), which closes off these attack avenues. These issues in the Python standard library are CVE-2013-1664 and CVE-2013-1665. More information available from the Python security team. Django’s XML serializer does not create documents with a DTD, so this should not cause any issues with the typical round-trip from dumpdata to loaddata, but if you feed your own XML documents to the loaddata management command, you will need to ensure they do not contain a DTD. Formset memory exhaustion Previous versions of Django did not validate or limit the form-count data provided by the client in a formset’s management form, making it possible to exhaust a server’s available memory by forcing it to create very large numbers of forms. In Django 1.4.4, all formsets have a strictly-enforced maximum number of forms (1000 by default, though it can be set higher via the max_num formset factory argument). Admin history view information leakage In previous versions of Django, an admin user without change permission on a model could still view the unicode representation of instances via their admin history log. Django 1.4.4 now limits the admin history log view for an object to users with change permission for that model. Other bugfixes and changes • Prevented transaction state from leaking from one request to the next (#19707). • Changed an SQL command syntax to be MySQL 4 compatible (#19702). • Added backwards-compatibility with old unsalted MD5 passwords (#18144). • Numerous documentation improvements and fixes. Django 1.4.3 release notes December 10, 2012 Django 1.4.3 addresses two security issues present in previous Django releases in the 1.4 series.

9.1. Final releases

1617

Django Documentation, Release 2.1.dev20171115023625

Please be aware that this security release is slightly different from previous ones. Both issues addressed here have been dealt with in prior security updates to Django. In one case, we have received ongoing reports of problems, and in the other we’ve chosen to take further steps to tighten up Django’s code in response to independent discovery of potential problems from multiple sources. Host header poisoning Several earlier Django security releases focused on the issue of poisoning the HTTP Host header, causing Django to generate URLs pointing to arbitrary, potentially-malicious domains. In response to further input received and reports of continuing issues following the previous release, we’re taking additional steps to tighten Host header validation. Rather than attempt to accommodate all features HTTP supports here, Django’s Host header validation attempts to support a smaller, but far more common, subset: • Hostnames must consist of characters [A-Za-z0-9] plus hyphen (‘-‘) or dot (‘.’). • IP addresses – both IPv4 and IPv6 – are permitted. • Port, if specified, is numeric. Any deviation from this will now be rejected, raising the exception django.core.exceptions. SuspiciousOperation. Redirect poisoning Also following up on a previous issue: in July of this year, we made changes to Django’s HTTP redirect classes, performing additional validation of the scheme of the URL to redirect to (since, both within Django’s own supplied applications and many third-party applications, accepting a user-supplied redirect target is a common pattern). Since then, two independent audits of the code turned up further potential problems. So, similar to the Host-header issue, we are taking steps to provide tighter validation in response to reported problems (primarily with third-party applications, but to a certain extent also within Django itself). This comes in two parts: 1. A new utility function, django.utils.http.is_safe_url, is added; this function takes a URL and a hostname, and checks that the URL is either relative, or if absolute matches the supplied hostname. This function is intended for use whenever user-supplied redirect targets are accepted, to ensure that such redirects cannot lead to arbitrary third-party sites. 2. All of Django’s own built-in views – primarily in the authentication system – which allow user-supplied redirect targets now use is_safe_url to validate the supplied URL. Django 1.4.2 release notes October 17, 2012 This is the second security release in the Django 1.4 series. Host header poisoning Some parts of Django – independent of end-user-written applications – make use of full URLs, including domain name, which are generated from the HTTP Host header. Some attacks against this are beyond Django’s ability to control, and require the web server to be properly configured; Django’s documentation has for some time contained notes advising users on such configuration.

1618

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Django’s own built-in parsing of the Host header is, however, still vulnerable, as was reported to us recently. The Host header parsing in Django 1.3.3 and Django 1.4.1 – specifically, django.http.HttpRequest.get_host() – was incorrectly handling username/password information in the header. Thus, for example, the following Host header would be accepted by Django when running on “validsite.com”: Host: validsite.com:[emailprotected]

Using this, an attacker can cause parts of Django – particularly the password-reset mechanism – to generate and display arbitrary URLs to users. To remedy this, the parsing in HttpRequest.get_host() is being modified; Host headers which contain potentially dangerous content (such as username/password pairs) now raise the exception django.core.exceptions. SuspiciousOperation. Details of this issue were initially posted online as a security advisory. Backwards incompatible changes • The newly introduced GenericIPAddressField constructor arguments have been adapted to match those of all other model fields. The first two keyword arguments are now verbose_name and name. Other bugfixes and changes • Subclass HTMLParser only for appropriate Python versions (#18239). • Added batch_size argument to qs.bulk_create() (#17788). • Fixed a small regression in the admin filters where wrongly formatted dates passed as url parameters caused an unhandled ValidationError (#18530). • Fixed an endless loop bug when accessing permissions in templates (#18979) • Fixed some Python 2.5 compatibility issues • Fixed an issue with quoted filenames in Content-Disposition header (#19006) • Made the context option in trans and blocktrans tags accept literals wrapped in single quotes (#18881). • Numerous documentation improvements and fixes. Django 1.4.1 release notes July 30, 2012 This is the first security release in the Django 1.4 series, fixing several security issues in Django 1.4. Django 1.4.1 is a recommended upgrade for all users of Django 1.4. For a full list of issues addressed in this release, see the security advisory. Django 1.4 release notes March 23, 2012 Welcome to Django 1.4! These release notes cover the new features, as well as some backwards incompatible changes you’ll want to be aware of when upgrading from Django 1.3 or older versions. We’ve also dropped some features, which are detailed in our deprecation plan, and we’ve begun the deprecation process for some features. 9.1. Final releases

1619

Django Documentation, Release 2.1.dev20171115023625

Overview The biggest new feature in Django 1.4 is support for time zones when handling date/times. When enabled, this Django will store date/times in UTC, use timezone-aware objects internally, and translate them to users’ local timezones for display. If you’re upgrading an existing project to Django 1.4, switching to the timezone aware mode may take some care: the new mode disallows some rather sloppy behavior that used to be accepted. We encourage anyone who’s upgrading to check out the timezone migration guide and the timezone FAQ for useful pointers. Other notable new features in Django 1.4 include: • A number of ORM improvements, including SELECT FOR UPDATE support, the ability to bulk insert large datasets for improved performance, and QuerySet.prefetch_related, a method to batch-load related objects in areas where select_related() doesn’t work. • Some nice security additions, including improved password hashing (featuring PBKDF2 and bcrypt support), new tools for cryptographic signing, several CSRF improvements, and simple clickjacking protection. • An updated default project layout and manage.py that removes the “magic” from prior versions. And for those who don’t like the new layout, you can use custom project and app templates instead! • Support for in-browser testing frameworks (like Selenium). • ... and a whole lot more; see below! Wherever possible we try to introduce new features in a backwards-compatible manner per our API stability policy policy. However, as with previous releases, Django 1.4 ships with some minor backwards incompatible changes; people upgrading from previous versions of Django should read that list carefully. Python compatibility Django 1.4 has dropped support for Python 2.4. Python 2.5 is now the minimum required Python version. Django is tested and supported on Python 2.5, 2.6 and 2.7. This change should affect only a small number of Django users, as most operating-system vendors today are shipping Python 2.5 or newer as their default version. If you’re still using Python 2.4, however, you’ll need to stick to Django 1.3 until you can upgrade. Per our support policy, Django 1.3 will continue to receive security support until the release of Django 1.5. Django does not support Python 3.x at this time. At some point before the release of Django 1.4, we plan to publish a document outlining our full timeline for deprecating Python 2.x and moving to Python 3.x. What’s new in Django 1.4 Support for time zones In previous versions, Django used “naive” date/times (that is, date/times without an associated time zone), leaving it up to each developer to interpret what a given date/time “really means”. This can cause all sorts of subtle timezone-related bugs. In Django 1.4, you can now switch Django into a more correct, time-zone aware mode. In this mode, Django stores date and time information in UTC in the database, uses time-zone-aware datetime objects internally and translates them to the end user’s time zone in templates and forms. Reasons for using this feature include: • Customizing date and time display for users around the world.

1620

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

• Storing datetimes in UTC for database portability and interoperability. (This argument doesn’t apply to PostgreSQL, because it already stores timestamps with time zone information in Django 1.3.) • Avoiding data corruption problems around DST transitions. Time zone support is enabled by default in new projects created with startproject. If you want to use this feature in an existing project, read the migration guide. If you encounter problems, there’s a helpful FAQ. Support for in-browser testing frameworks Django 1.4 supports integration with in-browser testing frameworks like Selenium. The new django.test. LiveServerTestCase base class lets you test the interactions between your site’s front and back ends more comprehensively. See the documentation for more details and concrete examples. Updated default project layout and manage.py Django 1.4 ships with an updated default project layout and manage.py file for the startproject management command. These fix some issues with the previous manage.py handling of Python import paths that caused double imports, trouble moving from development to deployment, and other difficult-to-debug path issues. The previous manage.py called functions that are now deprecated, and thus projects upgrading to Django 1.4 should update their manage.py. (The old-style manage.py will continue to work as before until Django 1.6. In 1.5 it will raise DeprecationWarning). The new recommended manage.py file should look like this: #!/usr/bin/env python import os, sys if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings") from django.core.management import execute_from_command_line execute_from_command_line(sys.argv)

{{ project_name }} should be replaced with the Python package name of the actual project. If settings, URLconfs and apps within the project are imported or referenced using the project name prefix (e.g. myproject.settings, ROOT_URLCONF = "myproject.urls", etc.), the new manage.py will need to be moved one directory up, so it is outside the project package rather than adjacent to settings.py and urls.py. For instance, with the following layout: manage.py mysite/ __init__.py settings.py urls.py myapp/ __init__.py models.py

You could import mysite.settings, mysite.urls, and mysite.myapp, but not settings, urls, or myapp as top-level modules.

9.1. Final releases

1621

Django Documentation, Release 2.1.dev20171115023625

Anything imported as a top-level module can be placed adjacent to the new manage.py. For instance, to decouple “myapp” from the project module and import it as just myapp, place it outside the mysite/ directory: manage.py myapp/ __init__.py models.py mysite/ __init__.py settings.py urls.py

If the same code is imported inconsistently (some places with the project prefix, some places without it), the imports will need to be cleaned up when switching to the new manage.py. Custom project and app templates The startapp and startproject management commands now have a --template option for specifying a path or URL to a custom app or project template. For example, Django will use the /path/to/my_project_template directory when you run the following command: django-admin.py startproject --template=/path/to/my_project_template myproject

You can also now provide a destination directory as the second argument to both startapp and startproject: django-admin.py startapp myapp /path/to/new/app django-admin.py startproject myproject /path/to/new/project

For more information, see the startapp and startproject documentation. Improved WSGI support The startproject management command now adds a wsgi.py module to the initial project layout, containing a simple WSGI application that can be used for deploying with WSGI app servers. The built-in development server now supports using an externally-defined WSGI callable, which makes it possible to run runserver with the same WSGI configuration that is used for deployment. The new WSGI_APPLICATION setting lets you configure which WSGI callable runserver uses. (The runfcgi management WSGI_APPLICATION .)

command

also

internally

wraps

the

WSGI

callable

configured

via

SELECT FOR UPDATE support Django 1.4 includes a QuerySet.select_for_update() method, which generates a SELECT ... FOR UPDATE SQL query. This will lock rows until the end of the transaction, meaning other transactions cannot modify or delete rows matched by a FOR UPDATE query. For more details, see the documentation for select_for_update().

1622

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Model.objects.bulk_create in the ORM This method lets you create multiple objects more efficiently. It can result in significant performance increases if you have many objects. Django makes use of this internally, meaning some operations (such as database setup for test suites) have seen a performance benefit as a result. See the bulk_create() docs for more information. QuerySet.prefetch_related Similar to select_related() but with a different strategy and broader scope, prefetch_related() has been added to QuerySet. This method returns a new QuerySet that will prefetch each of the specified related lookups in a single batch as soon as the query begins to be evaluated. Unlike select_related, it does the joins in Python, not in the database, and supports many-to-many relationships, GenericForeignKey and more. This allows you to fix a very common performance problem in which your code ends up doing O(n) database queries (or worse) if objects on your primary QuerySet each have many related objects that you also need to fetch. Improved password hashing Django’s auth system (django.contrib.auth) stores passwords using a one-way algorithm. Django 1.3 uses the SHA1 algorithm, but increasing processor speeds and theoretical attacks have revealed that SHA1 isn’t as secure as we’d like. Thus, Django 1.4 introduces a new password storage system: by default Django now uses the PBKDF2 algorithm (as recommended by NIST). You can also easily choose a different algorithm (including the popular bcrypt algorithm). For more details, see How Django stores passwords. HTML5 doctype We’ve switched the admin and other bundled templates to use the HTML5 doctype. While Django will be careful to maintain compatibility with older browsers, this change means that you can use any HTML5 features you need in admin pages without having to lose HTML validity or override the provided templates to change the doctype. List filters in admin interface Prior to Django 1.4, the admin app let you specify change list filters by specifying a field lookup, but it didn’t allow you to create custom filters. This has been rectified with a simple API (previously used internally and known as “FilterSpec”). For more details, see the documentation for list_filter. Multiple sort in admin interface The admin change list now supports sorting on multiple columns. It respects all elements of the ordering attribute, and sorting on multiple columns by clicking on headers is designed to mimic the behavior of desktop GUIs. We also added a get_ordering() method for specifying the ordering dynamically (i.e., depending on the request). New ModelAdmin methods We added a save_related() method to ModelAdmin to ease customization of how related objects are saved in the admin. 9.1. Final releases

1623

Django Documentation, Release 2.1.dev20171115023625

Two other new ModelAdmin methods, get_list_display() and get_list_display_links() enable dynamic customization of fields and links displayed on the admin change list. Admin inlines respect user permissions Admin inlines now only allow those actions for which the user has permission. For ManyToMany relationships with an auto-created intermediate model (which does not have its own permissions), the change permission for the related model determines if the user has the permission to add, change or delete relationships. Tools for cryptographic signing Django 1.4 adds both a low-level API for signing values and a high-level API for setting and reading signed cookies, one of the most common uses of signing in Web applications. See the cryptographic signing docs for more information. Cookie-based session backend Django 1.4 introduces a cookie-based session backend that uses the tools for cryptographic signing to store the session data in the client’s browser. Warning: Session data is signed and validated by the server, but it’s not encrypted. This means a user can view any data stored in the session but cannot change it. Please read the documentation for further clarification before using this backend. See the cookie-based session backend docs for more information. New form wizard The previous FormWizard from django.contrib.formtools has been replaced with a new implementation based on the class-based views introduced in Django 1.3. It features a pluggable storage API and doesn’t require the wizard to pass around hidden fields for every previous step. Django 1.4 ships with a session-based storage backend and a cookie-based storage backend. The latter uses the tools for cryptographic signing also introduced in Django 1.4 to store the wizard’s state in the user’s cookies. reverse_lazy A lazily evaluated version of reverse() was added to allow using URL reversals before the project’s URLconf gets loaded. Translating URL patterns Django can now look for a language prefix in the URLpattern when using the new i18n_patterns() helper function. It’s also now possible to define translatable URL patterns using ugettext_lazy(). See Internationalization: in URL patterns for more information about the language prefix and how to internationalize URL patterns.

1624

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Contextual translation support for {% trans %} and {% blocktrans %} The contextual translation support introduced in Django 1.3 via the pgettext function has been extended to the trans and blocktrans template tags using the new context keyword. Customizable SingleObjectMixin URLConf kwargs Two new attributes, pk_url_kwarg and slug_url_kwarg, have been added to SingleObjectMixin to enable the customization of URLconf keyword arguments used for single object generic views. Assignment template tags A new assignment_tag helper function was added to template.Library to ease the creation of template tags that store data in a specified context variable. *args and **kwargs support for template tag helper functions The simple_tag, inclusion_tag and newly introduced assignment_tag template helper functions may now accept any number of positional or keyword arguments. For example: @register.simple_tag def my_tag(a, b, *args, **kwargs): warning = kwargs['warning'] profile = kwargs['profile'] ... return ...

Then, in the template, any number of arguments may be passed to the template tag. For example: {% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}

No wrapping of exceptions in TEMPLATE_DEBUG mode In previous versions of Django, whenever the TEMPLATE_DEBUG setting was True, any exception raised during template rendering (even exceptions unrelated to template syntax) were wrapped in TemplateSyntaxError and re-raised. This was done in order to provide detailed template source location information in the debug 500 page. In Django 1.4, exceptions are no longer wrapped. Instead, the original exception is annotated with the source information. This means that catching exceptions from template rendering is now consistent regardless of the value of TEMPLATE_DEBUG, and there’s no need to catch and unwrap TemplateSyntaxError in order to catch other errors. truncatechars template filter This new filter truncates a string to be no longer than the specified number of characters. Truncated strings end with a translatable ellipsis sequence (”...”). See the documentation for truncatechars for more details.

9.1. Final releases

1625

Django Documentation, Release 2.1.dev20171115023625

static template tag The staticfiles contrib app has a new static template tag to refer to files saved with the STATICFILES_STORAGE storage backend. It uses the storage backend’s url method and therefore supports advanced features such as serving files from a cloud service. CachedStaticFilesStorage storage backend The staticfiles contrib app now has a CachedStaticFilesStorage backend that caches the files it saves (when running the collectstatic management command) by appending the MD5 hash of the file’s content to the filename. For example, the file css/styles.css would also be saved as css/styles.55e7cbb9ba48.css See the CachedStaticFilesStorage docs for more information. Simple clickjacking protection We’ve added a middleware to provide easy protection against clickjacking using the X-Frame-Options header. It’s not enabled by default for backwards compatibility reasons, but you’ll almost certainly want to enable it to help plug that security hole for browsers that support the header. CSRF improvements We’ve made various improvements to our CSRF features, including the ensure_csrf_cookie() decorator, which can help with AJAX-heavy sites; protection for PUT and DELETE requests; and the CSRF_COOKIE_SECURE and CSRF_COOKIE_PATH settings, which can improve the security and usefulness of CSRF protection. See the CSRF docs for more information. Error report filtering We added two function decorators, sensitive_variables() and sensitive_post_parameters(), to allow designating the local variables and POST parameters that may contain sensitive information and should be filtered out of error reports. All POST parameters are now systematically filtered out of error reports for certain views (login, password_reset_confirm, password_change and add_view in django.contrib.auth.views, as well as user_change_password in the admin app) to prevent the leaking of sensitive information such as user passwords. You can override or customize the default filtering by writing a custom filter. For more information see the docs on Filtering error reports. Extended IPv6 support Django 1.4 can now better handle IPv6 addresses with the new GenericIPAddressField model field, GenericIPAddressField form field and the validators validate_ipv46_address and validate_ipv6_address.

1626

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

HTML comparisons in tests The base classes in django.test now have some helpers to compare HTML without tripping over irrelevant differences in whitespace, argument quoting/ordering and closing of self-closing tags. You can either compare HTML directly with the new assertHTMLEqual() and assertHTMLNotEqual() assertions, or use the html=True flag with assertContains() and assertNotContains() to test whether the client’s response contains a given HTML fragment. See the assertions documentation for more. Two new date format strings Two new date formats were added for use in template filters, template tags and Format localization: • e – the name of the timezone of the given datetime object • o – the ISO 8601 year number Please make sure to update your custom format files if they contain either e or o in a format string. For example a Spanish localization format previously only escaped the d format character: DATE_FORMAT = r'j \de F \de Y'

But now it needs to also escape e and o: DATE_FORMAT = r'j \d\e F \d\e Y'

For more information, see the date documentation. Minor features Django 1.4 also includes several smaller improvements worth noting: • A more usable stacktrace in the technical 500 page. Frames in the stack trace that reference Django’s framework code are dimmed out, while frames in application code are slightly emphasized. This change makes it easier to scan a stacktrace for issues in application code. • Tablespace support in PostgreSQL. • Customizable names for simple_tag(). • In the documentation, a helpful security overview page. • The django.contrib.auth.models.check_password function has been moved to the django. contrib.auth.hashers module. Importing it from the old location will still work, but you should update your imports. • The collectstatic management command now has a --clear option to delete all files at the destination before copying or linking the static files. • It’s now possible to load fixtures containing forward references when using MySQL with the InnoDB database engine. • A new 403 response handler has been added as 'django.views.defaults.permission_denied'. You can set your own handler by setting the value of django.conf.urls.handler403. See the documentation about the 403 (HTTP Forbidden) view for more information. • The makemessages command uses a new and more accurate lexer, JsLex, for extracting translatable strings from JavaScript files.

9.1. Final releases

1627

Django Documentation, Release 2.1.dev20171115023625

• The trans template tag now takes an optional as argument to be able to retrieve a translation string without displaying it but setting a template context variable instead. • The if template tag now supports {% elif %} clauses. • If your Django app is behind a proxy, you might find the new SECURE_PROXY_SSL_HEADER setting useful. It solves the problem of your proxy “eating” the fact that a request came in via HTTPS. But only use this setting if you know what you’re doing. • A new, plain-text, version of the HTTP 500 status code internal error page served when DEBUG is True is now sent to the client when Django detects that the request has originated in JavaScript code. (is_ajax() is used for this.) Like its HTML counterpart, it contains a collection of different pieces of information about the state of the application. This should make it easier to read when debugging interaction with client-side JavaScript. • Added the makemessages --no-location option. • Changed the locmem cache backend to use pickle.HIGHEST_PROTOCOL for better compatibility with the other cache backends. • Added support in the ORM for generating SELECT queries containing DISTINCT ON. The distinct() QuerySet method now accepts an optional list of model field names. If specified, then the DISTINCT statement is limited to these fields. This is only supported in PostgreSQL. For more details, see the documentation for distinct(). • The admin login page will add a password reset link if you include a URL with the name ‘admin_password_reset’ in your urls.py, so plugging in the built-in password reset mechanism and making it available is now much easier. For details, see Adding a password reset feature. • The MySQL database backend can now make use of the savepoint feature implemented by MySQL version 5.0.3 or newer with the InnoDB storage engine. • It’s now possible to pass initial values to the model forms that are part of both model formsets and inline model formsets as returned from factory functions modelformset_factory and inlineformset_factory respectively just like with regular formsets. However, initial values only apply to extra forms, i.e. those which are not bound to an existing model instance. • The sitemaps framework can now handle HTTPS links using the new Sitemap.protocol class attribute. • A new django.test.SimpleTestCase subclass of unittest.TestCase that’s lighter than django.test.TestCase and company. It can be useful in tests that don’t need to hit a database. See Hierarchy of Django unit testing classes. Backwards incompatible changes in 1.4 SECRET_KEY setting is required Running Django with an empty or known SECRET_KEY disables many of Django’s security protections and can lead to remote-code-execution vulnerabilities. No Django site should ever be run without a SECRET_KEY. In Django 1.4, starting Django with an empty SECRET_KEY will raise a DeprecationWarning. In Django 1.5, it will raise an exception and Django will refuse to start. This is slightly accelerated from the usual deprecation path due to the severity of the consequences of running Django with no SECRET_KEY.

1628

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

django.contrib.admin The included administration app django.contrib.admin has for a long time shipped with a default set of static files such as JavaScript, images and stylesheets. Django 1.3 added a new contrib app django.contrib. staticfiles to handle such files in a generic way and defined conventions for static files included in apps. Starting in Django 1.4, the admin’s static files also follow this convention, to make the files easier to deploy. In previous versions of Django, it was also common to define an ADMIN_MEDIA_PREFIX setting to point to the URL where the admin’s static files live on a Web server. This setting has now been deprecated and replaced by the more general setting STATIC_URL. Django will now expect to find the admin static files under the URL /admin/. If you’ve previously used a URL path for ADMIN_MEDIA_PREFIX (e.g. /media/) simply make sure STATIC_URL and STATIC_ROOT are configured and your Web server serves those files correctly. The development server continues to serve the admin files just like before. Read the static files howto for more details. If your ADMIN_MEDIA_PREFIX is set to an specific domain (e.g. http://media.example.com/admin/), make sure to also set your STATIC_URL setting to the correct URL – for example, http://media.example. com/. Warning: If you’re implicitly relying on the path of the admin static files within Django’s source code, you’ll need to update that path. The files were moved from django/contrib/admin/media/ to django/contrib/ admin/static/admin/.

Supported browsers for the admin Django hasn’t had a clear policy on which browsers are supported by the admin app. Our new policy formalizes existing practices: YUI’s A-grade browsers should provide a fully-functional admin experience, with the notable exception of Internet Explorer 6, which is no longer supported. Released over 10 years ago, IE6 imposes many limitations on modern Web development. The practical implications of this policy are that contributors are free to improve the admin without consideration for these limitations. Obviously, this new policy has no impact on sites you develop using Django. It only applies to the Django admin. Feel free to develop apps compatible with any range of browsers. Removed admin icons As part of an effort to improve the performance and usability of the admin’s change-list sorting interface and horizontal and vertical “filter” widgets, some icon files were removed and grouped into two sprite files. Specifically: selector-add.gif, selector-addall.gif, selector-remove.gif, selector-removeall.gif, selector_stacked-add.gif and selector_stacked-remove. gif were combined into selector-icons.gif; and arrow-up.gif and arrow-down.gif were combined into sorting-icons.gif. If you used those icons to customize the admin, then you’ll need to replace them with your own icons or get the files from a previous release. CSS class names in admin forms To avoid conflicts with other common CSS class names (e.g. “button”), we added a prefix (“field-”) to all CSS class names automatically generated from the form field names in the main admin forms, stacked inline forms and tabular

9.1. Final releases

1629

Django Documentation, Release 2.1.dev20171115023625

inline cells. You’ll need to take that prefix into account in your custom style sheets or JavaScript files if you previously used plain field names as selectors for custom styles or JavaScript transformations. Compatibility with old signed data Django 1.3 changed the cryptographic signing mechanisms used in a number of places in Django. While Django 1.3 kept fallbacks that would accept hashes produced by the previous methods, these fallbacks are removed in Django 1.4. So, if you upgrade to Django 1.4 directly from 1.2 or earlier, you may lose/invalidate certain pieces of data that have been cryptographically signed using an old method. To avoid this, use Django 1.3 first for a period of time to allow the signed data to expire naturally. The affected parts are detailed below, with 1) the consequences of ignoring this advice and 2) the amount of time you need to run Django 1.3 for the data to expire or become irrelevant. • contrib.sessions data integrity check – Consequences: The user will be logged out, and session data will be lost. – Time period: Defined by SESSION_COOKIE_AGE. • contrib.auth password reset hash – Consequences: Password reset links from before the upgrade will not work. – Time period: Defined by PASSWORD_RESET_TIMEOUT_DAYS. Form-related hashes: these have a are much shorter lifetime and are relevant only for the short window where a user might fill in a form generated by the pre-upgrade Django instance and try to submit it to the upgraded Django instance: • contrib.comments form security hash – Consequences: The user will see the validation error “Security hash failed.” – Time period: The amount of time you expect users to take filling out comment forms. • FormWizard security hash – Consequences: The user will see an error about the form having expired and will be sent back to the first page of the wizard, losing the data entered so far. – Time period: The amount of time you expect users to take filling out the affected forms. • CSRF check – Note: This is actually a Django 1.1 fallback, not Django 1.2, and it applies only if you’re upgrading from 1.1. – Consequences: The user will see a 403 error with any CSRF-protected POST form. – Time period: The amount of time you expect user to take filling out such forms. • contrib.auth user password hash-upgrade sequence – Consequences: Each user’s password will be updated to a stronger password hash when it’s written to the database in 1.4. This means that if you upgrade to 1.4 and then need to downgrade to 1.3, version 1.3 won’t be able to read the updated passwords. – Remedy: Set PASSWORD_HASHERS to use your original password hashing when you initially upgrade to 1.4. After you confirm your app works well with Django 1.4 and you won’t have to roll back to 1.3, enable the new password hashes.

1630

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

django.contrib.flatpages Starting in 1.4, the FlatpageFallbackMiddleware only adds a trailing slash and redirects if the resulting URL refers to an existing flatpage. For example, requesting /notaflatpageoravalidurl in a previous version would redirect to /notaflatpageoravalidurl/, which would subsequently raise a 404. Requesting / notaflatpageoravalidurl now will immediately raise a 404. Also, redirects returned by flatpages are now permanent (with 301 status code), to match the behavior of CommonMiddleware. Serialization of datetime and time As a consequence of time-zone support, and according to the ECMA-262 specification, we made changes to the JSON serializer: • It includes the time zone for aware datetime objects. It raises an exception for aware time objects. • It includes milliseconds for datetime and time objects. There is still some precision loss, because Python stores microseconds (6 digits) and JSON only supports milliseconds (3 digits). However, it’s better than discarding microseconds entirely. We changed the XML serializer to use the ISO8601 format for datetimes. The letter T is used to separate the date part from the time part, instead of a space. Time zone information is included in the [+-]HH:MM format. Though the serializers now use these new formats when creating fixtures, they can still load fixtures that use the old format. supports_timezone changed to False for SQLite The database feature supports_timezone used to be True for SQLite. Indeed, if you saved an aware datetime object, SQLite stored a string that included an UTC offset. However, this offset was ignored when loading the value back from the database, which could corrupt the data. In the context of time-zone support, this flag was changed to False, and datetimes are now stored without time-zone information in SQLite. When USE_TZ is False, if you attempt to save an aware datetime object, Django raises an exception. MySQLdb-specific exceptions The MySQL backend historically has raised MySQLdb.OperationalError when a query triggered an exception. We’ve fixed this bug, and we now raise django.db.DatabaseError instead. If you were testing for MySQLdb. OperationalError, you’ll need to update your except clauses. Database connection’s thread-locality DatabaseWrapper objects (i.e. the connection objects referenced by django.db.connection and django. db.connections["some_alias"]) used to be thread-local. They are now global objects in order to be potentially shared between multiple threads. While the individual connection objects are now global, the django. db.connections dictionary referencing those objects is still thread-local. Therefore if you just use the ORM or DatabaseWrapper.cursor() then the behavior is still the same as before. Note, however, that django. db.connection does not directly reference the default DatabaseWrapper object anymore and is now a proxy to access that object’s attributes. If you need to access the actual DatabaseWrapper object, use django.db. connections[DEFAULT_DB_ALIAS] instead. 9.1. Final releases

1631

Django Documentation, Release 2.1.dev20171115023625

As part of this change, all underlying SQLite connections are now enabled for potential thread-sharing (by passing the check_same_thread=False attribute to pysqlite). DatabaseWrapper however preserves the previous behavior by disabling thread-sharing by default, so this does not affect any existing code that purely relies on the ORM or on DatabaseWrapper.cursor(). Finally, while it’s now possible to pass connections between threads, Django doesn’t make any effort to synchronize access to the underlying backend. Concurrency behavior is defined by the underlying backend implementation. Check their documentation for details. COMMENTS_BANNED_USERS_GROUP setting Django’s comments has historically supported excluding the comments of a special user group, but we’ve never documented the feature properly and didn’t enforce the exclusion in other parts of the app such as the template tags. To fix this problem, we removed the code from the feed class. If you rely on the feature and want to restore the old behavior, use a custom comment model manager to exclude the user group, like this: from django.conf import settings from django.contrib.comments.managers import CommentManager class BanningCommentManager(CommentManager): def get_query_set(self): qs = super().get_query_set() if getattr(settings, 'COMMENTS_BANNED_USERS_GROUP', None): where = ['user_id NOT IN (SELECT user_id FROM auth_user_groups WHERE ˓→group_id = %s)'] params = [settings.COMMENTS_BANNED_USERS_GROUP] qs = qs.extra(where=where, params=params) return qs

Save this model manager in your custom comment app (e.g., in my_comments_app/managers.py) and add it your custom comment app model: from django.db import models from django.contrib.comments.models import Comment from my_comments_app.managers import BanningCommentManager class CommentWithTitle(Comment): title = models.CharField(max_length=300) objects = BanningCommentManager()

IGNORABLE_404_STARTS and IGNORABLE_404_ENDS settings Until Django 1.3, it was possible to exclude some URLs from Django’s 404 error reporting by adding prefixes to IGNORABLE_404_STARTS and suffixes to IGNORABLE_404_ENDS. In Django 1.4, these two settings are superseded by IGNORABLE_404_URLS, which is a list of compiled regular expressions. Django won’t send an email for 404 errors on URLs that match any of them. Furthermore, the previous settings had some rather arbitrary default values:

1632

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

IGNORABLE_404_STARTS = ('/cgi-bin/', '/_vti_bin', '/_vti_inf') IGNORABLE_404_ENDS = ('mail.pl', 'mailform.pl', 'mail.cgi', 'mailform.cgi', 'favicon.ico', '.php')

It’s not Django’s role to decide if your website has a legacy /cgi-bin/ section or a favicon. ico. As a consequence, the default values of IGNORABLE_404_URLS, IGNORABLE_404_STARTS, and IGNORABLE_404_ENDS are all now empty. If you have customized IGNORABLE_404_STARTS or IGNORABLE_404_ENDS, or if you want to keep the old default value, you should add the following lines in your settings file: import re IGNORABLE_404_URLS = ( # for each in IGNORABLE_404_STARTS re.compile(r'^'), # for each in IGNORABLE_404_ENDS re.compile(r'$'), )

Don’t forget to escape characters that have a special meaning in a regular expression, such as periods. CSRF protection extended to PUT and DELETE Previously, Django’s CSRF protection provided protection only against POST requests. Since use of PUT and DELETE methods in AJAX applications is becoming more common, we now protect all methods not defined as safe by RFC 2616 – i.e., we exempt GET, HEAD, OPTIONS and TRACE, and we enforce protection on everything else. If you’re using PUT or DELETE methods in AJAX applications, please see the instructions about using AJAX and CSRF. Password reset view now accepts subject_template_name The password_reset view in django.contrib.auth now accepts a subject_template_name parameter, which is passed to the password save form as a keyword argument. If you are using this view with a custom password reset form, then you will need to ensure your form’s save() method accepts this keyword argument. django.core.template_loaders This was an alias to django.template.loader since 2005, and we’ve removed it without emitting a warning due to the length of the deprecation. If your code still referenced this, please use django.template.loader instead. django.db.models.fields.URLField.verify_exists This functionality has been removed due to intractable performance and security issues. Any existing usage of verify_exists should be removed.

9.1. Final releases

1633

Django Documentation, Release 2.1.dev20171115023625

django.core.files.storage.Storage.open The open method of the base Storage class used to take an obscure parameter mixin that allowed you to dynamically change the base classes of the returned file object. This has been removed. In the rare case you relied on the mixin parameter, you can easily achieve the same by overriding the open method, like this: from django.core.files import File from django.core.files.storage import FileSystemStorage class Spam(File): """ Spam, spam, spam, spam and spam. """ def ham(self): return 'eggs' class SpamStorage(FileSystemStorage): """ A custom file storage backend. """ def open(self, name, mode='rb'): return Spam(open(self.path(name), mode))

YAML deserializer now uses yaml.safe_load yaml.load is able to construct any Python object, which may trigger arbitrary code execution if you process a YAML document that comes from an untrusted source. This feature isn’t necessary for Django’s YAML deserializer, whose primary use is to load fixtures consisting of simple objects. Even though fixtures are trusted data, the YAML deserializer now uses yaml.safe_load for additional security. Session cookies now have the httponly flag by default Session cookies now include the httponly attribute by default to help reduce the impact of potential XSS attacks. As a consequence of this change, session cookie data, including sessionid, is no longer accessible from JavaScript in many browsers. For strict backwards compatibility, use SESSION_COOKIE_HTTPONLY = False in your settings file. The urlize filter no longer escapes every URL When a URL contains a %xx sequence, where xx are two hexadecimal digits, urlize now assumes that the URL is already escaped and doesn’t apply URL escaping again. This is wrong for URLs whose unquoted form contains a %xx sequence, but such URLs are very unlikely to happen in the wild, because they would confuse browsers too. assertTemplateUsed and assertTemplateNotUsed as context manager It’s now possible to check whether a template was used within a block of code with assertTemplateUsed() and assertTemplateNotUsed(). And they can be used as a context manager: with self.assertTemplateUsed('index.html'): render_to_string('index.html')

1634

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

with self.assertTemplateNotUsed('base.html'): render_to_string('index.html')

See the assertion documentation for more. Database connections after running the test suite The default test runner no longer restores the database connections after tests’ execution. This prevents the production database from being exposed to potential threads that would still be running and attempting to create new connections. If your code relied on connections to the production database being created after tests’ execution, then you can restore the previous behavior by subclassing DjangoTestRunner and overriding its teardown_databases() method. Output of manage.py help manage.py help now groups available commands by application. If you depended on the output of this command – if you parsed it, for example – then you’ll need to update your code. To get a list of all available management commands in a script, use manage.py help --commands instead. extends template tag Previously, the extends tag used a buggy method of parsing arguments, which could lead to it erroneously considering an argument as a string literal when it wasn’t. It now uses parser.compile_filter, like other tags. The internals of the tag aren’t part of the official stable API, but in the interests of full disclosure, the ExtendsNode. __init__ definition has changed, which may break any custom tags that use this class. Loading some incomplete fixtures no longer works Prior to 1.4, a default value was inserted for fixture objects that were missing a specific date or datetime value when auto_now or auto_now_add was set for the field. This was something that should not have worked, and in 1.4 loading such incomplete fixtures will fail. Because fixtures are a raw import, they should explicitly specify all field values, regardless of field options on the model. Development Server Multithreading The development server is now is multithreaded by default. Use the runserver --nothreading option to disable the use of threading in the development server: django-admin.py runserver --nothreading

Attributes disabled in markdown when safe mode set Prior to Django 1.4, attributes were included in any markdown output regardless of safe mode setting of the filter. With version > 2.1 of the Python-Markdown library, an enable_attributes option was added. When the safe argument is passed to the markdown filter, both the safe_mode=True and enable_attributes=False options are set. If using a version of the Python-Markdown library less than 2.1, a warning is issued that the output is insecure.

9.1. Final releases

1635

Django Documentation, Release 2.1.dev20171115023625

FormMixin get_initial returns an instance-specific dictionary In Django 1.3, the get_initial method of the django.views.generic.edit.FormMixin class was returning the class initial dictionary. This has been fixed to return a copy of this dictionary, so form instances can modify their initial data without messing with the class variable. Features deprecated in 1.4 Old styles of calling cache_page decorator Some legacy ways of calling cache_page() have been deprecated. Please see the documentation for the correct way to use this decorator. Support for PostgreSQL versions older than 8.2 Django 1.3 dropped support for PostgreSQL versions older than 8.0, and we suggested using a more recent version because of performance improvements and, more importantly, the end of upstream support periods for 8.0 and 8.1 was near (November 2010). Django 1.4 takes that policy further and sets 8.2 as the minimum PostgreSQL version it officially supports. Request exceptions are now always logged When we added logging support in Django in 1.3, the admin error email support was moved into the django. utils.log.AdminEmailHandler, attached to the 'django.request' logger. In order to maintain the established behavior of error emails, the 'django.request' logger was called only when DEBUG was False. To increase the flexibility of error logging for requests, the 'django.request' logger is now called regardless of the value of DEBUG, and the default settings file for new projects now includes a separate filter attached to django. utils.log.AdminEmailHandler to prevent admin error emails in DEBUG mode: 'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse' } }, 'handlers': { 'mail_admins': { 'level': 'ERROR', 'filters': ['require_debug_false'], 'class': 'django.utils.log.AdminEmailHandler' } },

If your project was created prior to this change, your LOGGING setting will not include this new filter. In order to maintain backwards-compatibility, Django will detect that your 'mail_admins' handler configuration includes no 'filters' section and will automatically add this filter for you and issue a pending-deprecation warning. This will become a deprecation warning in Django 1.5, and in Django 1.6 the backwards-compatibility shim will be removed entirely. The existence of any 'filters' key under the 'mail_admins' handler will disable this backward-compatibility shim and deprecation warning.

1636

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

django.conf.urls.defaults Until Django 1.3, the include(), patterns(), and url() functions, plus handler404 and handler500 were located in a django.conf.urls.defaults module. In Django 1.4, they live in django.conf.urls. django.contrib.databrowse Databrowse has not seen active development for some time, and this does not show any sign of changing. There had been a suggestion for a GSOC project to integrate the functionality of databrowse into the admin, but no progress was made. While Databrowse has been deprecated, an enhancement of django.contrib.admin providing a similar feature set is still possible. The code that powers Databrowse is licensed under the same terms as Django itself, so it’s available to be adopted by an individual or group as a third-party project. django.core.management.setup_environ This function temporarily modified sys.path in order to make the parent “project” directory importable under the old flat startproject layout. This function is now deprecated, as its path workarounds are no longer needed with the new manage.py and default project layout. This function was never documented or part of the public API, but it was widely recommended for use in setting up a “Django environment” for a user script. These uses should be replaced by setting the DJANGO_SETTINGS_MODULE environment variable or using django.conf.settings.configure(). django.core.management.execute_manager This function was previously used by manage.py to execute a management command. It is identical to django. core.management.execute_from_command_line, except that it first calls setup_environ, which is now deprecated. As such, execute_manager is also deprecated; execute_from_command_line can be used instead. Neither of these functions is documented as part of the public API, but a deprecation path is needed due to use in existing manage.py files. is_safe and needs_autoescape attributes of template filters Two flags, is_safe and needs_autoescape, define how each template filter interacts with Django’s autoescaping behavior. They used to be attributes of the filter function: @register.filter def noop(value): return value noop.is_safe = True

However, this technique caused some problems in combination with decorators, especially @stringfilter. Now, the flags are keyword arguments of @register.filter: @register.filter(is_safe=True) def noop(value): return value

9.1. Final releases

1637

Django Documentation, Release 2.1.dev20171115023625

See filters and auto-escaping for more information. Wildcard expansion of application names in INSTALLED_APPS Until Django 1.3, INSTALLED_APPS accepted wildcards in application names, like django.contrib.*. The expansion was performed by a filesystem-based implementation of from import *. Unfortunately, this can’t be done reliably. This behavior was never documented. Since it is unpythonic and not obviously useful, it was removed in Django 1.4. If you relied on it, you must edit your settings file to list all your applications explicitly. HttpRequest.raw_post_data renamed to HttpRequest.body This attribute was confusingly named HttpRequest.raw_post_data, but it actually provided the body of the HTTP request. It’s been renamed to HttpRequest.body, and HttpRequest.raw_post_data has been deprecated. django.contrib.sitemaps bug fix with potential performance implications In previous versions, Paginator objects used in sitemap classes were cached, which could result in stale site maps. We’ve removed the caching, so each request to a site map now creates a new Paginator object and calls the items() method of the Sitemap subclass. Depending on what your items() method is doing, this may have a negative performance impact. To mitigate the performance impact, consider using the caching framework within your Sitemap subclass. Versions of Python-Markdown earlier than 2.1 Versions of Python-Markdown earlier than 2.1 do not support the option to disable attributes. As a security issue, earlier versions of this library will not be supported by the markup contrib app in 1.5 under an accelerated deprecation timeline.

9.1.11 1.3 release Django 1.3.7 release notes February 20, 2013 Django 1.3.7 corrects a packaging problem with yesterday’s 1.3.6 release. The release contained stray .pyc files that caused “bad magic number” errors when running with some versions of Python. This releases corrects this, and also fixes a bad documentation link in the project template settings.py file generated by manage.py startproject. Django 1.3.6 release notes February 19, 2013 Django 1.3.6 fixes four security issues present in previous Django releases in the 1.3 series. This is the sixth bugfix/security release in the Django 1.3 series.

1638

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Host header poisoning Some parts of Django – independent of end-user-written applications – make use of full URLs, including domain name, which are generated from the HTTP Host header. Django’s documentation has for some time contained notes advising users on how to configure Web servers to ensure that only valid Host headers can reach the Django application. However, it has been reported to us that even with the recommended Web server configurations there are still techniques available for tricking many common Web servers into supplying the application with an incorrect and possibly malicious Host header. For this reason, Django 1.3.6 adds a new setting, ALLOWED_HOSTS, which should contain an explicit list of valid host/domain names for this site. A request with a Host header not matching an entry in this list will raise SuspiciousOperation if request.get_host() is called. For full details see the documentation for the ALLOWED_HOSTS setting. The default value for this setting in Django 1.3.6 is ['*'] (matching any host), for backwards-compatibility, but we strongly encourage all sites to set a more restrictive value. This host validation is disabled when DEBUG is True or when running tests. XML deserialization The XML parser in the Python standard library is vulnerable to a number of attacks via external entities and entity expansion. Django uses this parser for deserializing XML-formatted database fixtures. The fixture deserializer is not intended for use with untrusted data, but in order to err on the side of safety in Django 1.3.6 the XML deserializer refuses to parse an XML document with a DTD (DOCTYPE definition), which closes off these attack avenues. These issues in the Python standard library are CVE-2013-1664 and CVE-2013-1665. More information available from the Python security team. Django’s XML serializer does not create documents with a DTD, so this should not cause any issues with the typical round-trip from dumpdata to loaddata, but if you feed your own XML documents to the loaddata management command, you will need to ensure they do not contain a DTD. Formset memory exhaustion Previous versions of Django did not validate or limit the form-count data provided by the client in a formset’s management form, making it possible to exhaust a server’s available memory by forcing it to create very large numbers of forms. In Django 1.3.6, all formsets have a strictly-enforced maximum number of forms (1000 by default, though it can be set higher via the max_num formset factory argument). Admin history view information leakage In previous versions of Django, an admin user without change permission on a model could still view the unicode representation of instances via their admin history log. Django 1.3.6 now limits the admin history log view for an object to users with change permission for that model. Django 1.3.5 release notes December 10, 2012 Django 1.3.5 addresses two security issues present in previous Django releases in the 1.3 series.

9.1. Final releases

1639

Django Documentation, Release 2.1.dev20171115023625

Please be aware that this security release is slightly different from previous ones. Both issues addressed here have been dealt with in prior security updates to Django. In one case, we have received ongoing reports of problems, and in the other we’ve chosen to take further steps to tighten up Django’s code in response to independent discovery of potential problems from multiple sources. Host header poisoning Several earlier Django security releases focused on the issue of poisoning the HTTP Host header, causing Django to generate URLs pointing to arbitrary, potentially-malicious domains. In response to further input received and reports of continuing issues following the previous release, we’re taking additional steps to tighten Host header validation. Rather than attempt to accommodate all features HTTP supports here, Django’s Host header validation attempts to support a smaller, but far more common, subset: • Hostnames must consist of characters [A-Za-z0-9] plus hyphen (‘-‘) or dot (‘.’). • IP addresses – both IPv4 and IPv6 – are permitted. • Port, if specified, is numeric. Any deviation from this will now be rejected, raising the exception django.core.exceptions. SuspiciousOperation. Redirect poisoning Also following up on a previous issue: in July of this year, we made changes to Django’s HTTP redirect classes, performing additional validation of the scheme of the URL to redirect to (since, both within Django’s own supplied applications and many third-party applications, accepting a user-supplied redirect target is a common pattern). Since then, two independent audits of the code turned up further potential problems. So, similar to the Host-header issue, we are taking steps to provide tighter validation in response to reported problems (primarily with third-party applications, but to a certain extent also within Django itself). This comes in two parts: 1. A new utility function, django.utils.http.is_safe_url, is added; this function takes a URL and a hostname, and checks that the URL is either relative, or if absolute matches the supplied hostname. This function is intended for use whenever user-supplied redirect targets are accepted, to ensure that such redirects cannot lead to arbitrary third-party sites. 2. All of Django’s own built-in views – primarily in the authentication system – which allow user-supplied redirect targets now use is_safe_url to validate the supplied URL. Django 1.3.4 release notes October 17, 2012 This is the fourth release in the Django 1.3 series. Host header poisoning Some parts of Django – independent of end-user-written applications – make use of full URLs, including domain name, which are generated from the HTTP Host header. Some attacks against this are beyond Django’s ability to control, and require the web server to be properly configured; Django’s documentation has for some time contained notes advising users on such configuration.

1640

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Django’s own built-in parsing of the Host header is, however, still vulnerable, as was reported to us recently. The Host header parsing in Django 1.3.3 and Django 1.4.1 – specifically, django.http.HttpRequest.get_host() – was incorrectly handling username/password information in the header. Thus, for example, the following Host header would be accepted by Django when running on “validsite.com”: Host: validsite.com:[emailprotected]

Using this, an attacker can cause parts of Django – particularly the password-reset mechanism – to generate and display arbitrary URLs to users. To remedy this, the parsing in HttpRequest.get_host() is being modified; Host headers which contain potentially dangerous content (such as username/password pairs) now raise the exception django.core.exceptions. SuspiciousOperation. Details of this issue were initially posted online as a security advisory. Django 1.3.3 release notes August 1, 2012 Following Monday’s security release of Django 1.3.2, we began receiving reports that one of the fixes applied was breaking Python 2.4 compatibility for Django 1.3. Since Python 2.4 is a supported Python version for that release series, this release fixes compatibility with Python 2.4. Django 1.3.2 release notes July 30, 2012 This is the second security release in the Django 1.3 series, fixing several security issues in Django 1.3. Django 1.3.2 is a recommended upgrade for all users of Django 1.3. For a full list of issues addressed in this release, see the security advisory. Django 1.3.1 release notes September 9, 2011 Welcome to Django 1.3.1! This is the first security release in the Django 1.3 series, fixing several security issues in Django 1.3. Django 1.3.1 is a recommended upgrade for all users of Django 1.3. For a full list of issues addressed in this release, see the security advisory. Django 1.3 release notes March 23, 2011 Welcome to Django 1.3! Nearly a year in the making, Django 1.3 includes quite a few new features and plenty of bug fixes and improvements to existing features. These release notes cover the new features in 1.3, as well as some backwards-incompatible changes you’ll want to be aware of when upgrading from Django 1.2 or older versions.

9.1. Final releases

1641

(Video) 10 Reasons To Use Python Django

Django Documentation, Release 2.1.dev20171115023625

Overview Django 1.3’s focus has mostly been on resolving smaller, long-standing feature requests, but that hasn’t prevented a few fairly significant new features from landing, including: • A framework for writing class-based views. • Built-in support for using Python’s logging facilities. • Contrib support for easy handling of static files. • Django’s testing framework now supports (and ships with a copy of) the unittest2 library. Wherever possible, of course, new features are introduced in a backwards-compatible manner per our API stability policy policy. As a result of this policy, Django 1.3 begins the deprecation process for some features. Python compatibility The release of Django 1.2 was notable for having the first shift in Django’s Python compatibility policy; prior to Django 1.2, Django supported any 2.x version of Python from 2.3 up. As of Django 1.2, the minimum requirement was raised to Python 2.4. Django 1.3 continues to support Python 2.4, but will be the final Django release series to do so; beginning with Django 1.4, the minimum supported Python version will be 2.5. A document outlining our full timeline for deprecating Python 2.x and moving to Python 3.x will be published shortly after the release of Django 1.3. What’s new in Django 1.3 Class-based views Django 1.3 adds a framework that allows you to use a class as a view. This means you can compose a view out of a collection of methods that can be subclassed and overridden to provide common views of data without having to write too much code. Analogs of all the old function-based generic views have been provided, along with a completely generic view base class that can be used as the basis for reusable applications that can be easily extended. See the documentation on class-based generic views for more details. There is also a document to help you convert your function-based generic views to class-based views. Logging Django 1.3 adds framework-level support for Python’s logging module. This means you can now easily configure and control logging as part of your Django project. A number of logging handlers and logging calls have been added to Django’s own code as well – most notably, the error emails sent on a HTTP 500 server error are now handled as a logging activity. See the documentation on Django’s logging interface for more details. Extended static files handling Django 1.3 ships with a new contrib app – django.contrib.staticfiles – to help developers handle the static media files (images, CSS, JavaScript, etc.) that are needed to render a complete web page. In previous versions of Django, it was common to place static assets in MEDIA_ROOT along with user-uploaded files, and serve them both at MEDIA_URL. Part of the purpose of introducing the staticfiles app is to make it easier 1642

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

to keep static files separate from user-uploaded files. Static assets should now go in static/ subdirectories of your apps or in other static assets directories listed in STATICFILES_DIRS, and will be served at STATIC_URL. See the reference documentation of the app for more details or learn how to manage static files. unittest2 support Python 2.7 introduced some major changes to the unittest library, adding some extremely useful features. To ensure that every Django project can benefit from these new features, Django ships with a copy of unittest2, a copy of the Python 2.7 unittest library, backported for Python 2.4 compatibility. To access this library, Django provides the django.utils.unittest module alias. If you are using Python 2.7, or you have installed unittest2 locally, Django will map the alias to the installed version of the unittest library. Otherwise, Django will use its own bundled version of unittest2. To take advantage of this alias, simply use: from django.utils import unittest

wherever you would have historically used: import unittest

If you want to continue to use the base unittest library, you can – you just won’t get any of the nice new unittest2 features. Transaction context managers Users of Python 2.5 and above may now use transaction management functions as context managers. For example: with transaction.autocommit(): # ...

Configurable delete-cascade ForeignKey and OneToOneField now accept an on_delete argument to customize behavior when the referenced object is deleted. Previously, deletes were always cascaded; available alternatives now include set null, set default, set to any value, protect, or do nothing. For more information, see the on_delete documentation. Contextual markers and comments for translatable strings For translation strings with ambiguous meaning, you can now use the pgettext function to specify the context of the string. And if you just want to add some information for translators, you can also add special translator comments in the source. For more information, see Contextual markers and Comments for translators.

9.1. Final releases

1643

Django Documentation, Release 2.1.dev20171115023625

Improvements to built-in template tags A number of improvements have been made to Django’s built-in template tags: • The include tag now accepts a with option, allowing you to specify context variables to the included template • The include tag now accepts an only option, allowing you to exclude the current context from the included context • The with tag now allows you to define multiple context variables in a single with block. • The load tag now accepts a from argument, allowing you to load a single tag or filter from a library. TemplateResponse It can sometimes be beneficial to allow decorators or middleware to modify a response after it has been constructed by the view. For example, you may want to change the template that is used, or put additional data into the context. However, you can’t (easily) modify the content of a basic HttpResponse after it has been constructed. To overcome this limitation, Django 1.3 adds a new TemplateResponse class. Unlike basic HttpResponse objects, TemplateResponse objects retain the details of the template and context that was provided by the view to compute the response. The final output of the response is not computed until it is needed, later in the response process. For more details, see the documentation on the TemplateResponse class. Caching changes Django 1.3 sees the introduction of several improvements to the Django’s caching infrastructure. Firstly, Django now supports multiple named caches. In the same way that Django 1.2 introduced support for multiple database connections, Django 1.3 allows you to use the new CACHES setting to define multiple named cache connections. Secondly, versioning, site-wide prefixing and transformation have been added to the cache API. Thirdly, cache key creation has been updated to take the request query string into account on GET requests. Finally, support for pylibmc has been added to the memcached cache backend. For more details, see the documentation on caching in Django. Permissions for inactive users If you provide a custom auth backend with supports_inactive_user set to True, an inactive User instance will check the backend for permissions. This is useful for further centralizing the permission handling. See the authentication docs for more details. GeoDjango The GeoDjango test suite is now included when running the Django test suite with runtests.py when using spatial database backends.

1644

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

MEDIA_URL and STATIC_URL must end in a slash Previously, the MEDIA_URL setting only required a trailing slash if it contained a suffix beyond the domain name. A trailing slash is now required for MEDIA_URL and the new STATIC_URL setting as long as it is not blank. This ensures there is a consistent way to combine paths in templates. Project settings which provide either of both settings without a trailing slash will now raise a PendingDeprecationWarning. In Django 1.4 this same condition will raise DeprecationWarning, and in Django 1.5 will raise an ImproperlyConfigured exception. Everything else Django 1.1 and 1.2 added lots of big ticket items to Django, like multiple-database support, model validation, and a session-based messages framework. However, this focus on big features came at the cost of lots of smaller features. To compensate for this, the focus of the Django 1.3 development process has been on adding lots of smaller, long standing feature requests. These include: • Improved tools for accessing and manipulating the current Site object in the sites framework. • A RequestFactory for mocking requests in tests. • A new test assertion – assertNumQueries() – making it easier to test the database activity associated with a view. • Support for lookups spanning relations in admin’s list_filter. • Support for HTTPOnly cookies. • mail_admins() and mail_managers() now support easily attaching HTML content to messages. • EmailMessage now supports CC’s. • Error emails now include more of the detail and formatting of the debug server error page. • simple_tag() now accepts a takes_context argument, making it easier to write simple template tags that require access to template context. • A new render() shortcut – an alternative to django.shortcuts.render_to_response() providing a RequestContext by default. • Support for combining F expressions with timedelta values when retrieving or updating database values. Backwards-incompatible changes in 1.3 CSRF validation now applies to AJAX requests Prior to Django 1.2.5, Django’s CSRF-prevention system exempted AJAX requests from CSRF verification; due to security issues reported to us, however, all requests are now subjected to CSRF verification. Consult the Django CSRF documentation for details on how to handle CSRF verification in AJAX requests.

9.1. Final releases

1645

Django Documentation, Release 2.1.dev20171115023625

Restricted filters in admin interface Prior to Django 1.2.5, the Django administrative interface allowed filtering on any model field or relation – not just those specified in list_filter – via query string manipulation. Due to security issues reported to us, however, query string lookup arguments in the admin must be for fields or relations specified in list_filter or date_hierarchy. Deleting a model doesn’t delete associated files In earlier Django versions, when a model instance containing a FileField was deleted, FileField took it upon itself to also delete the file from the backend storage. This opened the door to several data-loss scenarios, including rolled-back transactions and fields on different models referencing the same file. In Django 1.3, when a model is deleted the FileField’s delete() method won’t be called. If you need cleanup of orphaned files, you’ll need to handle it yourself (for instance, with a custom management command that can be run manually or scheduled to run periodically via e.g. cron). PasswordInput default rendering behavior The PasswordInput form widget, intended for use with form fields which represent passwords, accepts a boolean keyword argument render_value indicating whether to send its data back to the browser when displaying a submitted form with errors. Prior to Django 1.3, this argument defaulted to True, meaning that the submitted password would be sent back to the browser as part of the form. Developers who wished to add a bit of additional security by excluding that value from the redisplayed form could instantiate a PasswordInput passing render_value=False . Due to the sensitive nature of passwords, however, Django 1.3 takes this step automatically; the default value of render_value is now False, and developers who want the password value returned to the browser on a submission with errors (the previous behavior) must now explicitly indicate this. For example: class LoginForm(forms.Form): username = forms.CharField(max_length=100) password = forms.CharField(widget=forms.PasswordInput(render_value=True))

Clearable default widget for FileField Django 1.3 now includes a ClearableFileInput form widget in addition to FileInput. ClearableFileInput renders with a checkbox to clear the field’s value (if the field has a value and is not required); FileInput provided no means for clearing an existing file from a FileField. ClearableFileInput is now the default widget for a FileField, so existing forms including FileField without assigning a custom widget will need to account for the possible extra checkbox in the rendered form output. To return to the previous rendering (without the ability to clear the FileField), use the FileInput widget in place of ClearableFileInput. For instance, in a ModelForm for a hypothetical Document model with a FileField named document: from django import forms from myapp.models import Document class DocumentForm(forms.ModelForm): class Meta: model = Document widgets = {'document': forms.FileInput}

1646

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

New index on database session table Prior to Django 1.3, the database table used by the database backend for the sessions app had no index on the expire_date column. As a result, date-based queries on the session table – such as the query that is needed to purge old sessions – would be very slow if there were lots of sessions. If you have an existing project that is using the database session backend, you don’t have to do anything to accommodate this change. However, you may get a significant performance boost if you manually add the new index to the session table. The SQL that will add the index can be found by running the sqlindexes admin command: python manage.py sqlindexes sessions

No more naughty words Django has historically provided (and enforced) a list of profanities. The comments app has enforced this list of profanities, preventing people from submitting comments that contained one of those profanities. Unfortunately, the technique used to implement this profanities list was woefully naive, and prone to the Scunthorpe problem. Improving the built-in filter to fix this problem would require significant effort, and since natural language processing isn’t the normal domain of a web framework, we have “fixed” the problem by making the list of prohibited words an empty list. If you want to restore the old behavior, simply put a PROFANITIES_LIST setting in your settings file that includes the words that you want to prohibit (see the commit that implemented this change if you want to see the list of words that was historically prohibited). However, if avoiding profanities is important to you, you would be well advised to seek out a better, less naive approach to the problem. Localflavor changes Django 1.3 introduces the following backwards-incompatible changes to local flavors: • Canada (ca) – The province “Newfoundland and Labrador” has had its province code updated to “NL”, rather than the older “NF”. In addition, the Yukon Territory has had its province code corrected to “YT”, instead of “YK”. • Indonesia (id) – The province “Nanggroe Aceh Darussalam (NAD)” has been removed from the province list in favor of the new official designation “Aceh (ACE)”. • United States of America (us) – The list of “states” used by USStateField has expanded to include Armed Forces postal codes. This is backwards-incompatible if you were relying on USStateField not including them. FormSet updates In Django 1.3 FormSet creation behavior is modified slightly. Historically the class didn’t make a distinction between not being passed data and being passed empty dictionary. This was inconsistent with behavior in other parts of the framework. Starting with 1.3 if you pass in empty dictionary the FormSet will raise a ValidationError. For example with a FormSet: >>> class ArticleForm(Form): ... title = CharField() ... pub_date = DateField() >>> ArticleFormSet = formset_factory(ArticleForm)

9.1. Final releases

1647

Django Documentation, Release 2.1.dev20171115023625

the following code will raise a ValidationError: >>> ArticleFormSet({}) Traceback (most recent call last): ... ValidationError: [u'ManagementForm data is missing or has been tampered with']

if you need to instantiate an empty FormSet, don’t pass in the data or use None: >>> formset = ArticleFormSet() >>> formset = ArticleFormSet(data=None)

Callables in templates Previously, a callable in a template would only be called automatically as part of the variable resolution process if it was retrieved via attribute lookup. This was an inconsistency that could result in confusing and unhelpful behavior: >>> Template("{{ user.get_full_name }}").render(Context({'user': user})) u'Joe Bloggs' >>> Template("{{ full_name }}").render(Context({'full_name': user.get_full_name})) u'>> from django.db.models import get_app, get_models >>> get_models(get_app('gis')) []

1672

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

To get the correct SpatialRefSys and GeometryColumns for your spatial database use the methods provided by the spatial backend: >>> from django.db import connections >>> SpatialRefSys = connections['my_spatialite'].ops.spatial_ref_sys() >>> GeometryColumns = connections['my_postgis'].ops.geometry_columns()

Note: When using the models returned from the spatial_ref_sys() and geometry_columns() method, you’ll still need to use the correct database alias when querying on the non-default connection. In other words, to ensure that the models in the example above use the correct database: sr_qs = SpatialRefSys.objects.using('my_spatialite').filter(...) gc_qs = GeometryColumns.objects.using('my_postgis').filter(...)

Language code no The currently used language code for Norwegian Bokmål no is being replaced by the more common language code nb. Function-based template loaders Django 1.2 changes the template loading mechanism to use a class-based approach. Old style function-based template loaders will still work, but should be updated to use the new class-based template loaders.

9.1.13 1.1 release Django 1.1.4 release notes Welcome to Django 1.1.4! This is the fourth “bugfix” release in the Django 1.1 series, improving the stability and performance of the Django 1.1 codebase. With one exception, Django 1.1.4 maintains backwards compatibility with Django 1.1.3. It also contains a number of fixes and other improvements. Django 1.1.4 is a recommended upgrade for any development or deployment currently using or targeting Django 1.1. For full details on the new features, backwards incompatibilities, and deprecated features in the 1.1 branch, see the Django 1.1 release notes. Backwards incompatible changes CSRF exception for AJAX requests Django includes a CSRF-protection mechanism, which makes use of a token inserted into outgoing forms. Middleware then checks for the token’s presence on form submission, and validates it. Prior to Django 1.2.5, our CSRF protection made an exception for AJAX requests, on the following basis:

9.1. Final releases

1673

Django Documentation, Release 2.1.dev20171115023625

• Many AJAX toolkits add an X-Requested-With header when using XMLHttpRequest. • Browsers have strict same-origin policies regarding XMLHttpRequest. • In the context of a browser, the only way that a custom header of this nature can be added is with XMLHttpRequest. Therefore, for ease of use, we did not apply CSRF checks to requests that appeared to be AJAX on the basis of the X-Requested-With header. The Ruby on Rails web framework had a similar exemption. Recently, engineers at Google made members of the Ruby on Rails development team aware of a combination of browser plugins and redirects which can allow an attacker to provide custom HTTP headers on a request to any website. This can allow a forged request to appear to be an AJAX request, thereby defeating CSRF protection which trusts the same-origin nature of AJAX requests. Michael Koziarski of the Rails team brought this to our attention, and we were able to produce a proof-of-concept demonstrating the same vulnerability in Django’s CSRF handling. To remedy this, Django will now apply full CSRF validation to all requests, regardless of apparent AJAX origin. This is technically backwards-incompatible, but the security risks have been judged to outweigh the compatibility concerns in this case. Additionally, Django will now accept the CSRF token in the custom HTTP header X-CSRFTOKEN, as well as in the form submission itself, for ease of use with popular JavaScript toolkits which allow insertion of custom headers into all AJAX requests. Please see the CSRF docs for example jQuery code that demonstrates this technique, ensuring that you are looking at the documentation for your version of Django, as the exact code necessary is different for some older versions of Django. Django 1.1.3 release notes Welcome to Django 1.1.3! This is the third “bugfix” release in the Django 1.1 series, improving the stability and performance of the Django 1.1 codebase. With one exception, Django 1.1.3 maintains backwards compatibility with Django 1.1.2. It also contains a number of fixes and other improvements. Django 1.1.2 is a recommended upgrade for any development or deployment currently using or targeting Django 1.1. For full details on the new features, backwards incompatibilities, and deprecated features in the 1.1 branch, see the Django 1.1 release notes. Backwards incompatible changes Restricted filters in admin interface The Django administrative interface, django.contrib.admin, supports filtering of displayed lists of objects by fields on the corresponding models, including across database-level relationships. This is implemented by passing lookup arguments in the querystring portion of the URL, and options on the ModelAdmin class allow developers to specify particular fields or relationships which will generate automatic links for filtering. One historically-undocumented and -unofficially-supported feature has been the ability for a user with sufficient knowledge of a model’s structure and the format of these lookup arguments to invent useful new filters on the fly by manipulating the querystring.

1674

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

However, it has been demonstrated that this can be abused to gain access to information outside of an admin user’s permissions; for example, an attacker with access to the admin and sufficient knowledge of model structure and relations could construct query strings which – with repeated use of regular-expression lookups supported by the Django database API – expose sensitive information such as users’ password hashes. To remedy this, django.contrib.admin will now validate that querystring lookup arguments either specify only fields on the model being viewed, or cross relations which have been explicitly whitelisted by the application developer using the pre-existing mechanism mentioned above. This is backwards-incompatible for any users relying on the prior ability to insert arbitrary lookups. Django 1.1.2 release notes Welcome to Django 1.1.2! This is the second “bugfix” release in the Django 1.1 series, improving the stability and performance of the Django 1.1 codebase. Django 1.1.2 maintains backwards compatibility with Django 1.1.0, but contain a number of fixes and other improvements. Django 1.1.2 is a recommended upgrade for any development or deployment currently using or targeting Django 1.1. For full details on the new features, backwards incompatibilities, and deprecated features in the 1.1 branch, see the Django 1.1 release notes. Backwards-incompatible changes in 1.1.2 Test runner exit status code The exit status code of the test runners (tests/runtests.py and python manage.py test) no longer represents the number of failed tests, since a failure of 256 or more tests resulted in a wrong exit status code. The exit status code for the test runner is now 0 for success (no failing tests) and 1 for any number of test failures. If needed, the number of test failures can be found at the end of the test runner’s output. Cookie encoding To fix bugs with cookies in Internet Explorer, Safari, and possibly other browsers, our encoding of cookie values was changed so that the characters comma and semi-colon are treated as non-safe characters, and are therefore encoded as \054 and \073 respectively. This could produce backwards incompatibilities, especially if you are storing comma or semi-colon in cookies and have JavaScript code that parses and manipulates cookie values client-side. One new feature Ordinarily, a point release would not include new features, but in the case of Django 1.1.2, we have made an exception to this rule. Django 1.2 (the next major release of Django) will contain a feature that will improve protection against Cross-Site Request Forgery (CSRF) attacks. This feature requires the use of a new csrf_token template tag in all forms that Django renders. To make it easier to support both 1.1.X and 1.2.X versions of Django with the same templates, we have decided to introduce the csrf_token template tag to the 1.1.X branch. In the 1.1.X branch, csrf_token does nothing - it has no effect on templates or form processing. However, it means that the same template will work with Django 1.2.

9.1. Final releases

1675

Django Documentation, Release 2.1.dev20171115023625

Django 1.1 release notes July 29, 2009 Welcome to Django 1.1! Django 1.1 includes a number of nifty new features, lots of bug fixes, and an easy upgrade path from Django 1.0. Backwards-incompatible changes in 1.1 Django has a policy of API stability. This means that, in general, code you develop against Django 1.0 should continue to work against 1.1 unchanged. However, we do sometimes make backwards-incompatible changes if they’re necessary to resolve bugs, and there are a handful of such (minor) changes between Django 1.0 and Django 1.1. Before upgrading to Django 1.1 you should double-check that the following changes don’t impact you, and upgrade your code if they do. Changes to constraint names Django 1.1 modifies the method used to generate database constraint names so that names are consistent regardless of machine word size. This change is backwards incompatible for some users. If you are using a 32-bit platform, you’re off the hook; you’ll observe no differences as a result of this change. However, users on 64-bit platforms may experience some problems using the reset management command. Prior to this change, 64-bit platforms would generate a 64-bit, 16 character digest in the constraint name; for example: ALTER TABLE myapp_sometable ADD CONSTRAINT object_id_refs_id_5e8f10c132091d1e FOREIGN ˓→KEY ...

Following this change, all platforms, regardless of word size, will generate a 32-bit, 8 character digest in the constraint name; for example: ALTER TABLE myapp_sometable ADD CONSTRAINT object_id_refs_id_32091d1e FOREIGN KEY ...

As a result of this change, you will not be able to use the reset management command on any table made by a 64-bit machine. This is because the new generated name will not match the historically generated name; as a result, the SQL constructed by the reset command will be invalid. If you need to reset an application that was created with 64-bit constraints, you will need to manually drop the old constraint prior to invoking reset. Test cases are now run in a transaction Django 1.1 runs tests inside a transaction, allowing better test performance (see test performance improvements for details). This change is slightly backwards incompatible if existing tests need to test transactional behavior, if they rely on invalid assumptions about the test environment, or if they require a specific test case ordering. For these cases, TransactionTestCase can be used instead. This is a just a quick fix to get around test case errors revealed by the new rollback approach; in the long-term tests should be rewritten to correct the test case.

1676

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Removed SetRemoteAddrFromForwardedFor middleware For convenience, Django 1.0 included an optional middleware class – django.middleware.http. SetRemoteAddrFromForwardedFor – which updated the value of REMOTE_ADDR based on the HTTP X-Forwarded-For header commonly set by some proxy configurations. It has been demonstrated that this mechanism cannot be made reliable enough for general-purpose use, and that (despite documentation to the contrary) its inclusion in Django may lead application developers to assume that the value of REMOTE_ADDR is “safe” or in some way reliable as a source of authentication. While not directly a security issue, we’ve decided to remove this middleware with the Django 1.1 release. It has been replaced with a class that does nothing other than raise a DeprecationWarning. If you’ve been relying on this middleware, the easiest upgrade path is: • Examine the code as it existed before it was removed. • Verify that it works correctly with your upstream proxy, modifying it to support your particular proxy (if necessary). • Introduce your modified version of SetRemoteAddrFromForwardedFor as a piece of middleware in your own project. Names of uploaded files are available later In Django 1.0, files uploaded and stored in a model’s FileField were saved to disk before the model was saved to the database. This meant that the actual file name assigned to the file was available before saving. For example, it was available in a model’s pre-save signal handler. In Django 1.1 the file is saved as part of saving the model in the database, so the actual file name used on disk cannot be relied on until after the model has been saved. Changes to how model formsets are saved In Django 1.1, BaseModelFormSet now calls ModelForm.save(). This is backwards-incompatible if you were modifying self.initial in a model formset’s __init__, or if you relied on the internal _total_form_count or _initial_form_count attributes of BaseFormSet. Those attributes are now public methods. Fixed the join filter’s escaping behavior The join filter no longer escapes the literal value that is passed in for the connector. This is backwards incompatible for the special situation of the literal string containing one of the five special HTML characters. Thus, if you were writing {{ foo|join:"&" }}, you now have to write {{ foo|join:"&" }}. The previous behavior was a bug and contrary to what was documented and expected. Permanent redirects and the redirect_to() generic view Django 1.1 adds a permanent argument to the django.views.generic.simple.redirect_to() view. This is technically backwards-incompatible if you were using the redirect_to view with a format-string key called ‘permanent’, which is highly unlikely. 9.1. Final releases

1677

Django Documentation, Release 2.1.dev20171115023625

Features deprecated in 1.1 One feature has been marked as deprecated in Django 1.1: • You should no longer use AdminSite.root() to register that admin views. That is, if your URLconf contains the line: (r'^admin/(.*)', admin.site.root),

You should change it to read: (r'^admin/', include(admin.site.urls)),

You should begin to remove use of this feature from your code immediately. AdminSite.root will raise a PendingDeprecationWarning if used in Django 1.1. This warning is hidden by default. In Django 1.2, this warning will be upgraded to a DeprecationWarning, which will be displayed loudly. Django 1.3 will remove AdminSite.root() entirely. For more details on our deprecation policies and strategy, see Django’s release process. What’s new in Django 1.1 Quite a bit: since Django 1.0, we’ve made 1,290 code commits, fixed 1,206 bugs, and added roughly 10,000 lines of documentation. The major new features in Django 1.1 are: ORM improvements Two major enhancements have been added to Django’s object-relational mapper (ORM): aggregate support, and query expressions. Aggregate support It’s now possible to run SQL aggregate queries (i.e. COUNT(), MAX(), MIN(), etc.) from within Django’s ORM. You can choose to either return the results of the aggregate directly, or else annotate the objects in a QuerySet with the results of the aggregate query. This feature is available as new aggregate() and annotate() methods, and is covered in detail in the ORM aggregation documentation. Query expressions Queries can now refer to another field on the query and can traverse relationships to refer to fields on related models. This is implemented in the new F object; for full details, including examples, consult the F expressions documentation. Model improvements A number of features have been added to Django’s model layer:

1678

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

“Unmanaged” models You can now control whether or not Django manages the life-cycle of the database tables for a model using the managed model option. This defaults to True, meaning that Django will create the appropriate database tables in syncdb and remove them as part of the reset command. That is, Django manages the database table’s lifecycle. If you set this to False, however, no database table creating or deletion will be automatically performed for this model. This is useful if the model represents an existing table or a database view that has been created by some other means. For more details, see the documentation for the managed option. Proxy models You can now create proxy models: subclasses of existing models that only add Python-level (rather than databaselevel) behavior and aren’t represented by a new table. That is, the new model is a proxy for some underlying model, which stores all the real data. All the details can be found in the proxy models documentation. This feature is similar on the surface to unmanaged models, so the documentation has an explanation of how proxy models differ from unmanaged models. Deferred fields In some complex situations, your models might contain fields which could contain a lot of data (for example, large text fields), or require expensive processing to convert them to Python objects. If you know you don’t need those particular fields, you can now tell Django not to retrieve them from the database. You’ll do this with the new queryset methods defer() and only(). Testing improvements A few notable improvements have been made to the testing framework. Test performance improvements Tests written using Django’s testing framework now run dramatically faster (as much as 10 times faster in many cases). This was accomplished through the introduction of transaction-based tests: when using django.test.TestCase, your tests will now be run in a transaction which is rolled back when finished, instead of by flushing and re-populating the database. This results in an immense speedup for most types of unit tests. See the documentation for TestCase and TransactionTestCase for a full description, and some important notes on database support. Test client improvements A couple of small – but highly useful – improvements have been made to the test client: • The test Client now can automatically follow redirects with the follow argument to Client.get() and Client.post(). This makes testing views that issue redirects simpler. • It’s now easier to get at the template context in the response returned the test client: you’ll simply access the context as request.context[key]. The old way, which treats request.context as a list of contexts, one for each rendered template in the inheritance chain, is still available if you need it.

9.1. Final releases

1679

Django Documentation, Release 2.1.dev20171115023625

New admin features Django 1.1 adds a couple of nifty new features to Django’s admin interface: Editable fields on the change list You can now make fields editable on the admin list views via the new list_editable admin option. These fields will show up as form widgets on the list pages, and can be edited and saved in bulk. Admin “actions” You can now define admin actions that can perform some action to a group of models in bulk. Users will be able to select objects on the change list page and then apply these bulk actions to all selected objects. Django ships with one pre-defined admin action to delete a group of objects in one fell swoop. Conditional view processing Django now has much better support for conditional view processing using the standard ETag and Last-Modified HTTP headers. This means you can now easily short-circuit view processing by testing less-expensive conditions. For many views this can lead to a serious improvement in speed and reduction in bandwidth. URL namespaces Django 1.1 improves named URL patterns with the introduction of URL “namespaces.” In short, this feature allows the same group of URLs, from the same application, to be included in a Django URLConf multiple times, with varying (and potentially nested) named prefixes which will be used when performing reverse resolution. In other words, reusable applications like Django’s admin interface may be registered multiple times without URL conflicts. For full details, see the documentation on defining URL namespaces. GeoDjango In Django 1.1, GeoDjango (i.e. django.contrib.gis) has several new features: • Support for SpatiaLite – a spatial database for SQLite – as a spatial backend. • Geographic aggregates (Collect, Extent, MakeLine, Union) and F expressions. • New GeoQuerySet methods: collect, geojson, and snap_to_grid. • A new list interface methods for GEOSGeometry objects. For more details, see the GeoDjango documentation. Other improvements Other new features and changes introduced since Django 1.0 include:

1680

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

• The CSRF protection middleware has been split into two classes – CsrfViewMiddleware checks incoming requests, and CsrfResponseMiddleware processes outgoing responses. The combined CsrfMiddleware class (which does both) remains for backwards-compatibility, but using the split classes is now recommended in order to allow fine-grained control of when and where the CSRF processing takes place. • reverse() and code which uses it (e.g., the {% url %} template tag) now works with URLs in Django’s administrative site, provided that the admin URLs are set up via include(admin.site.urls) (sending admin requests to the admin.site.root view still works, but URLs in the admin will not be “reversible” when configured this way). • The include() function in Django URLconf modules can now accept sequences of URL patterns (generated by patterns()) in addition to module names. • Instances of Django forms (see the forms overview) now have two additional methods, hidden_fields() and visible_fields(), which return the list of hidden – i.e., – and visible fields on the form, respectively. • The redirect_to generic view now accepts an additional keyword argument permanent. If permanent is True, the view will emit an HTTP permanent redirect (status code 301). If False, the view will emit an HTTP temporary redirect (status code 302). • A new database lookup type – week_day – has been added for DateField and DateTimeField. This type of lookup accepts a number between 1 (Sunday) and 7 (Saturday), and returns objects where the field value matches that day of the week. See the full list of lookup types for details. • The {% for %} tag in Django’s template language now accepts an optional {% empty %} clause, to be displayed when {% for %} is asked to loop over an empty sequence. See the list of built-in template tags for examples of this. • The dumpdata management command now accepts individual model names as arguments, allowing you to export the data just from particular models. • There’s a new safeseq template filter which works just like safe for lists, marking each item in the list as safe. • Cache backends now support incr() and decr() commands to increment and decrement the value of a cache key. On cache backends that support atomic increment/decrement – most notably, the memcached backend – these operations will be atomic, and quite fast. • Django now can easily delegate authentication to the Web server via a new authentication backend that supports the standard REMOTE_USER environment variable used for this purpose. • There’s a new django.shortcuts.redirect() function that makes it easier to issue redirects given an object, a view name, or a URL. • The postgresql_psycopg2 backend now supports native PostgreSQL autocommit. This is an advanced, PostgreSQL-specific feature, that can make certain read-heavy applications a good deal faster. What’s next? We’ll take a short break, and then work on Django 1.2 will begin – no rest for the weary! If you’d like to help, discussion of Django development, including progress toward the 1.2 release, takes place daily on the django-developers mailing list and in the #django-dev IRC channel on irc.freenode.net. Feel free to join the discussions! Django’s online documentation also includes pointers on how to contribute to Django: • How to contribute to Django Contributions on any level – developing code, writing documentation or simply triaging tickets and helping to test proposed bugfixes – are always welcome and appreciated.

9.1. Final releases

1681

Django Documentation, Release 2.1.dev20171115023625

And that’s the way it is.

9.1.14 1.0 release Django 1.0.2 release notes Welcome to Django 1.0.2! This is the second “bugfix” release in the Django 1.0 series, improving the stability and performance of the Django 1.0 codebase. As such, Django 1.0.2 contains no new features (and, pursuant to our compatibility policy, maintains backwards compatibility with Django 1.0.0), but does contain a number of fixes and other improvements. Django 1.0.2 is a recommended upgrade for any development or deployment currently using or targeting Django 1.0. Fixes and improvements in Django 1.0.2 The primary reason behind this release is to remedy an issue in the recently-released Django 1.0.1; the packaging scripts used for Django 1.0.1 omitted some directories from the final release package, including one directory required by django.contrib.gis and part of Django’s unit-test suite. Django 1.0.2 contains updated packaging scripts, and the release package contains the directories omitted from Django 1.0.1. As such, this release contains all of the fixes and improvements from Django 1.0.1; see the Django 1.0.1 release notes for details. Additionally, in the period since Django 1.0.1 was released: • Updated Hebrew and Danish translations have been added. • The default __repr__ method of Django models has been made more robust in the face of bad Unicode data coming from the __unicode__ method; rather than raise an exception in such cases, repr() will now contain the string “[Bad Unicode data]” in place of the invalid Unicode. • A bug involving the interaction of Django’s SafeUnicode class and the MySQL adapter has been resolved; SafeUnicode instances (generated, for example, by template rendering) can now be assigned to model attributes and saved to MySQL without requiring an explicit intermediate cast to unicode. • A bug affecting filtering on a nullable DateField in SQLite has been resolved. • Several updates and improvements have been made to Django’s documentation. Django 1.0.1 release notes Welcome to Django 1.0.1! This is the first “bugfix” release in the Django 1.0 series, improving the stability and performance of the Django 1.0 codebase. As such, Django 1.0.1 contains no new features (and, pursuant to our compatibility policy, maintains backwards compatibility with Django 1.0), but does contain a number of fixes and other improvements. Django 1.0.1 is a recommended upgrade for any development or deployment currently using or targeting Django 1.0. Fixes and improvements in Django 1.0.1 Django 1.0.1 contains over two hundred fixes to the original Django 1.0 codebase; full details of every fix are available in the history of the 1.0.X branch, but here are some of the highlights: • Several fixes in django.contrib.comments, pertaining to RSS feeds of comments, default ordering of comments and the XHTML and internationalization of the default templates for comments.

1682

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

• Multiple fixes for Django’s support of Oracle databases, including pagination support for GIS QuerySets, more efficient slicing of results and improved introspection of existing databases. • Several fixes for query support in the Django object-relational mapper, including repeated setting and resetting of ordering and fixes for working with INSERT-only queries. • Multiple fixes for inline forms in formsets. • Multiple fixes for unique and unique_together model constraints in automatically-generated forms. • Fixed support for custom callable upload_to declarations when handling file uploads through automaticallygenerated forms. • Fixed support for sorting an admin change list based on a callable attributes in list_display. • A fix to the application of autoescaping for literal strings passed to the join template filter. Previously, literal strings passed to join were automatically escaped, contrary to the documented behavior for autoescaping and literal strings. Literal strings passed to join are no longer automatically escaped, meaning you must now manually escape them; this is an incompatibility if you were relying on this bug, but not if you were relying on escaping behaving as documented. • Improved and expanded translation files for many of the languages Django supports by default. • And as always, a large number of improvements to Django’s documentation, including both corrections to existing documents and expanded and new documentation. Django 1.0 release notes Welcome to Django 1.0! We’ve been looking forward to this moment for over three years, and it’s finally here. Django 1.0 represents the largest milestone in Django’s development to date: a Web framework that a group of perfectionists can truly be proud of. Django 1.0 represents over three years of community development as an Open Source project. Django’s received contributions from hundreds of developers, been translated into fifty languages, and today is used by developers on every continent and in every kind of job. An interesting historical note: when Django was first released in July 2005, the initial released version of Django came from an internal repository at revision number 8825. Django 1.0 represents revision 8961 of our public repository. It seems fitting that our 1.0 release comes at the moment where community contributions overtake those made privately. Stability and forwards-compatibility The release of Django 1.0 comes with a promise of API stability and forwards-compatibility. In a nutshell, this means that code you develop against Django 1.0 will continue to work against 1.1 unchanged, and you should need to make only minor changes for any 1.X release. See the API stability guide for full details. Backwards-incompatible changes Django 1.0 has a number of backwards-incompatible changes from Django 0.96. If you have apps written against Django 0.96 that you need to port, see our detailed porting guide:

9.1. Final releases

1683

Django Documentation, Release 2.1.dev20171115023625

Porting your apps from Django 0.96 to 1.0 Django 1.0 breaks compatibility with 0.96 in some areas. This guide will help you port 0.96 projects and apps to 1.0. The first part of this document includes the common changes needed to run with 1.0. If after going through the first part your code still breaks, check the section Lesscommon Changes for a list of a bunch of less-common compatibility issues. See also: The 1.0 release notes. That document explains the new features in 1.0 more deeply; the porting guide is more concerned with helping you quickly update your code. Common changes This section describes the changes between 0.96 and 1.0 that most users will need to make. Use Unicode Change string literals ('foo') into Unicode literals (u'foo'). Django now uses Unicode strings throughout. In most places, raw strings will continue to work, but updating to use Unicode literals will prevent some obscure problems. See Unicode data for full details. Models Common changes to your models file: Rename maxlength to max_length Rename your maxlength argument to max_length (this was changed to be consistent with form fields): Replace __str__ with __unicode__ Replace your model’s __str__ function with a __unicode__ method, and make sure you use Unicode (u'foo') in that method. Remove prepopulated_from Remove the prepopulated_from argument on model fields. It’s no longer valid and has been moved to the ModelAdmin class in admin.py. See the admin, below, for more details about changes to the admin. Remove core Remove the core argument from your model fields. It is no longer necessary, since the equivalent functionality (part of inline editing) is handled differently by the admin interface now. You don’t have to worry about inline editing until you get to the admin section, below. For now, remove all references to core.

1684

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Replace class Admin: with admin.py Remove all your inner class Admin declarations from your models. They won’t break anything if you leave them, but they also won’t do anything. To register apps with the admin you’ll move those declarations to an admin.py file; see the admin below for more details. See also: A contributor to djangosnippets has written a script that’ll scan your models.py and generate a corresponding admin.py. Example Below is an example models.py file with all the changes you’ll need to make: Old (0.96) models.py: class Author(models.Model): first_name = models.CharField(maxlength=30) last_name = models.CharField(maxlength=30) slug = models.CharField(maxlength=60, prepopulate_from=('first_name', 'last_name ˓→')) class Admin: list_display = ['first_name', 'last_name'] def __str__(self): return '%s %s' % (self.first_name, self.last_name)

New (1.0) models.py: class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30) slug = models.CharField(max_length=60) def __unicode__(self): return u'%s %s' % (self.first_name, self.last_name)

New (1.0) admin.py: from django.contrib import admin from models import Author class AuthorAdmin(admin.ModelAdmin): list_display = ['first_name', 'last_name'] prepopulated_fields = { 'slug': ('first_name', 'last_name') } admin.site.register(Author, AuthorAdmin)

The Admin One of the biggest changes in 1.0 is the new admin. The Django administrative interface (django.contrib. admin) has been completely refactored; admin definitions are now completely decoupled from model definitions,

9.1. Final releases

1685

Django Documentation, Release 2.1.dev20171115023625

the framework has been rewritten to use Django’s new form-handling library and redesigned with extensibility and customization in mind. Practically, this means you’ll need to rewrite all of your class Admin declarations. You’ve already seen in models above how to replace your class Admin with a admin.site.register() call in an admin.py file. Below are some more details on how to rewrite that Admin declaration into the new syntax. Use new inline syntax The new edit_inline options have all been moved to admin.py. Here’s an example: Old (0.96): class Parent(models.Model): ... class Child(models.Model): parent = models.ForeignKey(Parent, edit_inline=models.STACKED, num_in_admin=3)

New (1.0): class ChildInline(admin.StackedInline): model = Child extra = 3 class ParentAdmin(admin.ModelAdmin): model = Parent inlines = [ChildInline] admin.site.register(Parent, ParentAdmin)

See InlineModelAdmin objects for more details. Simplify fields, or use fieldsets The old fields syntax was quite confusing, and has been simplified. The old syntax still works, but you’ll need to use fieldsets instead. Old (0.96): class ModelOne(models.Model): ... class Admin: fields = ( (None, {'fields': ('foo','bar')}), ) class ModelTwo(models.Model): ... class Admin: fields = ( ('group1', {'fields': ('foo','bar'), 'classes': 'collapse'}), ('group2', {'fields': ('spam','eggs'), 'classes': 'collapse wide'}), )

1686

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

New (1.0): class ModelOneAdmin(admin.ModelAdmin): fields = ('foo', 'bar') class ModelTwoAdmin(admin.ModelAdmin): fieldsets = ( ('group1', {'fields': ('foo','bar'), 'classes': 'collapse'}), ('group2', {'fields': ('spam','eggs'), 'classes': 'collapse wide'}), )

See also: • More detailed information about the changes and the reasons behind them can be found on the NewformsAdminBranch wiki page • The new admin comes with a ton of new features; you can read about them in the admin documentation. URLs Update your root urls.py If you’re using the admin site, you need to update your root urls.py. Old (0.96) urls.py: from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^admin/', include('django.contrib.admin.urls')), # ... the rest of your URLs here ... )

New (1.0) urls.py: from django.conf.urls.defaults import * # The next two lines enable the admin and load each admin.py file: from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', (r'^admin/(.*)', admin.site.root), # ... the rest of your URLs here ... )

Views Use django.forms instead of newforms Replace django.newforms with django.forms – Django 1.0 renamed the newforms module (introduced in 0.96) to plain old forms. The oldforms module was also removed.

9.1. Final releases

1687

Django Documentation, Release 2.1.dev20171115023625

If you’re already using the newforms library, and you used our recommended import statement syntax, all you have to do is change your import statements. Old: from django import newforms as forms

New: from django import forms

If you’re using the old forms system (formerly known as django.forms and django.oldforms), you’ll have to rewrite your forms. A good place to start is the forms documentation Handle uploaded files using the new API Replace use of uploaded files – that is, entries in request.FILES – as simple dictionaries with the new UploadedFile. The old dictionary syntax no longer works. Thus, in a view like: def my_view(request): f = request.FILES['file_field_name'] ...

...you’d need to make the following changes: Old (0.96) f['content'] f['filename'] f['content-type']

New (1.0) f.read() f.name f.content_type

Work with file fields using the new API The internal implementation of django.db.models.FileField have changed. A visible result of this is that the way you access special attributes (URL, filename, image size, etc.) of these model fields has changed. You will need to make the following changes, assuming your model’s FileField is called myfile: Old (0.96) myfile.get_content_filename() myfile.get_content_url() myfile.get_content_size() myfile.save_content_file() myfile.get_content_width() myfile.get_content_height()

New (1.0) myfile.content.path myfile.content.url myfile.content.size myfile.content.save() myfile.content.width myfile.content.height

Note that the width and height attributes only make sense for ImageField fields. More details can be found in the model API documentation. Use Paginator instead of ObjectPaginator The ObjectPaginator in 0.96 has been removed and replaced with an improved version, django.core. paginator.Paginator.

1688

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Templates Learn to love autoescaping By default, the template system now automatically HTML-escapes the output of every variable. To learn more, see Automatic HTML escaping. To disable auto-escaping for an individual variable, use the safe filter: This will be escaped: {{ data }} This will not be escaped: {{ data|safe }}

To disable auto-escaping for an entire template, wrap the template (or just a particular section of the template) in the autoescape tag: {% autoescape off %} ... unescaped template content here ... {% endautoescape %}

Less-common changes The following changes are smaller, more localized changes. They should only affect more advanced users, but it’s probably worth reading through the list and checking your code for these things. Signals • Add **kwargs to any registered signal handlers. • Connect, disconnect, and send signals via methods on the Signal object instead of through module methods in django.dispatch.dispatcher. • Remove any use of the Anonymous and Any sender options; they no longer exist. You can still receive signals sent by any sender by using sender=None • Make any custom signals you’ve declared into instances of django.dispatch.Signal instead of anonymous objects. Here’s quick summary of the code changes you’ll need to make: Old (0.96) def callback(sender) sig = object() dispatcher.connect(callback, sig) dispatcher.send(sig, sender) dispatcher.connect(callback, sig, sender=Any)

New (1.0) def callback(sender, **kwargs) sig = django.dispatch.Signal() sig.connect(callback) sig.send(sender) sig.connect(callback, sender=None)

Comments If you were using Django 0.96’s django.contrib.comments app, you’ll need to upgrade to the new comments app introduced in 1.0. See the upgrade guide for details.

9.1. Final releases

1689

Django Documentation, Release 2.1.dev20171115023625

Template tags spaceless tag The spaceless template tag now removes all spaces between HTML tags, instead of preserving a single space. Local flavors U.S. local flavor django.contrib.localflavor.usa has been renamed to django.contrib.localflavor.us. This change was made to match the naming scheme of other local flavors. To migrate your code, all you need to do is change the imports. Sessions Getting a new session key SessionBase.get_new_session_key() has get_new_session_object() no longer exists.

been

renamed

to

_get_new_session_key().

Fixtures Loading a row no longer calls save() Previously, loading a row automatically ran the model’s save() method. This is no longer the case, so any fields (for example: timestamps) that were auto-populated by a save() now need explicit values in any fixture. Settings Better exceptions The old EnvironmentError has split into an ImportError when Django fails to find the settings module and a RuntimeError when you try to reconfigure settings after having already used them. LOGIN_URL has moved The LOGIN_URL constant moved from django.contrib.auth into the settings module. Instead of using from django.contrib.auth import LOGIN_URL refer to settings.LOGIN_URL. APPEND_SLASH behavior has been updated In 0.96, if a URL didn’t end in a slash or have a period in the final component of its path, and APPEND_SLASH was True, Django would redirect to the same URL, but with a slash appended to the end. Now, Django checks to see whether the pattern without the trailing slash would be matched by something in your URL patterns. If so, no redirection takes place, because it is assumed you deliberately wanted to catch that pattern.

1690

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

For most people, this won’t require any changes. Some people, though, have URL patterns that look like this: r'/some_prefix/(.*)$'

Previously, those patterns would have been redirected to have a trailing slash. If you always want a slash on such URLs, rewrite the pattern as: r'/some_prefix/(.*/)$'

Smaller model changes Different exception from get() Managers now return a MultipleObjectsReturned exception instead of AssertionError: Old (0.96): try: Model.objects.get(...) except AssertionError: handle_the_error()

New (1.0): try: Model.objects.get(...) except Model.MultipleObjectsReturned: handle_the_error()

LazyDate has been fired The LazyDate helper class no longer exists. Default field values and query arguments can both be callable objects, so instances of LazyDate can be replaced with a reference to datetime.datetime.now: Old (0.96): class Article(models.Model): title = models.CharField(maxlength=100) published = models.DateField(default=LazyDate())

New (1.0): import datetime class Article(models.Model): title = models.CharField(max_length=100) published = models.DateField(default=datetime.datetime.now)

DecimalField is new, and FloatField is now a proper float Old (0.96):

9.1. Final releases

1691

Django Documentation, Release 2.1.dev20171115023625

class MyModel(models.Model): field_name = models.FloatField(max_digits=10, decimal_places=3) ...

New (1.0): class MyModel(models.Model): field_name = models.DecimalField(max_digits=10, decimal_places=3) ...

If you forget to make this change, you will see errors about FloatField not taking a max_digits attribute in __init__, because the new FloatField takes no precision-related arguments. If you’re using MySQL or PostgreSQL, no further changes are needed. DecimalField are the same as for the old FloatField.

The database column types for

If you’re using SQLite, you need to force the database to view the appropriate columns as decimal types, rather than floats. To do this, you’ll need to reload your data. Do this after you have made the change to using DecimalField in your code and updated the Django code. Warning: Back up your database first! For SQLite, this means making a copy of the single file that stores the database (the name of that file is the DATABASE_NAME in your settings.py file). To upgrade each application to use a DecimalField, you can do the following, replacing in the code below with each app’s name: $ ./manage.py dumpdata --format=xml > data-dump.xml $ ./manage.py reset $ ./manage.py loaddata data-dump.xml

Notes: 1. It’s important that you remember to use XML format in the first step of this process. We are exploiting a feature of the XML data dumps that makes porting floats to decimals with SQLite possible. 2. In the second step you will be asked to confirm that you are prepared to lose the data for the application(s) in question. Say yes; we’ll restore this data in the third step, of course. 3. DecimalField is not used in any of the apps shipped with Django prior to this change being made, so you do not need to worry about performing this procedure for any of the standard Django models. If something goes wrong in the above process, just copy your backed up database file over the original file and start again. Internationalization django.views.i18n.set_language() now requires a POST request Previously, a GET request was used. The old behavior meant that state (the locale used to display the site) could be changed by a GET request, which is against the HTTP specification’s recommendations. Code calling this view must ensure that a POST request is now made, instead of a GET. This means you can no longer use a link to access the view, but must use a form submission of some kind (e.g. a button).

1692

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

_() is no longer in builtins _() (the callable object whose name is a single underscore) is no longer monkeypatched into builtins – that is, it’s no longer available magically in every module. If you were previously relying on _() always being present, you should now explicitly import ugettext or ugettext_lazy, if appropriate, and alias it to _ yourself: from django.utils.translation import ugettext as _

HTTP request/response objects Dictionary access to HttpRequest HttpRequest objects no longer directly support dictionary-style access; previously, both GET and POST data were directly available on the HttpRequest object (e.g., you could check for a piece of form data by using if 'some_form_key' in request or by reading request['some_form_key']. This is no longer supported; if you need access to the combined GET and POST data, use request.REQUEST instead. It is strongly suggested, however, that you always explicitly look in the appropriate dictionary for the type of request you expect to receive (request.GET or request.POST); relying on the combined request.REQUEST dictionary can mask the origin of incoming data. Accessing HTTPResponse headers django.http.HttpResponse.headers has been renamed to _headers and HttpResponse now supports containment checking directly. So use if header in response: instead of if header in response. headers:. Generic relations Generic relations have been moved out of core The generic relation classes – GenericForeignKey and GenericRelation – have moved into the django. contrib.contenttypes module. Testing django.test.Client.login() has changed Old (0.96): from django.test import Client c = Client() c.login('/path/to/login','myuser','mypassword')

New (1.0): # ... same as above, but then: c.login(username='myuser', password='mypassword')

9.1. Final releases

1693

Django Documentation, Release 2.1.dev20171115023625

Management commands Running management commands from your code django.core.management has been greatly refactored. Calls to management services in your code now need to use call_command. For example, if you have some test code that calls flush and load_data: from django.core import management management.flush(verbosity=0, interactive=False) management.load_data(['test_data'], verbosity=0)

...you’ll need to change this code to read: from django.core import management management.call_command('flush', verbosity=0, interactive=False) management.call_command('loaddata', 'test_data', verbosity=0)

Subcommands must now precede options django-admin.py and manage.py now require subcommands to precede options. So: $ django-admin.py --settings=foo.bar runserver

...no longer works and should be changed to: $ django-admin.py runserver --settings=foo.bar

Syndication Feed.__init__ has changed The __init__() method of the syndication framework’s Feed class now takes an HttpRequest object as its second parameter, instead of the feed’s URL. This allows the syndication framework to work without requiring the sites framework. This only affects code that subclasses Feed and overrides the __init__() method, and code that calls Feed.__init__() directly. Data structures SortedDictFromList is gone django.newforms.forms.SortedDictFromList was removed. django.utils.datastructures. SortedDict can now be instantiated with a sequence of tuples. To update your code: 1. Use django.utils.datastructures.SortedDict wherever you were using django.newforms. forms.SortedDictFromList.

1694

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

2. Because django.utils.datastructures.SortedDict.copy doesn’t return a deepcopy as SortedDictFromList.copy() did, you will need to update your code if you were relying on a deepcopy. Do this by using copy.deepcopy directly. Database backend functions Database backend functions have been renamed Almost all of the database backend-level functions have been renamed and/or relocated. None of these were documented, but you’ll need to change your code if you’re using any of these functions, all of which are in django.db: Old (0.96) backend.get_autoinc_sql backend.get_date_extract_sql backend.get_date_trunc_sql backend.get_datetime_cast_sql backend.get_deferrable_sql backend.get_drop_foreignkey_sql backend.get_fulltext_search_sql backend.get_last_insert_id backend.get_limit_offset_sql backend.get_max_name_length backend.get_pk_default_value backend.get_random_function_sql backend.get_sql_flush backend.get_sql_sequence_reset backend.get_start_transaction_sql backend.get_tablespace_sql backend.quote_name backend.get_query_set_class backend.get_field_cast_sql backend.get_drop_sequence backend.OPERATOR_MAPPING backend.allows_group_by_ordinal backend.allows_unique_and_pk backend.autoindexes_primary_keys backend.needs_datetime_string_cast backend.needs_upper_for_iops backend.supports_constraints backend.supports_tablespaces backend.uses_case_insensitive_names backend.uses_custom_queryset

New (1.0) connection.ops.autoinc_sql connection.ops.date_extract_sql connection.ops.date_trunc_sql connection.ops.datetime_cast_sql connection.ops.deferrable_sql connection.ops.drop_foreignkey_sql connection.ops.fulltext_search_sql connection.ops.last_insert_id connection.ops.limit_offset_sql connection.ops.max_name_length connection.ops.pk_default_value connection.ops.random_function_sql connection.ops.sql_flush connection.ops.sequence_reset_sql connection.ops.start_transaction_sql connection.ops.tablespace_sql connection.ops.quote_name connection.ops.query_set_class connection.ops.field_cast_sql connection.ops.drop_sequence_sql connection.operators connection.features.allows_group_by_ordinal connection.features.allows_unique_and_pk connection.features.autoindexes_primary_keys connection.features.needs_datetime_string_cast connection.features.needs_upper_for_iops connection.features.supports_constraints connection.features.supports_tablespaces connection.features.uses_case_insensitive_names connection.features.uses_custom_queryset

A complete list of backwards-incompatible changes can be found at https://code.djangoproject.com/wiki/ BackwardsIncompatibleChanges. What’s new in Django 1.0 A lot!

9.1. Final releases

1695

Django Documentation, Release 2.1.dev20171115023625

Since Django 0.96, we’ve made over 4,000 code commits, fixed more than 2,000 bugs, and edited, added, or removed around 350,000 lines of code. We’ve also added 40,000 lines of new documentation, and greatly improved what was already there. In fact, new documentation is one of our favorite features of Django 1.0, so we might as well start there. First, there’s a new documentation site: • https://docs.djangoproject.com/ The documentation has been greatly improved, cleaned up, and generally made awesome. There’s now dedicated search, indexes, and more. We can’t possibly document everything that’s new in 1.0, but the documentation will be your definitive guide. Anywhere you see something like: This feature is new in Django 1.0 You’ll know that you’re looking at something new or changed. The other major highlights of Django 1.0 are: Re-factored admin application The Django administrative interface (django.contrib.admin) has been completely refactored; admin definitions are now completely decoupled from model definitions (no more class Admin declaration in models!), rewritten to use Django’s new form-handling library (introduced in the 0.96 release as django.newforms, and now available as simply django.forms) and redesigned with extensibility and customization in mind. Full documentation for the admin application is available online in the official Django documentation: See the admin reference for details Improved Unicode handling Django’s internals have been refactored to use Unicode throughout; this drastically simplifies the task of dealing with non-Western-European content and data in Django. Additionally, utility functions have been provided to ease interoperability with third-party libraries and systems which may or may not handle Unicode gracefully. Details are available in Django’s Unicode-handling documentation. See Unicode data. An improved ORM Django’s object-relational mapper – the component which provides the mapping between Django model classes and your database, and which mediates your database queries – has been dramatically improved by a massive refactoring. For most users of Django this is backwards-compatible; the public-facing API for database querying underwent a few minor changes, but most of the updates took place in the ORM’s internals. A guide to the changes, including backwards-incompatible modifications and mentions of new features opened up by this refactoring, is available on the Django wiki. Automatic escaping of template variables To provide improved security against cross-site scripting (XSS) vulnerabilities, Django’s template system now automatically escapes the output of variables. This behavior is configurable, and allows both variables and larger template constructs to be marked as safe (requiring no escaping) or unsafe (requiring escaping). A full guide to this feature is in the documentation for the autoescape tag. 1696

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

django.contrib.gis (GeoDjango) A project over a year in the making, this adds world-class GIS (Geographic Information Systems) support to Django, in the form of a contrib application. Its documentation is currently being maintained externally, and will be merged into the main Django documentation shortly. Huge thanks go to Justin Bronn, Jeremy Dunck, Brett Hoerner and Travis Pinney for their efforts in creating and completing this feature. See http://geodjango.org/ for details. Pluggable file storage Django’s built-in FileField and ImageField now can take advantage of pluggable file-storage backends, allowing extensive customization of where and how uploaded files get stored by Django. For details, see the files documentation; big thanks go to Marty Alchin for putting in the hard work to get this completed. Jython compatibility Thanks to a lot of work from Leo Soto during a Google Summer of Code project, Django’s codebase has been refactored to remove incompatibilities with Jython, an implementation of Python written in Java, which runs Python code on the Java Virtual Machine. Django is now compatible with the forthcoming Jython 2.5 release. See Running Django on Jython. Generic relations in forms and admin Classes are now included in django.contrib.contenttypes which can be used to support generic relations in both the admin interface and in end-user forms. See the documentation for generic relations for details. INSERT/UPDATE distinction Although Django’s default behavior of having a model’s save() method automatically determine whether to perform an INSERT or an UPDATE at the SQL level is suitable for the majority of cases, there are occasional situations where forcing one or the other is useful. As a result, models can now support an additional parameter to save() which can force a specific operation. See Forcing an INSERT or UPDATE for details. Split CacheMiddleware Django’s CacheMiddleware has been split into three classes: CacheMiddleware itself still exists and retains all of its previous functionality, but it is now built from two separate middleware classes which handle the two parts of caching (inserting into and reading from the cache) separately, offering additional flexibility for situations where combining these functions into a single middleware posed problems. Full details, including updated notes on appropriate use, are in the caching documentation. Refactored django.contrib.comments As part of a Google Summer of Code project, Thejaswi Puthraya carried out a major rewrite and refactoring of Django’s bundled comment system, greatly increasing its flexibility and customizability. 9.1. Final releases

1697

Django Documentation, Release 2.1.dev20171115023625

Removal of deprecated features A number of features and methods which had previously been marked as deprecated, and which were scheduled for removal prior to the 1.0 release, are no longer present in Django. These include imports of the form library from django.newforms (now located simply at django.forms), the form_for_model and form_for_instance helper functions (which have been replaced by ModelForm) and a number of deprecated features which were replaced by the dispatcher, file-uploading and file-storage refactorings introduced in the Django 1.0 alpha releases. Known issues We’ve done our best to make Django 1.0 as solid as possible, but unfortunately there are a couple of issues that we know about in the release. Multi-table model inheritance with to_field If you’re using multiple table model inheritance, be aware of this caveat: child models using a custom parent_link and to_field will cause database integrity errors. A set of models like the following are not valid: class Parent(models.Model): name = models.CharField(max_length=10) other_value = models.IntegerField(unique=True) class Child(Parent): father = models.OneToOneField(Parent, primary_key=True, to_field="other_value", ˓→parent_link=True) value = models.IntegerField()

This bug will be fixed in the next release of Django. Caveats with support of certain databases Django attempts to support as many features as possible on all database backends. However, not all database backends are alike, and in particular many of the supported database differ greatly from version to version. It’s a good idea to checkout our notes on supported database: • MySQL notes • SQLite notes • Oracle notes

9.1.15 Pre-1.0 releases Django version 0.96 release notes Welcome to Django 0.96! The primary goal for 0.96 is a cleanup and stabilization of the features introduced in 0.95. There have been a few small backwards-incompatible changes since 0.95, but the upgrade process should be fairly simple and should not require major changes to existing applications.

1698

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

However, we’re also releasing 0.96 now because we have a set of backwards-incompatible changes scheduled for the near future. Once completed, they will involve some code changes for application developers, so we recommend that you stick with Django 0.96 until the next official release; then you’ll be able to upgrade in one step instead of needing to make incremental changes to keep up with the development version of Django. Backwards-incompatible changes The following changes may require you to update your code when you switch from 0.95 to 0.96: MySQLdb version requirement Due to a bug in older versions of the MySQLdb Python module (which Django uses to connect to MySQL databases), Django’s MySQL backend now requires version 1.2.1p2 or higher of MySQLdb, and will raise exceptions if you attempt to use an older version. If you’re currently unable to upgrade your copy of MySQLdb to meet this requirement, a separate, backwardscompatible backend, called “mysql_old”, has been added to Django. To use this backend, change the DATABASE_ENGINE setting in your Django settings file from this: DATABASE_ENGINE = "mysql"

to this: DATABASE_ENGINE = "mysql_old"

However, we strongly encourage MySQL users to upgrade to a more recent version of MySQLdb as soon as possible, The “mysql_old” backend is provided only to ease this transition, and is considered deprecated; aside from any necessary security fixes, it will not be actively maintained, and it will be removed in a future release of Django. Also, note that some features, like the new DATABASE_OPTIONS setting (see the databases documentation for details), are only available on the “mysql” backend, and will not be made available for “mysql_old”. Database constraint names changed The format of the constraint names Django generates for foreign key references have changed slightly. These names are generally only used when it is not possible to put the reference directly on the affected column, so they are not always visible. The effect of this change is that running manage.py reset and similar commands against an existing database may generate SQL with the new form of constraint name, while the database itself contains constraints named in the old form; this will cause the database server to raise an error message about modifying nonexistent constraints. If you need to work around this, there are two methods available: 1. Redirect the output of manage.py to a file, and edit the generated SQL to use the correct constraint names before executing it. 2. Examine the output of manage.py sqlall to see the new-style constraint names, and use that as a guide to rename existing constraints in your database. Name changes in manage.py A few of the options to manage.py have changed with the addition of fixture support:

9.1. Final releases

1699

Django Documentation, Release 2.1.dev20171115023625

• There are new dumpdata and loaddata commands which, as you might expect, will dump and load data to/from the database. These commands can operate against any of Django’s supported serialization formats. • The sqlinitialdata command has been renamed to sqlcustom to emphasize that loaddata should be used for data (and sqlcustom for other custom SQL – views, stored procedures, etc.). • The vestigial install command has been removed. Use syncdb. Backslash escaping changed The Django database API now escapes backslashes given as query parameters. If you have any database API code that matches backslashes, and it was working before (despite the lack of escaping), you’ll have to change your code to “unescape” the slashes one level. For example, this used to work: # Find text containing a single backslash MyModel.objects.filter(text__contains='\\\\')

The above is now incorrect, and should be rewritten as: # Find text containing a single backslash MyModel.objects.filter(text__contains='\\')

Removed ENABLE_PSYCO setting The ENABLE_PSYCO setting no longer exists. If your settings file includes ENABLE_PSYCO it will have no effect; to use Psyco, we recommend writing a middleware class to activate it. What’s new in 0.96? This revision represents over a thousand source commits and over four hundred bug fixes, so we can’t possibly catalog all the changes. Here, we describe the most notable changes in this release. New forms library django.newforms is Django’s new form-handling library. It’s a replacement for django.forms, the old form/manipulator/validation framework. Both APIs are available in 0.96, but over the next two releases we plan to switch completely to the new forms system, and deprecate and remove the old system. There are three elements to this transition: • We’ve copied the current django.forms to django.oldforms. This allows you to upgrade your code now rather than waiting for the backwards-incompatible change and rushing to fix your code after the fact. Just change your import statements like this: from django import forms # 0.95-style from django import oldforms as forms # 0.96-style

• The next official release of Django will move the current django.newforms to django.forms. This will be a backwards-incompatible change, and anyone still using the old version of django.forms at that time will need to change their import statements as described above. • The next release after that will completely remove django.oldforms. 1700

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Although the newforms library will continue to evolve, it’s ready for use for most common cases. We recommend that anyone new to form handling skip the old forms system and start with the new. For more information about django.newforms, read the newforms documentation. URLconf improvements You can now use any callable as the callback in URLconfs (previously, only strings that referred to callables were allowed). This allows a much more natural use of URLconfs. For example, this URLconf: from django.conf.urls.defaults import * urlpatterns = patterns('', ('^myview/$', 'mysite.myapp.views.myview') )

can now be rewritten as: from django.conf.urls.defaults import * from mysite.myapp.views import myview urlpatterns = patterns('', ('^myview/$', myview) )

One useful application of this can be seen when using decorators; this change allows you to apply decorators to views in your URLconf. Thus, you can make a generic view require login very easily: from from from from

django.conf.urls.defaults import * django.contrib.auth.decorators import login_required django.views.generic.list_detail import object_list mysite.myapp.models import MyModel

info = { "queryset" : MyModel.objects.all(), } urlpatterns = patterns('', ('^myview/$', login_required(object_list), info) )

Note that both syntaxes (strings and callables) are valid, and will continue to be valid for the foreseeable future. The test framework Django now includes a test framework so you can start transmuting fear into boredom (with apologies to Kent Beck). You can write tests based on doctest or unittest and test your views with a simple test client. There is also new support for “fixtures” – initial data, stored in any of the supported serialization formats, that will be loaded into your database at the start of your tests. This makes testing with real data much easier. See the testing documentation for the full details.

9.1. Final releases

1701

Django Documentation, Release 2.1.dev20171115023625

Improvements to the admin interface A small change, but a very nice one: dedicated views for adding and updating users have been added to the admin interface, so you no longer need to worry about working with hashed passwords in the admin. Thanks Since 0.95, a number of people have stepped forward and taken a major new role in Django’s development. We’d like to thank these people for all their hard work: • Russell Keith-Magee and Malcolm Tredinnick for their major code contributions. This release wouldn’t have been possible without them. • Our new release manager, James Bennett, for his work in getting out 0.95.1, 0.96, and (hopefully) future release. • Our ticket managers Chris Beaven (aka SmileyChris), Simon Greenhill, Michael Radziej, and Gary Wilson. They agreed to take on the monumental task of wrangling our tickets into nicely cataloged submission. Figuring out what to work on is now about a million times easier; thanks again, guys. • Everyone who submitted a bug report, patch or ticket comment. We can’t possibly thank everyone by name – over 200 developers submitted patches that went into 0.96 – but everyone who’s contributed to Django is listed in AUTHORS. Django version 0.95 release notes Welcome to the Django 0.95 release. This represents a significant advance in Django development since the 0.91 release in January 2006. The details of every change in this release would be too extensive to list in full, but a summary is presented below. Suitability and API stability This release is intended to provide a stable reference point for developers wanting to work on production-level applications that use Django. However, it’s not the 1.0 release, and we’ll be introducing further changes before 1.0. For a clear look at which areas of the framework will change (and which ones will not change) before 1.0, see the api-stability.txt file, which lives in the docs/ directory of the distribution. You may have a need to use some of the features that are marked as “subject to API change” in that document, but that’s OK with us as long as it’s OK with you, and as long as you understand APIs may change in the future. Fortunately, most of Django’s core APIs won’t be changing before version 1.0. There likely won’t be as big of a change between 0.95 and 1.0 versions as there was between 0.91 and 0.95. Changes and new features The major changes in this release (for developers currently using the 0.91 release) are a result of merging the ‘magicremoval’ branch of development. This branch removed a number of constraints in the way Django code had to be written that were a consequence of decisions made in the early days of Django, prior to its open-source release. It’s now possible to write more natural, Pythonic code that works as expected, and there’s less “black magic” happening behind the scenes.

1702

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Aside from that, another main theme of this release is a dramatic increase in usability. We’ve made countless improvements in error messages, documentation, etc., to improve developers’ quality of life. The new features and changes introduced in 0.95 include: • Django now uses a more consistent and natural filtering interface for retrieving objects from the database. • User-defined models, functions and constants now appear in the module namespace they were defined in. (Previously everything was magically transferred to the django.models.* namespace.) • Some optional applications, such as the FlatPage, Sites and Redirects apps, have been decoupled and moved into django.contrib. If you don’t want to use these applications, you no longer have to install their database tables. • Django now has support for managing database transactions. • We’ve added the ability to write custom authentication and authorization backends for authenticating users against alternate systems, such as LDAP. • We’ve made it easier to add custom table-level functions to models, through a new “Manager” API. • It’s now possible to use Django without a database. This simply means that the framework no longer requires you to have a working database set up just to serve dynamic pages. In other words, you can just use URLconfs/views on their own. Previously, the framework required that a database be configured, regardless of whether you actually used it. • It’s now more explicit and natural to override save() and delete() methods on models, rather than needing to hook into the pre_save() and post_save() method hooks. • Individual pieces of the framework now can be configured without requiring the setting of an environment variable. This permits use of, for example, the Django templating system inside other applications. • More and more parts of the framework have been internationalized, as we’ve expanded internationalization (i18n) support. The Django codebase, including code and templates, has now been translated, at least in part, into 31 languages. From Arabic to Chinese to Hungarian to Welsh, it is now possible to use Django’s admin site in your native language. The number of changes required to port from 0.91-compatible code to the 0.95 code base are significant in some cases. However, they are, for the most part, reasonably routine and only need to be done once. A list of the necessary changes is described in the Removing The Magic wiki page. There is also an easy checklist for reference when undertaking the porting operation. Problem reports and getting help Need help resolving a problem with Django? The documentation in the distribution is also available online at the Django website. The FAQ document is especially recommended, as it contains a number of issues that come up time and again. For more personalized help, the django-users mailing list is a very active list, with more than 2,000 subscribers who can help you solve any sort of Django problem. We recommend you search the archives first, though, because many common questions appear with some regularity, and any particular problem may already have been answered. Finally, for those who prefer the more immediate feedback offered by IRC, there’s a #django channel on irc.freenode.net that is regularly populated by Django users and developers from around the world. Friendly people are usually available at any hour of the day – to help, or just to chat. Thanks for using Django! The Django Team July 2006

9.1. Final releases

1703

Django Documentation, Release 2.1.dev20171115023625

9.2 Security releases Whenever a security issue is disclosed via Django’s security policies, appropriate release notes are now added to all affected release series. Additionally, an archive of disclosed security issues is maintained.

9.2.1 Archive of security issues Django’s development team is strongly committed to responsible reporting and disclosure of security-related issues, as outlined in Django’s security policies. As part of that commitment, we maintain the following historical list of issues which have been fixed and disclosed. For each issue, the list below includes the date, a brief description, the CVE identifier if applicable, a list of affected versions, a link to the full disclosure and links to the appropriate patch(es). Some important caveats apply to this information: • Lists of affected versions include only those versions of Django which had stable, security-supported releases at the time of disclosure. This means older versions (whose security support had expired) and versions which were in pre-release (alpha/beta/RC) states at the time of disclosure may have been affected, but are not listed. • The Django project has on occasion issued security advisories, pointing out potential security problems which can arise from improper configuration or from other issues outside of Django itself. Some of these advisories have received CVEs; when that is the case, they are listed here, but as they have no accompanying patches or releases, only the description, disclosure and CVE will be listed. Issues prior to Django’s security process Some security issues were handled before Django had a formalized security process in use. For these, new releases may not have been issued at the time and CVEs may not have been assigned. August 16, 2006 - CVE-2007-0404 Filename validation issue in translation framework. Full description Versions affected • Django 0.90 (patch) • Django 0.91 (patch) • Django 0.95 (patch) (released January 21 2007) January 21, 2007 - CVE-2007-0405 Apparent “caching” of authenticated user. Full description Versions affected • Django 0.95 (patch)

1704

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Issues under Django’s security process All other security issues have been handled under versions of Django’s security process. These are listed below. October 26, 2007 - CVE-2007-5712 Denial-of-service via arbitrarily-large Accept-Language header. Full description Versions affected • Django 0.91 (patch) • Django 0.95 (patch) • Django 0.96 (patch) May 14, 2008 - CVE-2008-2302 XSS via admin login redirect. Full description Versions affected • Django 0.91 (patch) • Django 0.95 (patch) • Django 0.96 (patch) September 2, 2008 - CVE-2008-3909 CSRF via preservation of POST data during admin login. Full description Versions affected • Django 0.91 (patch) • Django 0.95 (patch) • Django 0.96 (patch) July 28, 2009 - CVE-2009-2659 Directory-traversal in development server media handler. Full description Versions affected • Django 0.96 (patch) • Django 1.0 (patch)

9.2. Security releases

1705

Django Documentation, Release 2.1.dev20171115023625

October 9, 2009 - CVE-2009-3965 Denial-of-service via pathological regular expression performance. Full description Versions affected • Django 1.0 (patch) • Django 1.1 (patch) September 8, 2010 - CVE-2010-3082 XSS via trusting unsafe cookie value. Full description Versions affected • Django 1.2 (patch) December 22, 2010 - CVE-2010-4534 Information leakage in administrative interface. Full description Versions affected • Django 1.1 (patch) • Django 1.2 (patch) December 22, 2010 - CVE-2010-4535 Denial-of-service in password-reset mechanism. Full description Versions affected • Django 1.1 (patch) • Django 1.2 (patch) February 8, 2011 - CVE-2011-0696 CSRF via forged HTTP headers. Full description Versions affected • Django 1.1 (patch) • Django 1.2 (patch) 1706

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

February 8, 2011 - CVE-2011-0697 XSS via unsanitized names of uploaded files. Full description Versions affected • Django 1.1 (patch) • Django 1.2 (patch) February 8, 2011 - CVE-2011-0698 Directory-traversal on Windows via incorrect path-separator handling. Full description Versions affected • Django 1.1 (patch) • Django 1.2 (patch) September 9, 2011 - CVE-2011-4136 Session manipulation when using memory-cache-backed session. Full description Versions affected • Django 1.2 (patch) • Django 1.3 (patch) September 9, 2011 - CVE-2011-4137 Denial-of-service via URLField.verify_exists. Full description Versions affected • Django 1.2 (patch) • Django 1.3 (patch) September 9, 2011 - CVE-2011-4138 Information leakage/arbitrary request issuance via URLField.verify_exists. Full description

9.2. Security releases

1707

Django Documentation, Release 2.1.dev20171115023625

Versions affected • Django 1.2: (patch) • Django 1.3: (patch) September 9, 2011 - CVE-2011-4139 Host header cache poisoning. Full description Versions affected • Django 1.2 (patch) • Django 1.3 (patch) September 9, 2011 - CVE-2011-4140 Potential CSRF via Host header. Full description Versions affected This notification was an advisory only, so no patches were issued. • Django 1.2 • Django 1.3 July 30, 2012 - CVE-2012-3442 XSS via failure to validate redirect scheme. Full description Versions affected • Django 1.3: (patch) • Django 1.4: (patch) July 30, 2012 - CVE-2012-3443 Denial-of-service via compressed image files. Full description Versions affected • Django 1.3: (patch) • Django 1.4: (patch)

1708

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

July 30, 2012 - CVE-2012-3444 Denial-of-service via large image files. Full description Versions affected • Django 1.3 (patch) • Django 1.4 (patch) October 17, 2012 - CVE-2012-4520 Host header poisoning. Full description Versions affected • Django 1.3 (patch) • Django 1.4 (patch) December 10, 2012 - No CVE 1 Additional hardening of Host header handling. Full description Versions affected • Django 1.3 (patch) • Django 1.4 (patch) December 10, 2012 - No CVE 2 Additional hardening of redirect validation. Full description Versions affected • Django 1.3: (patch) • Django 1.4: (patch) February 19, 2013 - No CVE Additional hardening of Host header handling. Full description

9.2. Security releases

1709

Django Documentation, Release 2.1.dev20171115023625

Versions affected • Django 1.3 (patch) • Django 1.4 (patch) February 19, 2013 - CVE-2013-1664 / CVE-2013-1665 Entity-based attacks against Python XML libraries. Full description Versions affected • Django 1.3 (patch) • Django 1.4 (patch) February 19, 2013 - CVE-2013-0305 Information leakage via admin history log. Full description Versions affected • Django 1.3 (patch) • Django 1.4 (patch) February 19, 2013 - CVE-2013-0306 Denial-of-service via formset max_num bypass. Full description Versions affected • Django 1.3 (patch) • Django 1.4 (patch) August 13, 2013 - CVE-2013-4249 XSS via admin trusting URLField values. Full description Versions affected • Django 1.5 (patch) August 13, 2013 - CVE-2013-6044 Possible XSS via unvalidated URL redirect schemes. Full description 1710

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Versions affected • Django 1.4 (patch) • Django 1.5 (patch) September 10, 2013 - CVE-2013-4315 Directory-traversal via ssi template tag. Full description Versions affected • Django 1.4 (patch) • Django 1.5 (patch) September 14, 2013 - CVE-2013-1443 Denial-of-service via large passwords. Full description Versions affected • Django 1.4 (patch and Python compatibility fix) • Django 1.5 (patch) April 21, 2014 - CVE-2014-0472 Unexpected code execution using reverse(). Full description Versions affected • Django 1.4 (patch) • Django 1.5 (patch) • Django 1.6 (patch) • Django 1.7 (patch) April 21, 2014 - CVE-2014-0473 Caching of anonymous pages could reveal CSRF token. Full description

9.2. Security releases

1711

Django Documentation, Release 2.1.dev20171115023625

Versions affected • Django 1.4 (patch) • Django 1.5 (patch) • Django 1.6 (patch) • Django 1.7 (patch) April 21, 2014 - CVE-2014-0474 MySQL typecasting causes unexpected query results. Full description Versions affected • Django 1.4 (patch) • Django 1.5 (patch) • Django 1.6 (patch) • Django 1.7 (patch) May 18, 2014 - CVE-2014-1418 Caches may be allowed to store and serve private data. Full description Versions affected • Django 1.4 (patch) • Django 1.5 (patch) • Django 1.6 (patch) • Django 1.7 (patch) May 18, 2014 - CVE-2014-3730 Malformed URLs from user input incorrectly validated. Full description Versions affected • Django 1.4 (patch) • Django 1.5 (patch) • Django 1.6 (patch) • Django 1.7 (patch)

1712

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

August 20, 2014 - CVE-2014-0480 reverse() can generate URLs pointing to other hosts. Full description Versions affected • Django 1.4 (patch) • Django 1.5 (patch) • Django 1.6 (patch) • Django 1.7 (patch) August 20, 2014 - CVE-2014-0481 File upload denial of service. Full description Versions affected • Django 1.4 (patch) • Django 1.5 (patch) • Django 1.6 (patch) • Django 1.7 (patch) August 20, 2014 - CVE-2014-0482 RemoteUserMiddleware session hijacking. Full description Versions affected • Django 1.4 (patch) • Django 1.5 (patch) • Django 1.6 (patch) • Django 1.7 (patch) August 20, 2014 - CVE-2014-0483 Data leakage via querystring manipulation in admin. Full description

9.2. Security releases

1713

Django Documentation, Release 2.1.dev20171115023625

Versions affected • Django 1.4 (patch) • Django 1.5 (patch) • Django 1.6 (patch) • Django 1.7 (patch) January 13, 2015 - CVE-2015-0219 WSGI header spoofing via underscore/dash conflation. Full description Versions affected • Django 1.4 (patch) • Django 1.6 (patch) • Django 1.7 (patch) January 13, 2015 - CVE-2015-0220 Mitigated possible XSS attack via user-supplied redirect URLs. Full description Versions affected • Django 1.4 (patch) • Django 1.6 (patch) • Django 1.7 (patch) January 13, 2015 - CVE-2015-0221 Denial-of-service attack against django.views.static.serve(). Full description Versions affected • Django 1.4 (patch) • Django 1.6 (patch) • Django 1.7 (patch) January 13, 2015 - CVE-2015-0222 Database denial-of-service with ModelMultipleChoiceField. Full description

1714

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Versions affected • Django 1.6 (patch) • Django 1.7 (patch) March 9, 2015 - CVE-2015-2241 XSS attack via properties in ModelAdmin.readonly_fields. Full description Versions affected • Django 1.7 (patch) • Django 1.8 (patch) March 18, 2015 - CVE-2015-2316 Denial-of-service possibility with strip_tags(). Full description Versions affected • Django 1.6 (patch) • Django 1.7 (patch) • Django 1.8 (patch) March 18, 2015 - CVE-2015-2317 Mitigated possible XSS attack via user-supplied redirect URLs. Full description Versions affected • Django 1.4 (patch) • Django 1.6 (patch) • Django 1.7 (patch) • Django 1.8 (patch) May 20, 2015 - CVE-2015-3982 Fixed session flushing in the cached_db backend. Full description Versions affected • Django 1.8 (patch)

9.2. Security releases

1715

Django Documentation, Release 2.1.dev20171115023625

July 8, 2015 - CVE-2015-5143 Denial-of-service possibility by filling session store. Full description Versions affected • Django 1.8 (patch) • Django 1.7 (patch) • Django 1.4 (patch) July 8, 2015 - CVE-2015-5144 Header injection possibility since validators accept newlines in input. Full description Versions affected • Django 1.8 (patch) • Django 1.7 (patch) • Django 1.4 (patch) July 8, 2015 - CVE-2015-5145 Denial-of-service possibility in URL validation. Full description Versions affected • Django 1.8 (patch) August 18, 2015 - CVE-2015-5963 / CVE-2015-5964 Denial-of-service possibility in logout() view by filling session store. Full description Versions affected • Django 1.8 (patch) • Django 1.7 (patch) • Django 1.4 (patch) November 24, 2015 - CVE-2015-8213 Settings leak possibility in date template filter. Full description

1716

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Versions affected • Django 1.8 (patch) • Django 1.7 (patch) February 1, 2016 - CVE-2016-2048 User with “change” but not “add” permission can create objects for ModelAdmin’s with save_as=True. Full description Versions affected • Django 1.9 (patch) March 1, 2016 - CVE-2016-2512 Malicious redirect and possible XSS attack via user-supplied redirect URLs containing basic auth. Full description Versions affected • Django 1.9 (patch) • Django 1.8 (patch) March 1, 2016 - CVE-2016-2513 User enumeration through timing difference on password hasher work factor upgrade. Full description Versions affected • Django 1.9 (patch) • Django 1.8 (patch) July 18, 2016 - CVE-2016-6186 XSS in admin’s add/change related popup. Full description Versions affected • Django 1.9 (patch) • Django 1.8 (patch)

9.2. Security releases

1717

Django Documentation, Release 2.1.dev20171115023625

September 26, 2016 - CVE-2016-7401 CSRF protection bypass on a site with Google Analytics. Full description Versions affected • Django 1.9 (patch) • Django 1.8 (patch) November 1, 2016 - CVE-2016-9013 User with hardcoded password created when running tests on Oracle. Full description Versions affected • Django 1.10 (patch) • Django 1.9 (patch) • Django 1.8 (patch) November 1, 2016 - CVE-2016-9014 DNS rebinding vulnerability when DEBUG=True. Full description Versions affected • Django 1.10 (patch) • Django 1.9 (patch) • Django 1.8 (patch) April 4, 2017 - CVE-2017-7233 Open redirect and possible XSS attack via user-supplied numeric redirect URLs. Full description Versions affected • Django 1.10 (patch) • Django 1.9 (patch) • Django 1.8 (patch) April 4, 2017 - CVE-2017-7234 Open redirect vulnerability in django.views.static.serve(). Full description

1718

Chapter 9. Release notes

Django Documentation, Release 2.1.dev20171115023625

Versions affected • Django 1.10 (patch) • Django 1.9 (patch) • Django 1.8 (patch) September 5, 2017 - CVE-2017-12794 Possible XSS in traceback section of technical 500 debug page. Full description Versions affected • Django 1.11 (patch) • Django 1.10 (patch)

9.2. Security releases

1719

Django Documentation, Release 2.1.dev20171115023625

1720

Chapter 9. Release notes

CHAPTER

10

Django internals

Documentation for people hacking on Django itself. This is the place to go if you’d like to help improve Django or learn about how Django is managed.

10.1 Contributing to Django Django is a community that lives on its volunteers. As it keeps growing, we always need more people to help others. As soon as you learn Django, you can contribute in many ways: • Join the django-users mailing list and answer questions. This mailing list has a huge audience, and we really want to maintain a friendly and helpful atmosphere. If you’re new to the Django community, you should read the posting guidelines. • Join the #django IRC channel on Freenode and answer questions. By explaining Django to other users, you’re going to learn a lot about the framework yourself. • Blog about Django. We syndicate all the Django blogs we know about on the community page; if you’d like to see your blog on that page you can register it here. • Contribute to open-source Django projects, write some documentation, or release your own code as an opensource pluggable application. The ecosystem of pluggable applications is a big strength of Django, help us build it! If you think working with Django is fun, wait until you start working on it. We’re passionate about helping Django users make the jump to contributing members of the community, so there are several ways you can help Django’s development: • Report bugs in our ticket tracker. • Join the django-developers mailing list and share your ideas for how to improve Django. We’re always open to suggestions. • Submit patches for new and/or fixed behavior. If you’re looking for an easy way to start contributing to Django read the Writing your first patch for Django tutorial and have a look at the easy pickings tickets. The Patch review checklist will also be helpful.

1721

Django Documentation, Release 2.1.dev20171115023625

• Improve the documentation or write unit tests. • Triage tickets and review patches created by other users. Really, ANYONE can do something to help make Django better and greater! Browse the following sections to find out how:

10.1.1 Advice for new contributors New contributor and not sure what to do? Want to help but just don’t know how to get started? This is the section for you. Basic tools and workflow If you are new to contributing to Django, the Writing your first patch for Django tutorial will give you an introduction to the tools and the workflow.

First steps Start with these easy tasks to discover Django’s development process. • Sign the Contributor License Agreement The code that you write belongs to you or your employer. If your contribution is more than one or two lines of code, you need to sign the CLA. See the Contributor License Agreement FAQ for a more thorough explanation. • Triage tickets If an unreviewed ticket reports a bug, try and reproduce it. If you can reproduce it and it seems valid, make a note that you confirmed the bug and accept the ticket. Make sure the ticket is filed under the correct component area. Consider writing a patch that adds a test for the bug’s behavior, even if you don’t fix the bug itself. See more at How can I help with triaging? • Look for tickets that are accepted and review patches to build familiarity with the codebase and the process Mark the appropriate flags if a patch needs docs or tests. Look through the changes a patch makes, and keep an eye out for syntax that is incompatible with older but still supported versions of Python. Run the tests and make sure they pass. Where possible and relevant, try them out on a database other than SQLite. Leave comments and feedback! • Keep old patches up to date Oftentimes the codebase will change between a patch being submitted and the time it gets reviewed. Make sure it still applies cleanly and functions as expected. Simply updating a patch is both useful and important! See more on Submitting patches. • Write some documentation Django’s documentation is great but it can always be improved. Did you find a typo? Do you think that something should be clarified? Go ahead and suggest a documentation patch! See also the guide on Writing documentation. Note: The reports page contains links to many useful Trac queries, including several that are useful for triaging tickets and reviewing patches as suggested above.

1722

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

Guidelines As a newcomer on a large project, it’s easy to experience frustration. Here’s some advice to make your work on Django more useful and rewarding. • Pick a subject area that you care about, that you are familiar with, or that you want to learn about You don’t already have to be an expert on the area you want to work on; you become an expert through your ongoing contributions to the code. • Analyze tickets’ context and history Trac isn’t an absolute; the context is just as important as the words. When reading Trac, you need to take into account who says things, and when they were said. Support for an idea two years ago doesn’t necessarily mean that the idea will still have support. You also need to pay attention to who hasn’t spoken – for example, if an experienced contributor hasn’t been recently involved in a discussion, then a ticket may not have the support required to get into Django. • Start small It’s easier to get feedback on a little issue than on a big one. See the easy pickings. • If you’re going to engage in a big task, make sure that your idea has support first This means getting someone else to confirm that a bug is real before you fix the issue, and ensuring that there’s consensus on a proposed feature before you go implementing it. • Be bold! Leave feedback! Sometimes it can be scary to put your opinion out to the world and say “this ticket is correct” or “this patch needs work”, but it’s the only way the project moves forward. The contributions of the broad Django community ultimately have a much greater impact than that of any one person. We can’t do it without you! • Err on the side of caution when marking things Ready For Check-in If you’re really not certain if a ticket is ready, don’t mark it as such. Leave a comment instead, letting others know your thoughts. If you’re mostly certain, but not completely certain, you might also try asking on IRC to see if someone else can confirm your suspicions. • Wait for feedback, and respond to feedback that you receive Focus on one or two tickets, see them through from start to finish, and repeat. The shotgun approach of taking on lots of tickets and letting some fall by the wayside ends up doing more harm than good. • Be rigorous When we say “PEP 8, and must have docs and tests”, we mean it. If a patch doesn’t have docs and tests, there had better be a good reason. Arguments like “I couldn’t find any existing tests of this feature” don’t carry much weight–while it may be true, that means you have the extra-important job of writing the very first tests for that feature, not that you get a pass from writing tests altogether. FAQ 1. This ticket I care about has been ignored for days/weeks/months! What can I do to get it committed? First off, it’s not personal. Django is entirely developed by volunteers (except the Django fellow), and sometimes folks just don’t have time. The best thing to do is to send a gentle reminder to the django-developers mailing list asking for review on the ticket, or to bring it up in the #django-dev IRC channel. 2. I’m sure my ticket is absolutely 100% perfect, can I mark it as RFC myself? Short answer: No. It’s always better to get another set of eyes on a ticket. If you’re having trouble getting that second set of eyes, see question 1, above. 10.1. Contributing to Django

1723

Django Documentation, Release 2.1.dev20171115023625

10.1.2 Reporting bugs and requesting features Important: Please report security issues only to [emailprotected] This is a private list only open to long-time, highly trusted Django developers, and its archives are not public. For further details, please see our security policies. Otherwise, before reporting a bug or requesting a new feature on the ticket tracker, consider these points: • Check that someone hasn’t already filed the bug or feature request by searching or running custom queries in the ticket tracker. • Don’t use the ticket system to ask support questions. Use the django-users list or the #django IRC channel for that. • Don’t reopen issues that have been marked “wontfix” without finding consensus to do so on django-developers. • Don’t use the ticket tracker for lengthy discussions, because they’re likely to get lost. If a particular ticket is controversial, please move the discussion to django-developers. Reporting bugs Well-written bug reports are incredibly helpful. However, there’s a certain amount of overhead involved in working with any bug tracking system so your help in keeping our ticket tracker as useful as possible is appreciated. In particular: • Do read the FAQ to see if your issue might be a well-known question. • Do ask on django-users or #django first if you’re not sure if what you’re seeing is a bug. • Do write complete, reproducible, specific bug reports. You must include a clear, concise description of the problem, and a set of instructions for replicating it. Add as much debug information as you can: code snippets, test cases, exception backtraces, screenshots, etc. A nice small test case is the best way to report a bug, as it gives us an easy way to confirm the bug quickly. • Don’t post to django-developers just to announce that you have filed a bug report. All the tickets are mailed to another list, django-updates, which is tracked by developers and interested community members; we see them as they are filed. To understand the lifecycle of your ticket once you have created it, refer to Triaging tickets. Reporting user interface bugs and features If your bug or feature request touches on anything visual in nature, there are a few additional guidelines to follow: • Include screenshots in your ticket which are the visual equivalent of a minimal testcase. Show off the issue, not the crazy customizations you’ve made to your browser. • If the issue is difficult to show off using a still image, consider capturing a brief screencast. If your software permits it, capture only the relevant area of the screen. • If you’re offering a patch which changes the look or behavior of Django’s UI, you must attach before and after screenshots/screencasts. Tickets lacking these are difficult for triagers to assess quickly. • Screenshots don’t absolve you of other good reporting practices. Make sure to include URLs, code snippets, and step-by-step instructions on how to reproduce the behavior visible in the screenshots. • Make sure to set the UI/UX flag on the ticket so interested parties can find your ticket.

1724

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

Requesting features We’re always trying to make Django better, and your feature requests are a key part of that. Here are some tips on how to make a request most effectively: • Make sure the feature actually requires changes in Django’s core. If your idea can be developed as an independent application or module — for instance, you want to support another database engine — we’ll probably suggest that you to develop it independently. Then, if your project gathers sufficient community support, we may consider it for inclusion in Django. • First request the feature on the django-developers list, not in the ticket tracker. It’ll get read more closely if it’s on the mailing list. This is even more important for large-scale feature requests. We like to discuss any big changes to Django’s core on the mailing list before actually working on them. • Describe clearly and concisely what the missing feature is and how you’d like to see it implemented. Include example code (non-functional is OK) if possible. • Explain why you’d like the feature. In some cases this is obvious, but since Django is designed to help real developers get real work done, you’ll need to explain it, if it isn’t obvious why the feature would be useful. If there’s a consensus agreement on the feature, then it’s appropriate to create a ticket. Include a link the discussion on django-developers in the ticket description. As with most open-source projects, code talks. If you are willing to write the code for the feature yourself or, even better, if you’ve already written it, it’s much more likely to be accepted. Just fork Django on GitHub, create a feature branch, and show us your work! See also: Documenting new features. How we make decisions Whenever possible, we strive for a rough consensus. To that end, we’ll often have informal votes on django-developers about a feature. In these votes we follow the voting style invented by Apache and used on Python itself, where votes are given as +1, +0, -0, or -1. Roughly translated, these votes mean: • +1: “I love the idea and I’m strongly committed to it.” • +0: “Sounds OK to me.” • -0: “I’m not thrilled, but I won’t stand in the way.” • -1: “I strongly disagree and would be very unhappy to see the idea turn into reality.” Although these votes on django-developers are informal, they’ll be taken very seriously. After a suitable voting period, if an obvious consensus arises we’ll follow the votes. However, consensus is not always possible. If consensus cannot be reached, or if the discussion towards a consensus fizzles out without a concrete decision, the decision may be deferred to the technical board. Internally, the technical board will use the same voting mechanism. A proposition will be considered carried if: • There are at least three “+1” votes from members of the technical board. • There is no “-1” vote from any member of the technical board. Votes should be submitted within a week. Since this process allows any technical board member to veto a proposal, a “-1” vote should be accompanied by an explanation of what it would take to convert that “-1” into at least a “+0”. Votes on technical matters should be announced and held in public on the django-developers mailing list.

10.1. Contributing to Django

1725

Django Documentation, Release 2.1.dev20171115023625

10.1.3 Triaging tickets Django uses Trac for managing the work on the code base. Trac is a community-tended garden of the bugs people have found and the features people would like to see added. As in any garden, sometimes there are weeds to be pulled and sometimes there are flowers and vegetables that need picking. We need your help to sort out one from the other, and in the end we all benefit together. Like all gardens, we can aspire to perfection but in reality there’s no such thing. Even in the most pristine garden there are still snails and insects. In a community garden there are also helpful people who – with the best of intentions – fertilize the weeds and poison the roses. It’s the job of the community as a whole to self-manage, keep the problems to a minimum, and educate those coming into the community so that they can become valuable contributing members. Similarly, while we aim for Trac to be a perfect representation of the state of Django’s progress, we acknowledge that this simply will not happen. By distributing the load of Trac maintenance to the community, we accept that there will be mistakes. Trac is “mostly accurate”, and we give allowances for the fact that sometimes it will be wrong. That’s okay. We’re perfectionists with deadlines. We rely on the community to keep participating, keep tickets as accurate as possible, and raise issues for discussion on our mailing lists when there is confusion or disagreement. Django is a community project, and every contribution helps. We can’t do this without you! Triage workflow Unfortunately, not all bug reports and feature requests in the ticket tracker provide all the required details. A number of tickets have patches, but those patches don’t meet all the requirements of a good patch. One way to help out is to triage tickets that have been created by other users. Most of the workflow is based around the concept of a ticket’s triage stages. Each stage describes where in its lifetime a given ticket is at any time. Along with a handful of flags, this attribute easily tells us what and who each ticket is waiting on. Since a picture is worth a thousand words, let’s start there:

1726

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

The ticket is a bug and should be fixed.

The ticket was already reported, was already rejected, isn't a bug, doesn't contain enough information, or can't be reproduced.

Open tickets

Closed tickets

triage state

resolution

Unreviewed

duplicate wontfix invalid

Accepted needsinfo worksforme Ready for Checkin

fixed

The ticket has a patch which applies cleanly and includes all needed tests and docs. A core developer can commit it as is. Ticket triagers Committers

status in progress

stopped completed

We’ve got two roles in this diagram: • Committers: people with commit access who are responsible for making the final decision to merge a patch. • Ticket triagers: anyone in the Django community who chooses to become involved in Django’s development process. Our Trac installation is intentionally left open to the public, and anyone can triage tickets. Django is a community project, and we encourage triage by the community. By way of example, here we see the lifecycle of an average ticket: • Alice creates a ticket and sends an incomplete pull request (no tests, incorrect implementation). • Bob reviews the pull request, marks the ticket as “Accepted”, “needs tests”, and “patch needs improvement”, and leaves a comment telling Alice how the patch could be improved. • Alice updates the pull request, adding tests (but not changing the implementation). She removes the two flags. • Charlie reviews the pull request and resets the “patch needs improvement” flag with another comment about improving the implementation. • Alice updates the pull request, fixing the implementation. She removes the “patch needs improvement” flag. • Daisy reviews the pull request and marks the ticket as “Ready for checkin”. • Jacob, a committer, reviews the pull request and merges it. Some tickets require much less feedback than this, but then again some tickets require much much more.

10.1. Contributing to Django

1727

Django Documentation, Release 2.1.dev20171115023625

Triage stages Below we describe in more detail the various stages that a ticket may flow through during its lifetime. Unreviewed The ticket has not been reviewed by anyone who felt qualified to make a judgment about whether the ticket contained a valid issue, a viable feature, or ought to be closed for any of the various reasons. Accepted The big gray area! The absolute meaning of “accepted” is that the issue described in the ticket is valid and is in some stage of being worked on. Beyond that there are several considerations: • Accepted + No Flags The ticket is valid, but no one has submitted a patch for it yet. Often this means you could safely start writing a patch for it. This is generally more true for the case of accepted bugs than accepted features. A ticket for a bug that has been accepted means that the issue has been verified by at least one triager as a legitimate bug and should probably be fixed if possible. An accepted new feature may only mean that one triager thought the feature would be good to have, but this alone does not represent a consensus view or imply with any certainty that a patch will be accepted for that feature. Seek more feedback before writing an extensive patch if you are in doubt. • Accepted + Has Patch The ticket is waiting for people to review the supplied patch. This means downloading the patch and trying it out, verifying that it contains tests and docs, running the test suite with the included patch, and leaving feedback on the ticket. • Accepted + Has Patch + Needs ... This means the ticket has been reviewed, and has been found to need further work. “Needs tests” and “Needs documentation” are self-explanatory. “Patch needs improvement” will generally be accompanied by a comment on the ticket explaining what is needed to improve the code. Ready For Checkin The ticket was reviewed by any member of the community other than the person who supplied the patch and found to meet all the requirements for a commit-ready patch. A committer now needs to give the patch a final review prior to being committed. See the New contributors’ FAQ for “My ticket has been in RFC forever! What should I do?” Someday/Maybe This stage isn’t shown on the diagram. It’s used sparingly to keep track of high-level ideas or long term feature requests. These tickets are uncommon and overall less useful since they don’t describe concrete actionable issues. They are enhancement requests that we might consider adding someday to the framework if an excellent patch is submitted. They are not a high priority.

1728

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

Other triage attributes A number of flags, appearing as checkboxes in Trac, can be set on a ticket: Has patch This means the ticket has an associated patch. These will be reviewed to see if the patch is “good”. The following three fields (Needs documentation, Needs tests, Patch needs improvement) apply only if a patch has been supplied. Needs documentation This flag is used for tickets with patches that need associated documentation. Complete documentation of features is a prerequisite before we can check them into the codebase. Needs tests This flags the patch as needing associated unit tests. Again, this is a required part of a valid patch. Patch needs improvement This flag means that although the ticket has a patch, it’s not quite ready for checkin. This could mean the patch no longer applies cleanly, there is a flaw in the implementation, or that the code doesn’t meet our standards. Easy pickings Tickets that would require small, easy, patches. Type Tickets should be categorized by type between: • New Feature For adding something new. • Bug For when an existing thing is broken or not behaving as expected. • Cleanup/optimization For when nothing is broken but something could be made cleaner, better, faster, stronger. Component Tickets should be classified into components indicating which area of the Django codebase they belong to. This makes tickets better organized and easier to find.

10.1. Contributing to Django

1729

Django Documentation, Release 2.1.dev20171115023625

Severity The severity attribute is used to identify blockers, that is, issues which should get fixed before releasing the next version of Django. Typically those issues are bugs causing regressions from earlier versions or potentially causing severe data losses. This attribute is quite rarely used and the vast majority of tickets have a severity of “Normal”. Version It is possible to use the version attribute to indicate in which version the reported bug was identified. UI/UX This flag is used for tickets that relate to User Interface and User Experiences questions. For example, this flag would be appropriate for user-facing features in forms or the admin interface. Cc You may add your username or email address to this field to be notified when new contributions are made to the ticket. Keywords With this field you may label a ticket with multiple keywords. This can be useful, for example, to group several tickets of a same theme. Keywords can either be comma or space separated. Keyword search finds the keyword string anywhere in the keywords. For example, clicking on a ticket with the keyword “form” will yield similar tickets tagged with keywords containing strings such as “formset”, “modelformset”, and “ManagementForm”. Closing Tickets When a ticket has completed its useful lifecycle, it’s time for it to be closed. Closing a ticket is a big responsibility, though. You have to be sure that the issue is really resolved, and you need to keep in mind that the reporter of the ticket may not be happy to have their ticket closed (unless it’s fixed, of course). If you’re not certain about closing a ticket, just leave a comment with your thoughts instead. If you do close a ticket, you should always make sure of the following: • Be certain that the issue is resolved. • Leave a comment explaining the decision to close the ticket. • If there is a way they can improve the ticket to reopen it, let them know. • If the ticket is a duplicate, reference the original ticket. Also cross-reference the closed ticket by leaving a comment in the original one – this allows to access more related information about the reported bug or requested feature. • Be polite. No one likes having their ticket closed. It can be frustrating or even discouraging. The best way to avoid turning people off from contributing to Django is to be polite and friendly and to offer suggestions for how they could improve this ticket and other tickets in the future. A ticket can be resolved in a number of ways: • fixed Used once a patch has been rolled into Django and the issue is fixed.

1730

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

• invalid Used if the ticket is found to be incorrect. This means that the issue in the ticket is actually the result of a user error, or describes a problem with something other than Django, or isn’t a bug report or feature request at all (for example, some new users submit support queries as tickets). • wontfix Used when a someone decides that the request isn’t appropriate for consideration in Django. Sometimes a ticket is closed as “wontfix” with a request for the reporter to start a discussion on the djangodevelopers mailing list if they feel differently from the rationale provided by the person who closed the ticket. Other times, a mailing list discussion precedes the decision to close a ticket. Always use the mailing list to get a consensus before reopening tickets closed as “wontfix”. • duplicate Used when another ticket covers the same issue. By closing duplicate tickets, we keep all the discussion in one place, which helps everyone. • worksforme Used when the ticket doesn’t contain enough detail to replicate the original bug. • needsinfo Used when the ticket does not contain enough information to replicate the reported issue but is potentially still valid. The ticket should be reopened when more information is supplied. If you believe that the ticket was closed in error – because you’re still having the issue, or it’s popped up somewhere else, or the triagers have made a mistake – please reopen the ticket and provide further information. Again, please do not reopen tickets that have been marked as “wontfix” and bring the issue to django-developers instead. How can I help with triaging? The triage process is primarily driven by community members. Really, ANYONE can help. To get involved, start by creating an account on Trac. If you have an account but have forgotten your password, you can reset it using the password reset page. Then, you can help out by: • Closing “Unreviewed” tickets as “invalid”, “worksforme”, or “duplicate”, or “wontfix”. • Closing “Unreviewed” tickets as “needsinfo” when the description is too sparse to be actionable, or when they’re feature requests requiring a discussion on django-developers. • Correcting the “Needs tests”, “Needs documentation”, or “Has patch” flags for tickets where they are incorrectly set. • Setting the “Easy pickings” flag for tickets that are small and relatively straightforward. • Set the type of tickets that are still uncategorized. • Checking that old tickets are still valid. If a ticket hasn’t seen any activity in a long time, it’s possible that the problem has been fixed but the ticket hasn’t yet been closed. • Identifying trends and themes in the tickets. If there are a lot of bug reports about a particular part of Django, it may indicate we should consider refactoring that part of the code. If a trend is emerging, you should raise it for discussion (referencing the relevant tickets) on django-developers. • Verify if patches submitted by other users are correct. If they are correct and also contain appropriate documentation and tests then move them to the “Ready for Checkin” stage. If they are not correct then leave a comment to explain why and set the corresponding flags (“Patch needs improvement”, “Needs tests” etc.). Note: The Reports page contains links to many useful Trac queries, including several that are useful for triaging tickets and reviewing patches as suggested above. You can also find more Advice for new contributors. However, we do ask the following of all general community members working in the ticket database:

10.1. Contributing to Django

1731

Django Documentation, Release 2.1.dev20171115023625

• Please don’t promote your own tickets to “Ready for checkin”. You may mark other people’s tickets which you’ve reviewed as “Ready for checkin”, but you should get at minimum one other community member to review a patch that you submit. • Please don’t reverse a decision without posting a message to django-developers to find consensus. • If you’re unsure if you should be making a change, don’t make the change but instead leave a comment with your concerns on the ticket, or post a message to django-developers. It’s okay to be unsure, but your input is still valuable. Bisecting a regression A regression is a bug that’s present in some newer version of Django but not in an older one. An extremely helpful piece of information is the commit that introduced the regression. Knowing the commit that caused the change in behavior helps identify if the change was intentional or if it was an inadvertent side-effect. Here’s how you can determine this. Begin by writing a regression test for Django’s test suite for the issue. For example, we’ll pretend we’re debugging a regression in migrations. After you’ve written the test and confirmed that it fails on the latest master, put it in a separate file that you can run standalone. For our example, we’ll pretend we created tests/migrations/ test_regression.py, which can be run with: $ ./runtests.py migrations.test_regression

Next, we mark the current point in history as being “bad” since the test fails: $ git bisect bad You need to start by "git bisect start" Do you want me to do it for you [Y/n]? y

Now, we need to find a point in git history before the regression was introduced (i.e. a point where the test passes). Use something like git checkout HEAD~100 to checkout an earlier revision (100 commits earlier, in this case). Check if the test fails. If so, mark that point as “bad” (git bisect bad), then checkout an earlier revision and recheck. Once you find a revision where your test passes, mark it as “good”: $ git bisect good Bisecting: X revisions left to test after this (roughly Y steps) ...

Now we’re ready for the fun part: using git bisect run to automate the rest of the process: $ git bisect run tests/runtests.py migrations.test_regression

You should see git bisect use a binary search to automatically checkout revisions between the good and bad commits until it finds the first “bad” commit where the test fails. Now, report your results on the Trac ticket, and please include the regression test as an attachment. When someone writes a fix for the bug, they’ll already have your test as a starting point.

10.1.4 Writing code So you’d like to write some code to improve Django. Awesome! Browse the following sections to find out how to give your code patches the best chances to be included in Django core:

1732

(Video) What is ChatGPT and How You Can Use It

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

Coding style Please follow these coding standards when writing code for inclusion in Django. Python style • Please conform to the indentation style dictated in the .editorconfig file. We recommend using a text editor with EditorConfig support to avoid indentation and whitespace issues. The Python files use 4 spaces for indentation and the HTML files use 2 spaces. • Unless otherwise specified, follow PEP 8. Use flake8 to check for problems in this area. Note that our setup.cfg file contains some excluded files (deprecated modules we don’t care about cleaning up and some third-party code that Django vendors) as well as some excluded errors that we don’t consider as gross violations. Remember that PEP 8 is only a guide, so respect the style of the surrounding code as a primary goal. An exception to PEP 8 is our rules on line lengths. Don’t limit lines of code to 79 characters if it means the code looks significantly uglier or is harder to read. We allow up to 119 characters as this is the width of GitHub code review; anything longer requires horizontal scrolling which makes review more difficult. This check is included when you run flake8. Documentation, comments, and docstrings should be wrapped at 79 characters, even though PEP 8 suggests 72. • Use four spaces for indentation. • Use four space hanging indentation rather than vertical alignment: raise AttributeError( 'Here is a multine error message ' 'shortened for clarity.' )

Instead of: raise AttributeError('Here is a multine error message ' 'shortened for clarity.')

This makes better use of space and avoids having to realign strings if the length of the first line changes. • Use single quotes for strings, or a double quote if the the string contains a single quote. Don’t waste time doing unrelated refactoring of existing code to conform to this style. • Avoid use of “we” in comments, e.g. “Loop over” rather than “We loop over”. • Use underscores, not camelCase, for variable, function and method names (i.e. get_unique_voters(), not poll.getUniqueVoters()).

poll.

• Use InitialCaps for class names (or for factory functions that return classes). • In docstrings, follow the style of existing docstrings and PEP 257. • In tests, use assertRaisesMessage() instead of assertRaises() so you can check the exception message. Use assertRaisesRegex() only if you need regular expression matching. • In test docstrings, state the expected behavior that each test demonstrates. Don’t include preambles such as “Tests that” or “Ensures that”. Reserve ticket references for obscure issues where the ticket has additional details that can’t be easily described in docstrings or comments. Include the ticket number at the end of a sentence like this:

10.1. Contributing to Django

1733

Django Documentation, Release 2.1.dev20171115023625

def test_foo(): """ A test docstring looks like this (#123456). """ ...

Imports • Use isort to automate import sorting using the guidelines below. Quick start: $ pip install isort $ isort -rc .

This runs isort recursively from your current directory, modifying any files that don’t conform to the guidelines. If you need to have imports out of order (to avoid a circular import, for example) use a comment like this: import module

# isort:skip

• Put imports in these groups: future, standard library, third-party libraries, other Django components, local Django component, try/excepts. Sort lines in each group alphabetically by the full module name. Place all import module statements before from module import objects in each section. Use absolute imports for other Django components and relative imports for local components. • On each line, alphabetize the items with the upper case items grouped before the lower case items. • Break long lines using parentheses and indent continuation lines by 4 spaces. Include a trailing comma after the last import and put the closing parenthesis on its own line. Use a single blank line between the last import and any module level code, and use two blank lines above the first function or class. For example (comments are for explanatory purposes only): django/contrib/admin/example.py # future from __future__ import unicode_literals # standard library import json from itertools import chain # third-party import bcrypt # Django from django.http import Http404 from django.http.response import ( Http404, HttpResponse, HttpResponseNotAllowed, StreamingHttpResponse, cookie, ) # local Django from .models import LogEntry

1734

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

# try/except try: import yaml except ImportError: yaml = None CONSTANT = 'foo'

class Example: # ...

• Use convenience imports whenever available. For example, do this: from django.views import View

instead of: from django.views.generic.base import View

Template style • In Django template code, put one (and only one) space between the curly brackets and the tag contents. Do this: {{ foo }}

Don’t do this: {{foo}}

View style • In Django views, the first parameter in a view function should be called request. Do this: def my_view(request, foo): # ...

Don’t do this: def my_view(req, foo): # ...

Model style • Field names should be all lowercase, using underscores instead of camelCase. Do this: class Person(models.Model): first_name = models.CharField(max_length=20) last_name = models.CharField(max_length=40)

10.1. Contributing to Django

1735

Django Documentation, Release 2.1.dev20171115023625

Don’t do this: class Person(models.Model): FirstName = models.CharField(max_length=20) Last_Name = models.CharField(max_length=40)

• The class Meta should appear after the fields are defined, with a single blank line separating the fields and the class definition. Do this: class Person(models.Model): first_name = models.CharField(max_length=20) last_name = models.CharField(max_length=40) class Meta: verbose_name_plural = 'people'

Don’t do this: class Person(models.Model): first_name = models.CharField(max_length=20) last_name = models.CharField(max_length=40) class Meta: verbose_name_plural = 'people'

Don’t do this, either: class Person(models.Model): class Meta: verbose_name_plural = 'people' first_name = models.CharField(max_length=20) last_name = models.CharField(max_length=40)

• The order of model inner classes and standard methods should be as follows (noting that these are not all required): – All database fields – Custom manager attributes – class Meta – def __str__() – def save() – def get_absolute_url() – Any custom methods • If choices is defined for a given model field, define each choice as a tuple of tuples, with an all-uppercase name as a class attribute on the model. Example: class MyModel(models.Model): DIRECTION_UP = 'U' DIRECTION_DOWN = 'D' DIRECTION_CHOICES = ( (DIRECTION_UP, 'Up'), (DIRECTION_DOWN, 'Down'), )

1736

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

Use of django.conf.settings Modules should not in general use settings stored in django.conf.settings at the top level (i.e. evaluated when the module is imported). The explanation for this is as follows: Manual configuration of settings (i.e. not relying on the DJANGO_SETTINGS_MODULE environment variable) is allowed and possible as follows: from django.conf import settings settings.configure({}, SOME_SETTING='foo')

However, if any setting is accessed before the settings.configure line, this will not work. (Internally, settings is a LazyObject which configures itself automatically when the settings are accessed if it has not already been configured). So, if there is a module containing some code as follows: from django.conf import settings from django.urls import get_callable default_foo_view = get_callable(settings.FOO_VIEW)

...then importing this module will cause the settings object to be configured. That means that the ability for third parties to import the module at the top level is incompatible with the ability to configure the settings object manually, or makes it very difficult in some circumstances. Instead of the above code, a level of laziness or indirection must be used, such as django.utils.functional. LazyObject, django.utils.functional.lazy() or lambda. Miscellaneous • Mark all strings for internationalization; see the i18n documentation for details. • Remove import statements that are no longer used when you change code. flake8 will identify these imports for you. If an unused import needs to remain for backwards-compatibility, mark the end of with # NOQA to silence the flake8 warning. • Systematically remove all trailing whitespaces from your code as those add unnecessary bytes, add visual clutter to the patches and can also occasionally cause unnecessary merge conflicts. Some IDE’s can be configured to automatically remove them and most VCS tools can be set to highlight them in diff outputs. • Please don’t put your name in the code you contribute. Our policy is to keep contributors’ names in the AUTHORS file distributed with Django – not scattered throughout the codebase itself. Feel free to include a change to the AUTHORS file in your patch if you make more than a single trivial change. JavaScript style For details about the JavaScript code style used by Django, see JavaScript.

10.1. Contributing to Django

1737

Django Documentation, Release 2.1.dev20171115023625

Unit tests Django comes with a test suite of its own, in the tests directory of the code base. It’s our policy to make sure all tests pass at all times. We appreciate any and all contributions to the test suite! The Django tests all use the testing infrastructure that ships with Django for testing applications. See Writing and running tests for an explanation of how to write new tests. Running the unit tests Quickstart First, fork Django on GitHub. Second, create and activate a virtual environment. If you’re not familiar with how to do that, read our contributing tutorial. Next, clone your fork, install some requirements, and run the tests: $ $ $ $ $

git clone [emailprotected]:YourGitHubName/django.git django-repo cd django-repo/tests pip install -e .. pip install -r requirements/py3.txt ./runtests.py

Installing the requirements will likely require some operating system packages that your computer doesn’t have installed. You can usually figure out which package to install by doing a Web search for the last line or so of the error message. Try adding your operating system to the search query if needed. If you have trouble installing the requirements, you can skip that step. See Running all the tests for details on installing the optional test dependencies. If you don’t have an optional dependency installed, the tests that require it will be skipped. Running the tests requires a Django settings module that defines the databases to use. To make it easy to get started, Django provides and uses a sample settings module that uses the SQLite database. See Using another settings module to learn how to use a different settings module to run the tests with a different database. Windows users We recommend something like Git Bash to run the tests using the above approach. Having problems? See Troubleshooting for some common issues. Running tests using tox Tox is a tool for running tests in different virtual environments. Django includes a basic tox.ini that automates some checks that our build server performs on pull requests. To run the unit tests and other checks (such as import sorting, the documentation spelling checker, and code formatting), install and run the tox command from any place in the Django source tree: $ pip install tox $ tox

1738

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

By default, tox runs the test suite with the bundled test settings file for SQLite, flake8, isort, and the documentation spelling checker. In addition to the system dependencies noted elsewhere in this documentation, the command python3 must be on your path and linked to the appropriate version of Python. A list of default environments can be seen as follows: $ tox -l py3 flake8 docs isort

Testing other Python versions and database backends In addition to the default environments, tox supports running unit tests for other versions of Python and other database backends. Since Django’s test suite doesn’t bundle a settings file for database backends other than SQLite, however, you must create and provide your own test settings. For example, to run the tests on Python 3.5 using PostgreSQL: $ tox -e py35-postgres -- --settings=my_postgres_settings

This command sets up a Python 3.5 virtual environment, installs Django’s test suite dependencies (including those for PostgreSQL), and calls runtests.py with the supplied arguments (in this case, --settings=my_postgres_settings). The remainder of this documentation shows commands for running tests without tox, however, any option passed to runtests.py can also be passed to tox by prefixing the argument list with --, as above. Tox also respects the DJANGO_SETTINGS_MODULE environment variable, if set. For example, the following is equivalent to the command above: $ DJANGO_SETTINGS_MODULE=my_postgres_settings tox -e py35-postgres

Running the JavaScript tests Django includes a set of JavaScript unit tests for functions in certain contrib apps. The JavaScript tests aren’t run by default using tox because they require Node.js to be installed and aren’t necessary for the majority of patches. To run the JavaScript tests using tox: $ tox -e javascript

This command runs npm install to ensure test requirements are up to date and then runs npm test. Using another settings module The included settings module (tests/test_sqlite.py) allows you to run the test suite using SQLite. If you want to run the tests using a different database, you’ll need to define your own settings file. Some tests, such as those for contrib.postgres, are specific to a particular database backend and will be skipped if run with a different backend. To run the tests with different settings, ensure that the module is on your PYTHONPATH and pass the module with --settings. The DATABASES setting in any test settings module needs to define two databases: • A default database. This database should use the backend that you want to use for primary testing. 10.1. Contributing to Django

1739

Django Documentation, Release 2.1.dev20171115023625

• A database with the alias other. The other database is used to test that queries can be directed to different databases. This database should use the same backend as the default, and it must have a different name. If you’re using a backend that isn’t SQLite, you will need to provide other details for each database: • The USER option needs to specify an existing user account for the database. That user needs permission to execute CREATE DATABASE so that the test database can be created. • The PASSWORD option needs to provide the password for the USER that has been specified. Test databases get their names by prepending test_ to the value of the NAME settings for the databases defined in DATABASES. These test databases are deleted when the tests are finished. You will also need to ensure that your database uses UTF-8 as the default character set. If your database server doesn’t use UTF-8 as a default charset, you will need to include a value for CHARSET in the test settings dictionary for the applicable database. Running only some of the tests Django’s entire test suite takes a while to run, and running every single test could be redundant if, say, you just added a test to Django that you want to run quickly without running everything else. You can run a subset of the unit tests by appending the names of the test modules to runtests.py on the command line. For example, if you’d like to run tests only for generic relations and internationalization, type: $ ./runtests.py --settings=path.to.settings generic_relations i18n

How do you find out the names of individual tests? Look in tests/ — each directory name there is the name of a test. If you just want to run a particular class of tests, you can specify a list of paths to individual test classes. For example, to run the TranslationTests of the i18n module, type: $ ./runtests.py --settings=path.to.settings i18n.tests.TranslationTests

Going beyond that, you can specify an individual test method like this: $ ./runtests.py --settings=path.to.settings i18n.tests.TranslationTests.test_lazy_ ˓→objects

Running the Selenium tests Some tests require Selenium and a Web browser. To run these tests, you must install the selenium package and run the tests with the --selenium= option. For example, if you have Firefox and Google Chrome installed: $ ./runtests.py --selenium=firefox,chrome

See the selenium.webdriver package for the list of available browsers. Specifying --selenium automatically sets --tags=selenium to run only the tests that require selenium. Running all the tests If you want to run the full suite of tests, you’ll need to install a number of dependencies: • argon2-cffi 16.1.0+

1740

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

• bcrypt • docutils • geoip2 • jinja2 2.7+ • numpy • Pillow • PyYAML • pytz (required) • setuptools • memcached, plus a supported Python binding • gettext (gettext on Windows) • selenium • sqlparse You can find these dependencies in pip requirements files inside the tests/requirements directory of the Django source tree and install them like so: $ pip install -r tests/requirements/py3.txt

If you encounter an error during the installation, your system might be missing a dependency for one or more of the Python packages. Consult the failing package’s documentation or search the Web with the error message that you encounter. You can also install the database adapter(s) of your choice using oracle.txt, mysql.txt, or postgres.txt. If you want to test the memcached cache backend, you’ll also need to define a CACHES setting that points at your memcached instance. To run the GeoDjango tests, you will need to setup a spatial database and install the Geospatial libraries. Each of these dependencies is optional. If you’re missing any of them, the associated tests will be skipped. Code coverage Contributors are encouraged to run coverage on the test suite to identify areas that need additional tests. The coverage tool installation and use is described in testing code coverage. Coverage should be run in a single process to obtain accurate statistics. To run coverage on the Django test suite using the standard test settings: $ coverage run ./runtests.py --settings=test_sqlite --parallel=1

After running coverage, generate the html report by running: $ coverage html

When running coverage for the Django tests, the included .coveragerc settings file defines coverage_html as the output directory for the report and also excludes several directories not relevant to the results (test code or external code included in Django).

10.1. Contributing to Django

1741

Django Documentation, Release 2.1.dev20171115023625

Contrib apps Tests for contrib apps can be found in the tests/ directory, typically under _tests. For example, tests for contrib.auth are located in tests/auth_tests. Troubleshooting Many test failures with UnicodeEncodeError If the locales package is not installed, some tests will fail with a UnicodeEncodeError. You can resolve this on Debian-based systems, for example, by running: $ apt-get install locales $ dpkg-reconfigure locales

You can resolve this for macOS systems by configuring your shell’s locale: $ export LANG="en_US.UTF-8" $ export LC_ALL="en_US.UTF-8"

Run the locale command to confirm the change. Optionally, add those export commands to your shell’s startup file (e.g. ~/.bashrc for Bash) to avoid having to retype them. Tests that only fail in combination In case a test passes when run in isolation but fails within the whole suite, we have some tools to help analyze the problem. The --bisect option of runtests.py will run the failing test while halving the test set it is run together with on each iteration, often making it possible to identify a small number of tests that may be related to the failure. For example, suppose that the failing test that works on its own is ModelTest.test_eq, then using: $ ./runtests.py --bisect basic.tests.ModelTest.test_eq

will try to determine a test that interferes with the given one. First, the test is run with the first half of the test suite. If a failure occurs, the first half of the test suite is split in two groups and each group is then run with the specified test. If there is no failure with the first half of the test suite, the second half of the test suite is run with the specified test and split appropriately as described earlier. The process repeats until the set of failing tests is minimized. The --pair option runs the given test alongside every other test from the suite, letting you check if another test has side-effects that cause the failure. So: $ ./runtests.py --pair basic.tests.ModelTest.test_eq

will pair test_eq with every test label. With both --bisect and --pair, if you already suspect which cases might be responsible for the failure, you may limit tests to be cross-analyzed by specifying further test labels after the first one: $ ./runtests.py --pair basic.tests.ModelTest.test_eq queries transactions

You can also try running any set of tests in reverse using the --reverse option in order to verify that executing tests in a different order does not cause any trouble:

1742

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

$ ./runtests.py basic --reverse

Seeing the SQL queries run during a test If you wish to examine the SQL being run in failing tests, you can turn on SQL logging using the --debug-sql option. If you combine this with --verbosity=2, all SQL queries will be output: $ ./runtests.py basic --debug-sql

Seeing the full traceback of a test failure By default tests are run in parallel with one process per core. When the tests are run in parallel, however, you’ll only see a truncated traceback for any test failures. You can adjust this behavior with the --parallel option: $ ./runtests.py basic --parallel=1

You can also use the DJANGO_TEST_PROCESSES environment variable for this purpose. Tips for writing tests Isolating model registration To avoid polluting the global apps registry and prevent unnecessary table creation, models defined in a test method should be bound to a temporary Apps instance: from django.apps.registry import Apps from django.db import models from django.test import SimpleTestCase class TestModelDefinition(SimpleTestCase): def test_model_definition(self): test_apps = Apps(['app_label']) class TestModel(models.Model): class Meta: apps = test_apps ...

django.test.utils.isolate_apps(*app_labels, attr_name=None, kwarg_name=None) Since this pattern involves a lot of boilerplate, Django provides the isolate_apps() decorator. It’s used like this: from django.db import models from django.test import SimpleTestCase from django.test.utils import isolate_apps class TestModelDefinition(SimpleTestCase): @isolate_apps('app_label') def test_model_definition(self): class TestModel(models.Model): pass ...

10.1. Contributing to Django

1743

Django Documentation, Release 2.1.dev20171115023625

Setting app_label Models defined in a test method with no explicit app_label are automatically assigned the label of the app in which their test class is located. In order to make sure the models defined within the context of isolate_apps() instances are correctly installed, you should pass the set of targeted app_label as arguments: tests/app_label/tests.py from django.db import models from django.test import SimpleTestCase from django.test.utils import isolate_apps class TestModelDefinition(SimpleTestCase): @isolate_apps('app_label', 'other_app_label') def test_model_definition(self): # This model automatically receives app_label='app_label' class TestModel(models.Model): pass class OtherAppModel(models.Model): class Meta: app_label = 'other_app_label' ...

The decorator can also be applied to classes: from django.db import models from django.test import SimpleTestCase from django.test.utils import isolate_apps @isolate_apps('app_label') class TestModelDefinition(SimpleTestCase): def test_model_definition(self): class TestModel(models.Model): pass ...

The temporary Apps instance used to isolate model registration can be retrieved as an attribute when used as a class decorator by using the attr_name parameter: from django.db import models from django.test import SimpleTestCase from django.test.utils import isolate_apps @isolate_apps('app_label', attr_name='apps') class TestModelDefinition(SimpleTestCase): def test_model_definition(self): class TestModel(models.Model): pass self.assertIs(self.apps.get_model('app_label', 'TestModel'), TestModel)

Or as an argument on the test method when used as a method decorator by using the kwarg_name parameter: from django.db import models from django.test import SimpleTestCase from django.test.utils import isolate_apps

1744

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

class TestModelDefinition(SimpleTestCase): @isolate_apps('app_label', kwarg_name='apps') def test_model_definition(self, apps): class TestModel(models.Model): pass self.assertIs(apps.get_model('app_label', 'TestModel'), TestModel)

Submitting patches We’re always grateful for patches to Django’s code. Indeed, bug reports with associated patches will get fixed far more quickly than those without patches. Typo fixes and trivial documentation changes If you are fixing a really trivial issue, for example changing a word in the documentation, the preferred way to provide the patch is using GitHub pull requests without a Trac ticket. See the Working with Git and GitHub for more details on how to use pull requests. “Claiming” tickets In an open-source project with hundreds of contributors around the world, it’s important to manage communication efficiently so that work doesn’t get duplicated and contributors can be as effective as possible. Hence, our policy is for contributors to “claim” tickets in order to let other developers know that a particular bug or feature is being worked on. If you have identified a contribution you want to make and you’re capable of fixing it (as measured by your coding ability, knowledge of Django internals and time availability), claim it by following these steps: • Login using your GitHub account or create an account in our ticket system. If you have an account but have forgotten your password, you can reset it using the password reset page. • If a ticket for this issue doesn’t exist yet, create one in our ticket tracker. • If a ticket for this issue already exists, make sure nobody else has claimed it. To do this, look at the “Owned by” section of the ticket. If it’s assigned to “nobody,” then it’s available to be claimed. Otherwise, somebody else may be working on this ticket. Either find another bug/feature to work on, or contact the developer working on the ticket to offer your help. If a ticket has been assigned for weeks or months without any activity, it’s probably safe to reassign it to yourself. • Log into your account, if you haven’t already, by clicking “GitHub Login” or “DjangoProject Login” in the upper left of the ticket page. • Claim the ticket by clicking the “assign to myself” radio button under “Action” near the bottom of the page, then click “Submit changes.” Note: The Django software foundation requests that anyone contributing more than a trivial patch to Django sign and submit a Contributor License Agreement, this ensures that the Django Software Foundation has clear license to all contributions allowing for a clear license for all users.

10.1. Contributing to Django

1745

Django Documentation, Release 2.1.dev20171115023625

Ticket claimers’ responsibility Once you’ve claimed a ticket, you have a responsibility to work on that ticket in a reasonably timely fashion. If you don’t have time to work on it, either unclaim it or don’t claim it in the first place! If there’s no sign of progress on a particular claimed ticket for a week or two, another developer may ask you to relinquish the ticket claim so that it’s no longer monopolized and somebody else can claim it. If you’ve claimed a ticket and it’s taking a long time (days or weeks) to code, keep everybody updated by posting comments on the ticket. If you don’t provide regular updates, and you don’t respond to a request for a progress report, your claim on the ticket may be revoked. As always, more communication is better than less communication! Which tickets should be claimed? Of course, going through the steps of claiming tickets is overkill in some cases. In the case of small changes, such as typos in the documentation or small bugs that will only take a few minutes to fix, you don’t need to jump through the hoops of claiming tickets. Just submit your patch and be done with it. Of course, it is always acceptable, regardless whether someone has claimed it or not, to submit patches to a ticket if you happen to have a patch ready. Patch style Make sure that any contribution you do fulfills at least the following requirements: • The code required to fix a problem or add a feature is an essential part of a patch, but it is not the only part. A good patch should also include a regression test to validate the behavior that has been fixed and to prevent the problem from arising again. Also, if some tickets are relevant to the code that you’ve written, mention the ticket numbers in some comments in the test so that one can easily trace back the relevant discussions after your patch gets committed, and the tickets get closed. • If the code associated with a patch adds a new feature, or modifies behavior of an existing feature, the patch should also contain documentation. When you think your work is ready to be reviewed, send a GitHub pull request. Please review the patch yourself using our patch review checklist first. If you can’t send a pull request for some reason, you can also use patches in Trac. When using this style, follow these guidelines. • Submit patches in the format returned by the git diff command. • Attach patches to a ticket in the ticket tracker, using the “attach file” button. Please don’t put the patch in the ticket description or comment unless it’s a single line patch. • Name the patch file with a .diff extension; this will let the ticket tracker apply correct syntax highlighting, which is quite helpful. Regardless of the way you submit your work, follow these steps. • Make sure your code fulfills the requirements in our patch review checklist. • Check the “Has patch” box on the ticket and make sure the “Needs documentation”, “Needs tests”, and “Patch needs improvement” boxes aren’t checked. This makes the ticket appear in the “Patches needing review” queue on the Development dashboard.

1746

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

Non-trivial patches A “non-trivial” patch is one that is more than a simple bug fix. It’s a patch that introduces Django functionality and makes some sort of design decision. If you provide a non-trivial patch, include evidence that alternatives have been discussed on django-developers. If you’re not sure whether your patch should be considered non-trivial, just ask. Deprecating a feature There are a couple reasons that code in Django might be deprecated: • If a feature has been improved or modified in a backwards-incompatible way, the old feature or behavior will be deprecated. • Sometimes Django will include a backport of a Python library that’s not included in a version of Python that Django currently supports. When Django no longer needs to support the older version of Python that doesn’t include the library, the library will be deprecated in Django. As the deprecation policy describes, the first release of Django that deprecates a feature (A.B) should raise a RemovedInDjangoXXWarning (where XX is the Django version where the feature will be removed) when the deprecated feature is invoked. Assuming we have good test coverage, these warnings are converted to errors when running the test suite with warnings enabled: python -Wall runtests.py. Thus, when adding a RemovedInDjangoXXWarning you need to eliminate or silence any warnings generated when running the tests. The first step is to remove any use of the deprecated behavior by Django itself. Next you can silence warnings in tests that actually test the deprecated behavior by using the ignore_warnings decorator, either at the test or class level: 1. In a particular test: from django.test import ignore_warnings from django.utils.deprecation import RemovedInDjangoXXWarning @ignore_warnings(category=RemovedInDjangoXXWarning) def test_foo(self): ...

2. For an entire test case: from django.test import ignore_warnings from django.utils.deprecation import RemovedInDjangoXXWarning @ignore_warnings(category=RemovedInDjangoXXWarning) class MyDeprecatedTests(unittest.TestCase): ...

You can also add a test for the deprecation warning. You’ll have to disable the “warning as error” behavior in your test by doing: import warnings def test_foo_deprecation_warning(self): with warnings.catch_warnings(record=True) as warns: warnings.simplefilter('always') # prevent warnings from appearing as errors # invoke deprecated behavior self.assertEqual(len(warns), 1)

10.1. Contributing to Django

1747

Django Documentation, Release 2.1.dev20171115023625

msg = str(warns[0].message) self.assertEqual(msg, 'Expected deprecation message')

Finally, there are a couple of updates to Django’s documentation to make: 1. If the existing feature is documented, mark it deprecated in documentation using the .. deprecated:: A.B annotation. Include a short description and a note about the upgrade path if applicable. 2. Add a description of the deprecated behavior, and the upgrade path if applicable, to the current release notes (docs/releases/A.B.txt) under the “Features deprecated in A.B” heading. 3. Add an entry in the deprecation timeline (docs/internals/deprecation.txt) under the appropriate version describing what code will be removed. Once you have completed these steps, you are finished with the deprecation. RemovedInDjangoXXWarnings matching the new version are removed.

In each feature release, all

JavaScript patches For information on JavaScript patches, see the JavaScript patches documentation. Patch review checklist Use this checklist to review a pull request. If you are reviewing a pull request that is not your own and it passes all the criteria below, please set the “Triage Stage” on the corresponding Trac ticket to “Ready for checkin”. If you’ve left comments for improvement on the pull request, please tick the appropriate flags on the Trac ticket based on the results of your review: “Patch needs improvement”, “Needs documentation”, and/or “Needs tests”. As time and interest permits, committers do final reviews of “Ready for checkin” tickets and will either commit the patch or bump it back to “Accepted” if further works need to be done. If you’re looking to become a committer, doing thorough reviews of patches is a great way to earn trust. Looking for a patch to review? Check out the “Patches needing review” section of the Django Development Dashboard. Looking to get your patch reviewed? Ensure the Trac flags on the ticket are set so that the ticket appears in that queue. Documentation • Does the documentation build without any errors (make html, or make.bat html on Windows, from the docs directory)? • Does the documentation follow the writing style guidelines in Writing documentation? • Are there any spelling errors? Bugs • Is there a proper regression test (the test should fail before the fix is applied)? New Features • Are there tests to “exercise” all of the new code? • Is there a release note in docs/releases/A.B.txt?

1748

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

• Is there documentation for the feature and is it annotated appropriately with .. versionadded:: or .. versionchanged:: A.B?

A.B

Deprecating a feature See the Deprecating a feature guide. All code changes • Does the coding style conform to our guidelines? Are there any flake8 errors? • If the change is backwards incompatible in any way, is there a note in the release notes (docs/releases/ A.B.txt)? • Is Django’s test suite passing? All tickets • Is the pull request a single squashed commit with a message that follows our commit message format? • Are you the patch author and a new contributor? Please add yourself to the AUTHORS file and submit a Contributor License Agreement. Working with Git and GitHub This section explains how the community can contribute code to Django via pull requests. If you’re interested in how committers handle them, see Committing code. Below, we are going to show how to create a GitHub pull request containing the changes for Trac ticket #xxxxx. By creating a fully-ready pull request, you will make the reviewer’s job easier, meaning that your work is more likely to be merged into Django. You could also upload a traditional patch to Trac, but it’s less practical for reviews. Installing Git Django uses Git for its source control. You can download Git, but it’s often easier to install with your operating system’s package manager. Django’s Git repository is hosted on GitHub, and it is recommended that you also work using GitHub. After installing Git, the first thing you should do is setup your name and email: $ git config --global user.name "Your Real Name" $ git config --global user.email "[emailprotected]"

Note that user.name should be your real name, not your GitHub nick. GitHub should know the email you use in the user.email field, as this will be used to associate your commits with your GitHub account.

10.1. Contributing to Django

1749

Django Documentation, Release 2.1.dev20171115023625

Setting up local repository When you have created your GitHub account, with the nick “GitHub_nick”, and forked Django’s repository, create a local copy of your fork: git clone [emailprotected]:GitHub_nick/django.git

This will create a new directory “django”, containing a clone of your GitHub repository. The rest of the git commands on this page need to be run within the cloned directory, so switch to it now: cd django

Your GitHub repository will be called “origin” in Git. You should also setup django/django as an “upstream” remote (that is, tell git that the reference Django repository was the source of your fork of it): git remote add upstream [emailprotected]:django/django.git git fetch upstream

You can add other remotes similarly, for example: git remote add akaariai [emailprotected]:akaariai/django.git

Working on a ticket When working on a ticket, create a new branch for the work, and base that work on upstream/master: git checkout -b ticket_xxxxx upstream/master

The -b flag creates a new branch for you locally. Don’t hesitate to create new branches even for the smallest things that’s what they are there for. If instead you were working for a fix on the 1.4 branch, you would do: git checkout -b ticket_xxxxx_1_4 upstream/stable/1.4.x

Assume the work is carried on the ticket_xxxxx branch. Make some changes and commit them: git commit

When writing the commit message, follow the commit message guidelines to ease the work of the committer. If you’re uncomfortable with English, try at least to describe precisely what the commit does. If you need to do additional work on your branch, commit as often as necessary: git commit -m 'Added two more tests for edge cases'

Publishing work You can publish your work on GitHub just by doing: git push origin ticket_xxxxx

1750

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

When you go to your GitHub page, you will notice a new branch has been created. If you are working on a Trac ticket, you should mention in the ticket that your work is available from branch ticket_xxxxx of your GitHub repo. Include a link to your branch. Note that the above branch is called a “topic branch” in Git parlance. You are free to rewrite the history of this branch, by using git rebase for example. Other people shouldn’t base their work on such a branch, because their clone would become corrupt when you edit commits. There are also “public branches”. These are branches other people are supposed to fork, so the history of these branches should never change. Good examples of public branches are the master and stable/A.B.x branches in the django/django repository. When you think your work is ready to be pulled into Django, you should create a pull request at GitHub. A good pull request means: • commits with one logical change in each, following the coding style, • well-formed messages for each commit: a summary line and then paragraphs wrapped at 72 characters thereafter – see the committing guidelines for more details, • documentation and tests, if needed – actually tests are always needed, except for documentation changes. The test suite must pass and the documentation must build without warnings. Once you have created your pull request, you should add a comment in the related Trac ticket explaining what you’ve done. In particular, you should note the environment in which you ran the tests, for instance: “all tests pass under SQLite and MySQL”. Pull requests at GitHub have only two states: open and closed. The committer who will deal with your pull request has only two options: merge it or close it. For this reason, it isn’t useful to make a pull request until the code is ready for merging – or sufficiently close that a committer will finish it himself. Rebasing branches In the example above, you created two commits, the “Fixed ticket_xxxxx” commit and “Added two more tests” commit. We do not want to have the entire history of your working process in your repository. Your commit “Added two more tests” would be unhelpful noise. Instead, we would rather only have one commit containing all your work. To rework the history of your branch you can squash the commits into one by using interactive rebase: git rebase -i HEAD~2

The HEAD~2 above is shorthand for two latest commits. The above command will open an editor showing the two commits, prefixed with the word “pick”. Change “pick” on the second line to “squash” instead. This will keep the first commit, and squash the second commit into the first one. Save and quit the editor. A second editor window should open, so you can reword the commit message for the commit now that it includes both your steps. You can also use the “edit” option in rebase. This way you can change a single commit, for example to fix a typo in a docstring: git rebase -i HEAD~3 # Choose edit, pick, pick for the commits # Now you are able to rework the commit (use git add normally to add changes) # When finished, commit work with "--amend" and continue git commit --amend # Reword the commit message if needed

10.1. Contributing to Django

1751

Django Documentation, Release 2.1.dev20171115023625

git rebase --continue # The second and third commits should be applied.

If your topic branch is already published at GitHub, for example if you’re making minor changes to take into account a review, you will need to force-push the changes: git push -f origin ticket_xxxxx

Note that this will rewrite history of ticket_xxxxx - if you check the commit hashes before and after the operation at GitHub you will notice that the commit hashes do not match anymore. This is acceptable, as the branch is merely a topic branch, and nobody should be basing their work on it. After upstream has changed When upstream (django/django) has changed, you should rebase your work. To do this, use: git fetch upstream git rebase

The work is automatically rebased using the branch you forked on, in the example case using upstream/master. The rebase command removes all your local commits temporarily, applies the upstream commits, and then applies your local commits again on the work. If there are merge conflicts, you will need to resolve them and then use git rebase --continue. At any point you can use git rebase --abort to return to the original state. Note that you want to rebase on upstream, not merge the upstream. The reason for this is that by rebasing, your commits will always be on top of the upstream’s work, not mixed in with the changes in the upstream. This way your branch will contain only commits related to its topic, which makes squashing easier. After review It is unusual to get any non-trivial amount of code into core without changes requested by reviewers. In this case, it is often a good idea to add the changes as one incremental commit to your work. This allows the reviewer to easily check what changes you have done. In this case, do the changes required by the reviewer. Commit as often as necessary. Before publishing the changes, rebase your work. If you added two commits, you would run: git rebase -i HEAD~2

Squash the second commit into the first. Write a commit message along the lines of: Made changes asked in review by - Fixed whitespace errors in foobar - Reworded the docstring of bar()

Finally, push your work back to your GitHub repository. Since you didn’t touch the public commits during the rebase, you should not need to force-push: git push origin ticket_xxxxx

1752

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

Your pull request should now contain the new commit too. Note that the committer is likely to squash the review commit into the previous commit when committing the code. Working on a patch One of the ways that developers can contribute to Django is by reviewing patches. Those patches will typically exist as pull requests on GitHub and can be easily integrated into your local repository: git checkout -b pull_xxxxx upstream/master curl https://github.com/django/django/pull/xxxxx.patch | git am

This will create a new branch and then apply the changes from the pull request to it. At this point you can run the tests or do anything else you need to do to investigate the quality of the patch. For more detail on working with pull requests see the guidelines for committers. Summary • Work on GitHub if you can. • Announce your work on the Trac ticket by linking to your GitHub branch. • When you have something ready, make a pull request. • Make your pull requests as good as you can. • When doing fixes to your work, use git rebase -i to squash the commits. • When upstream has changed, do git fetch upstream; git rebase. JavaScript While most of Django core is Python, the admin and gis contrib apps contain JavaScript code. Please follow these coding standards when writing JavaScript code for inclusion in Django. Code style • Please conform to the indentation style dictated in the .editorconfig file. We recommend using a text editor with EditorConfig support to avoid indentation and whitespace issues. Most of the JavaScript files use 4 spaces for indentation, but there are some exceptions. • When naming variables, use camelCase instead of underscore_case. Different JavaScript files sometimes use a different code style. Please try to conform to the code style of each file. • Use the JSHint code linter to check your code for bugs and style errors. JSHint will be run when you run the JavaScript tests. We also recommended installing a JSHint plugin in your text editor. • Where possible, write code that will work even if the page structure is later changed with JavaScript. For instance, when binding a click handler, use $('body').on('click', selector, func) instead of $(selector).click(func). This makes it easier for projects to extend Django’s default behavior with JavaScript.

10.1. Contributing to Django

1753

Django Documentation, Release 2.1.dev20171115023625

JavaScript patches Django’s admin system leverages the jQuery framework to increase the capabilities of the admin interface. In conjunction, there is an emphasis on admin JavaScript performance and minimizing overall admin media file size. Serving compressed or “minified” versions of JavaScript files is considered best practice in this regard. To that end, patches for JavaScript files should include both the original code for future development (e.g. foo.js), and a compressed version for production use (e.g. foo.min.js). Any links to the file in the codebase should point to the compressed version. Compressing JavaScript To simplify the process of providing optimized JavaScript code, Django includes a handy Python script which should be used to create a “minified” version. To run it: $ pip install closure $ python django/contrib/admin/bin/compress.py

Behind the scenes, compress.py is a front-end for Google’s Closure Compiler which is written in Java. The Closure Compiler library is not bundled with Django, but you can install it using pip as done above. The Closure Compiler library requires Java 7 or higher. Please don’t forget to run compress.py and include the diff of the minified scripts when submitting patches for Django’s JavaScript. JavaScript tests Django’s JavaScript tests can be run in a browser or from the command line. The tests are located in a top level js_tests directory. Writing tests Django’s JavaScript tests use QUnit. Here is an example test module: module('magicTricks', { beforeEach: function() { var $ = django.jQuery; $('#qunit-fixture').append(''); } }); test('removeOnClick removes button on click', function(assert) { var $ = django.jQuery; removeOnClick('.button'); assert.equal($('.button').length === 1); $('.button').click(); assert.equal($('.button').length === 0); }); test('copyOnClick adds button on click', function(assert) { var $ = django.jQuery; copyOnClick('.button'); assert.equal($('.button').length === 1); $('.button').click();

1754

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

assert.equal($('.button').length === 2); });

Please consult the QUnit documentation for information on the types of assertions supported by QUnit. Running tests The JavaScript tests may be run from a web browser or from the command line. Testing from a web browser To run the tests from a web browser, open up js_tests/tests.html in your browser. To measure code coverage when running the tests, you need to view that file over HTTP. To view code coverage: • Execute python -m http.server from the root directory (not from inside js_tests). • Open http://localhost:8000/js_tests/tests.html in your web browser. Testing from the command line To run the tests from the command line, you need to have Node.js installed. After installing Node.js, install the JavaScript test dependencies by running the following from the root of your Django checkout: $ npm install

Then run the tests with: $ npm test

10.1.5 Writing documentation We place a high importance on consistency and readability of documentation. After all, Django was created in a journalism environment! So we treat our documentation like we treat our code: we aim to improve it as often as possible. Documentation changes generally come in two forms: • General improvements: typo corrections, error fixes and better explanations through clearer writing and more examples. • New features: documentation of features that have been added to the framework since the last release. This section explains how writers can craft their documentation changes in the most useful and least error-prone ways. Getting the raw documentation Though Django’s documentation is intended to be read as HTML at https://docs.djangoproject.com/, we edit it as a collection of text files for maximum flexibility. These files live in the top-level docs/ directory of a Django release. If you’d like to start contributing to our docs, get the development version of Django from the source code repository (see Installing the development version). The development version has the latest-and-greatest documentation, just 10.1. Contributing to Django

1755

Django Documentation, Release 2.1.dev20171115023625

as it has latest-and-greatest code. We also backport documentation fixes and improvements, at the discretion of the committer, to the last release branch. That’s because it’s highly advantageous to have the docs for the last release be up-to-date and correct (see Differences between versions). Getting started with Sphinx Django’s documentation uses the Sphinx documentation system, which in turn is based on docutils. The basic idea is that lightly-formatted plain-text documentation is transformed into HTML, PDF, and any other output format. To actually build the documentation locally, you’ll currently need to install Sphinx – pip install Sphinx should do the trick. Then, building the HTML is easy; just make html (or make.bat html on Windows) from the docs directory. To get started contributing, you’ll want to read the reStructuredText Primer. After that, you’ll want to read about the Sphinx-specific markup that’s used to manage metadata, indexing, and cross-references. Your locally-built documentation will be themed differently than the documentation at docs.djangoproject.com. This is OK! If your changes look good on your local machine, they’ll look good on the website. How the documentation is organized The documentation is organized into several categories: • Tutorials take the reader by the hand through a series of steps to create something. The important thing in a tutorial is to help the reader achieve something useful, preferably as early as possible, in order to give them confidence. Explain the nature of the problem we’re solving, so that the reader understands what we’re trying to achieve. Don’t feel that you need to begin with explanations of how things work - what matters is what the reader does, not what you explain. It can be helpful to refer back to what you’ve done and explain afterwards. • Topic guides aim to explain a concept or subject at a fairly high level. Link to reference material rather than repeat it. Use examples and don’t be reluctant to explain things that seem very basic to you - it might be the explanation someone else needs. Providing background context helps a newcomer connect the topic to things that they already know. • Reference guides contain technical reference for APIs. They describe the functioning of Django’s internal machinery and instruct in its use. Keep reference material tightly focused on the subject. Assume that the reader already understands the basic concepts involved but needs to know or be reminded of how Django does it. Reference guides aren’t the place for general explanation. If you find yourself explaining basic concepts, you may want to move that material to a topic guide. • How-to guides are recipes that take the reader through steps in key subjects. What matters most in a how-to guide is what a user wants to achieve. A how-to should always be result-oriented rather than focused on internal details of how Django implements whatever is being discussed. These guides are more advanced than tutorials and assume some knowledge about how Django works. Assume that the reader has followed the tutorials and don’t hesitate to refer the reader back to the appropriate tutorial rather than repeat the same material.

1756

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

Writing style When using pronouns in reference to a hypothetical person, such as “a user with a session cookie”, gender neutral pronouns (they/their/them) should be used. Instead of: • he or she... use they. • him or her... use them. • his or her... use their. • his or hers... use theirs. • himself or herself... use themselves. Commonly used terms Here are some style guidelines on commonly used terms throughout the documentation: • Django – when referring to the framework, capitalize Django. It is lowercase only in Python code and in the djangoproject.com logo. • email – no hyphen. • MySQL, PostgreSQL, SQLite • SQL – when referring to SQL, the expected pronunciation should be “Ess Queue Ell” and not “sequel”. Thus in a phrase like “Returns an SQL expression”, “SQL” should be preceded by “an” and not “a”. • Python – when referring to the language, capitalize Python. • realize, customize, initialize, etc. – use the American “ize” suffix, not “ise.” • subclass – it’s a single word without a hyphen, both as a verb (“subclass that model”) and as a noun (“create a subclass”). • Web, World Wide Web, the Web – note Web is always capitalized when referring to the World Wide Web. • website – use one word, without capitalization. Django-specific terminology • model – it’s not capitalized. • template – it’s not capitalized. • URLconf – use three capitalized letters, with no space before “conf.” • view – it’s not capitalized. Guidelines for reStructuredText files These guidelines regulate the format of our reST (reStructuredText) documentation: • In section titles, capitalize only initial words and proper nouns. • Wrap the documentation at 80 characters wide, unless a code example is significantly less readable when split over two lines, or for another good reason. • The main thing to keep in mind as you write and edit docs is that the more semantic markup you can add the better. So:

10.1. Contributing to Django

1757

Django Documentation, Release 2.1.dev20171115023625

Add ``django.contrib.auth`` to your ``INSTALLED_APPS``...

Isn’t nearly as helpful as: Add :mod:`django.contrib.auth` to your :setting:`INSTALLED_APPS`...

This is because Sphinx will generate proper links for the latter, which greatly helps readers. You can prefix the target with a ~ (that’s a tilde) to get just the “last bit” of that path. So :mod:`~django. contrib.auth` will just display a link with the title “auth”. • Use intersphinx to reference Python’s and Sphinx’ documentation. • Add .. code-block:: to literal blocks so that they get highlighted. Prefer relying on automatic highlighting simply using :: (two colons). This has the benefit that if the code contains some invalid syntax, it won’t be highlighted. Adding .. code-block:: python, for example, will force highlighting despite invalid syntax. • Use these heading styles: === One === Two === Three ----Four ~~~~ Five ^^^^

Django-specific markup Besides the Sphinx built-in markup, Django’s docs defines some extra description units: • Settings: .. setting:: INSTALLED_APPS

To link to a setting, use :setting:`INSTALLED_APPS`. • Template tags: .. templatetag:: regroup

To link, use :ttag:`regroup`. • Template filters: .. templatefilter:: linebreaksbr

To link, use :tfilter:`linebreaksbr`. • Field lookups (i.e. Foo.objects.filter(bar__exact=whatever)):

1758

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

.. fieldlookup:: exact

To link, use :lookup:`exact`. • django-admin commands: .. django-admin:: migrate

To link, use :djadmin:`migrate`. • django-admin command-line options: .. django-admin-option:: --traceback

To link, use :option:`command_name --traceback` (or omit command_name for the options shared by all commands like --verbosity). • Links to Trac tickets (typically reserved for patch release notes): :ticket:`12345`

Documenting new features Our policy for new features is: All documentation of new features should be written in a way that clearly designates the features are only available in the Django development version. Assume documentation readers are using the latest release, not the development version. Our preferred way for marking new features is by prefacing the features’ documentation with: versionadded:: X.Y”, followed by a mandatory blank line and an optional description (indented).

“..

General improvements, or other changes to the APIs that should be emphasized should use the “.. versionchanged:: X.Y” directive (with the same format as the versionadded mentioned above. These versionadded and versionchanged blocks should be “self-contained.” In other words, since we only keep these annotations around for two releases, it’s nice to be able to remove the annotation and its contents without having to reflow, reindent, or edit the surrounding text. For example, instead of putting the entire description of a new or changed feature in a block, do something like this: .. class:: Author(first_name, last_name, middle_name=None) A person who writes books. ``first_name`` is ... ... ``middle_name`` is ... .. versionchanged:: A.B The ``middle_name`` argument was added.

Put the changed annotation notes at the bottom of a section, not the top. Also, avoid referring to a specific version of Django outside a versionadded or versionchanged block. Even inside a block, it’s often redundant to do so as these annotations render as “New in Django A.B:” and “Changed in Django A.B”, respectively. 10.1. Contributing to Django

1759

Django Documentation, Release 2.1.dev20171115023625

If a function, attribute, etc. is added, it’s also okay to use a versionadded annotation like this: .. attribute:: Author.middle_name .. versionadded:: A.B An author's middle name.

We can simply remove the .. versionadded:: time comes.

A.B annotation without any indentation changes when the

Minimizing images Optimize image compression where possible. For PNG files, use OptiPNG and AdvanceCOMP’s advpng: $ cd docs/ $ optipng -o7 -zm1-9 -i0 -strip all `find . -type f -not -path "./_build/*" -name "*. ˓→png"` $ advpng -z4 `find . -type f -not -path "./_build/*" -name "*.png"`

This is based on OptiPNG version 0.7.5. Older versions may complain about the --strip all option being lossy. An example For a quick example of how it all fits together, consider this hypothetical example: • First, the ref/settings.txt document could have an overall layout like this: ======== Settings ======== ... .. _available-settings: Available settings ================== ... .. _deprecated-settings: Deprecated settings =================== ...

• Next, the topics/settings.txt document could contain something like this: You can access a :ref:`listing of all available settings `. For a list of deprecated settings see :ref:`deprecated-settings`. You can find both in the :doc:`settings reference document `.

1760

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

We use the Sphinx doc cross reference element when we want to link to another document as a whole and the ref element when we want to link to an arbitrary location in a document. • Next, notice how the settings are annotated: .. setting:: ADMINS ADMINS ====== Default: ``[]`` (Empty list) A list of all the people who get code error notifications. When ``DEBUG=False`` and a view raises an exception, Django will email these people with the full exception information. Each member of the list should be a tuple of (Full name, email address). Example:: [('John', '[emailprotected]'), ('Mary', '[emailprotected]')] Note that Django will email *all* of these people whenever an error happens. See :doc:`/howto/error-reporting` for more information.

This marks up the following header as the “canonical” target for the setting ADMINS. This means any time I talk about ADMINS, I can reference it using :setting:`ADMINS`. That’s basically how everything fits together. Spelling check Before you commit your docs, it’s a good idea to run the spelling checker. You’ll need to install a couple packages first: • pyenchant (which requires enchant) • sphinxcontrib-spelling Then from the docs directory, run make spelling. Wrong words (if any) along with the file and line number where they occur will be saved to _build/spelling/output.txt. If you encounter false-positives (error output that actually is correct), do one of the following: • Surround inline code or brand/technology names with grave accents (‘). • Find synonyms that the spell checker recognizes. • If, and only if, you are sure the word you are using is correct - add it to docs/spelling_wordlist (please keep the list in alphabetical order). Translating documentation See Localizing the Django documentation if you’d like to help translate the documentation into another language. django-admin man page Sphinx can generate a manual page for the django-admin command. This is configured in docs/conf.py. Unlike other documentation output, this man page should be included in the Django repository and the releases as docs/ man/django-admin.1. There isn’t a need to update this file when updating the documentation, as it’s updated once as part of the release process. 10.1. Contributing to Django

1761

Django Documentation, Release 2.1.dev20171115023625

To generate an updated version of the man page, run make man in the docs directory. The new man page will be written in docs/_build/man/django-admin.1.

10.1.6 Localizing Django Various parts of Django, such as the admin site and validation error messages, are internationalized. This means they display differently depending on each user’s language or country. For this, Django uses the same internationalization and localization infrastructure available to Django applications, described in the i18n documentation. Translations Translations are contributed by Django users worldwide. The translation work is coordinated at Transifex. If you find an incorrect translation or want to discuss specific translations, go to the Django project page. If you would like to help out with translating or add a language that isn’t yet translated, here’s what to do: • Join the Django i18n mailing list and introduce yourself. • Make sure you read the notes about Specialties of Django translation. • Sign up at Transifex and visit the Django project page. • On the Django project page, choose the language you want to work on, or – in case the language doesn’t exist yet – request a new language team by clicking on the “Request language” link and selecting the appropriate language. • Then, click the “Join this Team” button to become a member of this team. Every team has at least one coordinator who is responsible to review your membership request. You can of course also contact the team coordinator to clarify procedural problems and handle the actual translation process. • Once you are a member of a team choose the translation resource you want to update on the team page. For example the “core” resource refers to the translation catalog that contains all non-contrib translations. Each of the contrib apps also have a resource (prefixed with “contrib”). Note: For more information about how to use Transifex, read the Transifex User Guide. Translations from Transifex are only integrated into the Django repository at the time of a new feature release. We try to update them a second time during one of the following patch releases, but that depends on the translation manager’s availability. So don’t miss the string freeze period (between the release candidate and the feature release) to take the opportunity to complete and fix the translations for your language! Formats You can also review conf/locale//formats.py. This file describes the date, time and numbers formatting particularities of your locale. See Format localization for details. The format files aren’t managed by the use of Transifex. To change them, you must create a patch against the Django source tree, as for any code change: • Create a diff against the current Git master branch. • Open a ticket in Django’s ticket system, set its Component field to Translations, and attach the patch to it.

1762

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

Documentation There is also an opportunity to translate the documentation, though this is a huge undertaking to complete entirely (you have been warned!). We use the same Transifex tool. The translations will appear at https://docs. djangoproject.com// when at least the docs/intro/* files are fully translated in your language.

10.1.7 Committing code This section is addressed to the committers and to anyone interested in knowing how code gets committed into Django. If you’re a community member who wants to contribute code to Django, look at Working with Git and GitHub instead. Handling pull requests Since Django is now hosted at GitHub, most patches are provided in the form of pull requests. When committing a pull request, make sure each individual commit matches the commit guidelines described below. Contributors are expected to provide the best pull requests possible. In practice however, committers - who will likely be more familiar with the commit guidelines - may decide to bring a commit up to standard themselves. Note: Before merging, but after reviewing, have Jenkins test the pull request by commenting “buildbot, test this please” on the PR. See our Jenkins wiki page for more details. An easy way to checkout a pull request locally is to add an alias to your ~/.gitconfig (upstream is assumed to be django/django): [alias] pr = !sh -c \"git fetch upstream pull/${1}/head:pr/${1} && git checkout pr/${1}\"

Now you can simply run git pr #### to checkout the corresponding pull request. At this point, you can work on the code. Use git rebase -i and git commit --amend to make sure the commits have the expected level of quality. Once you’re ready: $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $

# Pull in the latest changes from master. git checkout master git pull upstream master # Rebase the pull request on master. git checkout pr/#### git rebase master git checkout master # Merge the work as "fast-forward" to master to avoid a merge commit. # (in practice, you can omit "--ff-only" since you just rebased) git merge --ff-only pr/XXXX # If you're not sure if you did things correctly, check that only the # changes you expect will be pushed to upstream. git push --dry-run upstream master # Push! git push upstream master # Delete the pull request branch. git branch -d pr/xxxx

For changes on your own branches, force push to your fork after rebasing on master but before merging and pushing to upstream. This allows the commit hashes on master and your branch to match which automatically closes the pull

10.1. Contributing to Django

1763

Django Documentation, Release 2.1.dev20171115023625

request. Since you can’t push to other contributors’ branches, comment on the pull request “Merged in XXXXXXX” (replacing with the commit hash) after you merge it. Trac checks for this message format to indicate on the ticket page whether or not a pull request is merged. If a pull request doesn’t need to be merged as multiple commits, you can use GitHub’s “Squash and merge” button on the website. Edit the commit message as needed to conform to the guidelines and remove the pull request number that’s automatically appended to the message’s first line. When rewriting the commit history of a pull request, the goal is to make Django’s commit history as usable as possible: • If a patch contains back-and-forth commits, then rewrite those into one. For example, if a commit adds some code and a second commit fixes stylistic issues introduced in the first commit, those commits should be squashed before merging. • Separate changes to different commits by logical grouping: if you do a stylistic cleanup at the same time as you do other changes to a file, separating the changes into two different commits will make reviewing history easier. • Beware of merges of upstream branches in the pull requests. • Tests should pass and docs should build after each commit. Neither the tests nor the docs should emit warnings. • Trivial and small patches usually are best done in one commit. Medium to large work may be split into multiple commits if it makes sense. Practicality beats purity, so it is up to each committer to decide how much history mangling to do for a pull request. The main points are engaging the community, getting work done, and having a usable commit history. Committing guidelines In addition, please follow the following guidelines when committing code to Django’s Git repository: • Never change the published history of django/django branches by force pushing. If you absolutely must (for security reasons for example), first discuss the situation with the team. • For any medium-to-big changes, where “medium-to-big” is according to your judgment, please bring things up on the django-developers mailing list before making the change. If you bring something up on django-developers and nobody responds, please don’t take that to mean your idea is great and should be implemented immediately because nobody contested it. Everyone doesn’t always have a lot of time to read mailing list discussions immediately, so you may have to wait a couple of days before getting a response. • Write detailed commit messages in the past tense, not present tense. – Good: “Fixed Unicode bug in RSS API.” – Bad: “Fixes Unicode bug in RSS API.” – Bad: “Fixing Unicode bug in RSS API.” The commit message should be in lines of 72 chars maximum. There should be a subject line, separated by a blank line and then paragraphs of 72 char lines. The limits are soft. For the subject line, shorter is better. In the body of the commit message more detail is better than less: Fixed #18307 -- Added git workflow guidelines Refactored the Django's documentation to remove mentions of SVN specific tasks. Added guidelines of how to use Git, GitHub, and how to use pull request together with Trac instead.

If the patch wasn’t a pull request, you should credit the contributors in the commit message: “Thanks A for report, B for the patch and C for the review.” 1764

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

• For commits to a branch, prefix the commit message with the branch name. For example: “[1.4.x] Fixed #xxxxx – Added support for mind reading.” • Limit commits to the most granular change that makes sense. This means, use frequent small commits rather than infrequent large commits. For example, if implementing feature X requires a small change to library Y, first commit the change to library Y, then commit feature X in a separate commit. This goes a long way in helping everyone follow your changes. • Separate bug fixes from feature changes. Bugfixes may need to be backported to the stable branch, according to the backwards-compatibility policy. • If your commit closes a ticket in the Django ticket tracker, begin your commit message with the text “Fixed #xxxxx”, where “xxxxx” is the number of the ticket your commit fixes. Example: “Fixed #123 – Added whizbang feature.”. We’ve rigged Trac so that any commit message in that format will automatically close the referenced ticket and post a comment to it with the full commit message. If your commit closes a ticket and is in a branch, use the branch name first, then the “Fixed #xxxxx.” For example: “[1.4.x] Fixed #123 – Added whizbang feature.” For the curious, we’re using a Trac plugin for this. Note: Note that the Trac integration doesn’t know anything about pull requests. So if you try to close a pull request with the phrase “closes #400” in your commit message, GitHub will close the pull request, but the Trac plugin will also close the same numbered ticket in Trac. • If your commit references a ticket in the Django ticket tracker but does not close the ticket, include the phrase “Refs #xxxxx”, where “xxxxx” is the number of the ticket your commit references. This will automatically post a comment to the appropriate ticket. • Write commit messages for backports using this pattern: [] Fixed -- Backport of from .

For example: [1.3.x] Fixed #17028 -- Changed diveintopython.org -> diveintopython.net. Backport of 80c0cbf1c97047daed2c5b41b296bbc56fe1d7e3 from master.

There’s a script on the wiki to automate this. Reverting commits Nobody’s perfect; mistakes will be committed. But try very hard to ensure that mistakes don’t happen. Just because we have a reversion policy doesn’t relax your responsibility to aim for the highest quality possible. Really: double-check your work, or have it checked by another committer, before you commit it in the first place! When a mistaken commit is discovered, please follow these guidelines: • If possible, have the original author revert their own commit. • Don’t revert another author’s changes without permission from the original author. • Use git revert – this will make a reverse commit, but the original commit will still be part of the commit history.

10.1. Contributing to Django

1765

Django Documentation, Release 2.1.dev20171115023625

• If the original author can’t be reached (within a reasonable amount of time – a day or so) and the problem is severe – crashing bug, major test failures, etc. – then ask for objections on the django-developers mailing list then revert if there are none. • If the problem is small (a feature commit after feature freeze, say), wait it out. • If there’s a disagreement between the committer and the reverter-to-be then try to work it out on the djangodevelopers mailing list. If an agreement can’t be reached then it should be put to a vote. • If the commit introduced a confirmed, disclosed security vulnerability then the commit may be reverted immediately without permission from anyone. • The release branch maintainer may back out commits to the release branch without permission if the commit breaks the release branch. • If you mistakenly push a topic branch to django/django, just delete it. For instance, if you did: git push upstream feature_antigravity, just do a reverse push: git push upstream :feature_antigravity.

10.2 Mailing lists Important: Please report security issues only to [emailprotected] This is a private list only open to long-time, highly trusted Django developers, and its archives are not public. For further details, please see our security policies. Django has several official mailing lists on Google Groups that are open to anyone.

10.2.1 django-users This is the right place if you are looking to ask any question regarding the installation, usage, or debugging of Django. Note: If it’s the first time you send an email to this list, your email must be accepted first so don’t worry if your message does not appear instantly. • django-users mailing archive • django-users subscription email address • django-users posting email

10.2.2 django-core-mentorship The Django Core Mentorship list is intended to provide a welcoming introductory environment for community members interested in contributing to the Django Project. • django-core-mentorship mailing archive • django-core-mentorship subscription email address • django-core-mentorship posting email

1766

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

10.2.3 django-developers The discussion about the development of Django itself takes place here. Before asking a question about how to contribute, read Contributing to Django. Many frequently asked questions are answered there. Note: Please make use of django-users mailing list if you want to ask for tech support, doing so in this list is inappropriate. • django-developers mailing archive • django-developers subscription email address • django-developers posting email

10.2.4 django-i18n This is the place to discuss the internationalization and localization of Django’s components. • django-i18n mailing archive • django-i18n subscription email address • django-i18n posting email

10.2.5 django-announce A (very) low-traffic list for announcing upcoming security releases, new releases of Django, and security advisories. • django-announce mailing archive • django-announce subscription email address • django-announce posting email

10.2.6 django-updates All the ticket updates are mailed automatically to this list, which is tracked by developers and interested community members. • django-updates mailing archive • django-updates subscription email address • django-updates posting email

10.3 Organization of the Django Project 10.3.1 Principles The Django Project is managed by a team of volunteers pursuing three goals: • Driving the development of the Django Web Framework,

10.3. Organization of the Django Project

1767

Django Documentation, Release 2.1.dev20171115023625

• Fostering the ecosystem of Django-related software, • Leading the Django community in accordance with the values described in the Django Code of Conduct. The Django Project isn’t a legal entity. The Django Software Foundation, a non-profit organization, handles financial and legal matters related to the Django Project. Other than that, the Django Software Foundation lets the Django Project manage the development of the Django framework, its ecosystem and its community. The Django core team makes the decisions, nominates its new members, and elects its technical board. While it holds decision power in theory, it aims at using it as rarely as possible in practice. Rough consensus should be the norm and formal voting an exception.

10.3.2 Core team Role The core team is the group of trusted volunteers who manage the Django Project. They assume many roles required to achieve the project’s goals, especially those that require a high level of trust. They make the decisions that shape the future of the project. Core team members are expected to act as role models for the community and custodians of the project, on behalf of the community and all those who rely on Django. They will intervene, where necessary, in online discussions or at official Django events on the rare occasions that a situation arises that requires intervention. They have authority over the Django Project infrastructure, including the Django Project website itself, the Django GitHub organization and repositories, the Trac bug tracker, the mailing lists, IRC channels, etc. Prerogatives Core team members may participate in formal votes, typically to nominate new team members and to elect the technical board. Some contributions don’t require commit access. Depending on the reasons why a contributor joins the team, they may or may not have commit permissions to the Django code repository. However, should the need arise, any team member may ask for commit access by writing to the core team’s mailing list. Access will be granted unless the person withdraws their request or the technical board vetoes the proposal. Core team members who have commit access are referred to as “committers” or “core developers”. Other permissions, such as access to the servers, are granted to those who need them through the same process. Membership Django team members demonstrate: • a good grasp of the philosophy of the Django Project • a solid track record of being constructive and helpful • significant contributions to the project’s goals, in any form • willingness to dedicate some time to improving Django As the project matures, contributions go way beyond code. Here’s an incomplete list of areas where contributions may be considered for joining the core team, in no particular order:

1768

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

• Working on community management and outreach • Providing support on the mailing-lists and on IRC • Triaging tickets • Writing patches (code, docs, or tests) • Reviewing patches (code, docs, or tests) • Participating in design decisions • Providing expertise in a particular domain (security, i18n, etc.) • Managing the continuous integration infrastructure • Managing the servers (website, tracker, documentation, etc.) • Maintaining related projects (djangoproject.com site, ex-contrib apps, etc.) • Creating visual designs Very few areas are reserved to core team members: • Reviewing security reports • Merging patches (code, docs, or tests) • Packaging releases Core team membership acknowledges sustained and valuable efforts that align well with the philosophy and the goals of the Django Project. It is granted by a four fifths majority of votes cast in a core team vote and no veto by the technical board. Core team members are always looking for promising contributors, teaching them how the project is managed, and submitting their names to the core team’s vote when they’re ready. If you would like to join the core team, you can contact a core team member privately or ask for guidance on the Django Core Mentorship mailing-list. There’s no time limit on core team membership. However, in order to provide the general public with a reasonable idea of how many people maintain Django, core team members who have stopped contributing are encouraged to declare themselves as “past team members”. Those who haven’t made any non-trivial contribution in two years may be asked to move themselves to this category, and moved there if they don’t respond. Past team members lose their privileges such as voting rights and commit access.

10.3.3 Technical board Role The technical board is a group of experienced and active committers who steer technical choices. Their main concern is to maintain the quality and stability of the Django Web Framework. Prerogatives The technical board holds two prerogatives: • Making major technical decisions when no consensus is found otherwise. This happens on the djangodevelopers mailing-list. • Veto a grant of commit access or remove commit access. This happens on the django-core mailing-list.

10.3. Organization of the Django Project

1769

Django Documentation, Release 2.1.dev20171115023625

In both cases, the technical board is a last resort. In these matters, it fulfills a similar function to the former Benevolent Dictators For Life. When the board wants to exercise one of these prerogatives, it must hold a private, simple majority vote on the resolution. The quorum is the full committee — each member must cast a vote or abstain explicitly. Then the board communicates the result, and if possible the reasons, on the appropriate mailing-list. There’s no appeal for such decisions. In addition, at its discretion, the technical board may act in an advisory capacity on non-technical decisions. Membership The technical board is an elected group of five committers. They’re expected to be experienced but there’s no formal seniority requirement. A new board is elected after each feature release of Django. The election process is managed by a returns officer nominated by the outgoing technical board. The election process works as follows: 1. Candidates advertise their application for the technical board to the team. They must be committers already. There’s no term limit for technical board members. 2. Each team member can vote for zero to five people among the candidates. Candidates are ranked by the total number of votes they received. In case of a tie, the person who joined the core team earlier wins. Both the application and the voting period last between one and two weeks, at the outgoing board’s discretion.

10.3.4 Changing the organization Changes to this document require a four fifths majority of votes cast in a core team vote and no veto by the technical board.

10.4 Django’s security policies Django’s development team is strongly committed to responsible reporting and disclosure of security-related issues. As such, we’ve adopted and follow a set of policies which conform to that ideal and are geared toward allowing us to deliver timely security updates to the official distribution of Django, as well as to third-party distributions.

10.4.1 Reporting security issues Short version: please report security issues by emailing [emailprotected] Most normal bugs in Django are reported to our public Trac instance, but due to the sensitive nature of security issues, we ask that they not be publicly reported in this fashion. Instead, if you believe you’ve found something in Django which has security implications, please send a description of the issue via email to [emailprotected] Mail sent to that address reaches the security team. Once you’ve submitted an issue via email, you should receive an acknowledgment from a member of the security team within 48 hours, and depending on the action to be taken, you may receive further followup emails. Sending encrypted reports

1770

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

If you want to send an encrypted email (optional), the public key ID for [emailprotected] is 0xfcb84b8d1d17f80b, and this public key is available from most commonly-used keyservers.

10.4.2 Supported versions At any given time, the Django team provides official security support for several versions of Django: • The master development branch, hosted on GitHub, which will become the next major release of Django, receives security support. Security issues that only affect the master development branch and not any stable released versions are fixed in public without going through the disclosure process. • The two most recent Django release series receive security support. For example, during the development cycle leading to the release of Django 1.5, support will be provided for Django 1.4 and Django 1.3. Upon the release of Django 1.5, Django 1.3’s security support will end. • Long-term support releases will receive security updates for a specified period. When new releases are issued for security reasons, the accompanying notice will include a list of affected versions. This list is comprised solely of supported versions of Django: older versions may also be affected, but we do not investigate to determine that, and will not issue patches or new releases for those versions.

10.4.3 How Django discloses security issues Our process for taking a security issue from private discussion to public disclosure involves multiple steps. Approximately one week before public disclosure, we send two notifications: First, we notify django-announce of the date and approximate time of the upcoming security release, as well as the severity of the issues. This is to aid organizations that need to ensure they have staff available to handle triaging our announcement and upgrade Django as needed. Severity levels are: High: • Remote code execution • SQL injection Moderate: • Cross site scripting (XSS) • Cross site request forgery (CSRF) • Broken authentication Low: • Sensitive data exposure • Broken session management • Unvalidated redirects/forwards • Issues requiring an uncommon configuration option Second, we notify a list of people and organizations, primarily composed of operating-system vendors and other distributors of Django. This email is signed with the PGP key of someone from Django’s release team and consists of: • A full description of the issue and the affected versions of Django. • The steps we will be taking to remedy the issue.

10.4. Django’s security policies

1771

Django Documentation, Release 2.1.dev20171115023625

• The patch(es), if any, that will be applied to Django. • The date on which the Django team will apply these patches, issue new releases and publicly disclose the issue. On the day of disclosure, we will take the following steps: 1. Apply the relevant patch(es) to Django’s codebase. 2. Issue the relevant release(s), by placing new packages on the Python Package Index and on the Django website, and tagging the new release(s) in Django’s git repository. 3. Post a public entry on the official Django development blog, describing the issue and its resolution in detail, pointing to the relevant patches and new releases, and crediting the reporter of the issue (if the reporter wishes to be publicly identified). 4. Post a notice to the django-announce and [emailprotected] mailing lists that links to the blog post. If a reported issue is believed to be particularly time-sensitive – due to a known exploit in the wild, for example – the time between advance notification and public disclosure may be shortened considerably. Additionally, if we have reason to believe that an issue reported to us affects other frameworks or tools in the Python/web ecosystem, we may privately contact and discuss those issues with the appropriate maintainers, and coordinate our own disclosure and resolution with theirs. The Django team also maintains an archive of security issues disclosed in Django.

10.4.4 Who receives advance notification The full list of people and organizations who receive advance notification of security issues is not and will not be made public. We also aim to keep this list as small as effectively possible, in order to better manage the flow of confidential information prior to disclosure. As such, our notification list is not simply a list of users of Django, and merely being a user of Django is not sufficient reason to be placed on the notification list. In broad terms, recipients of security notifications fall into three groups: 1. Operating-system vendors and other distributors of Django who provide a suitably-generic (i.e., not an individual’s personal email address) contact address for reporting issues with their Django package, or for general security reporting. In either case, such addresses must not forward to public mailing lists or bug trackers. Addresses which forward to the private email of an individual maintainer or security-response contact are acceptable, although private security trackers or security-response groups are strongly preferred. 2. On a case-by-case basis, individual package maintainers who have demonstrated a commitment to responding to and responsibly acting on these notifications. 3. On a case-by-case basis, other entities who, in the judgment of the Django development team, need to be made aware of a pending security issue. Typically, membership in this group will consist of some of the largest and/or most likely to be severely impacted known users or distributors of Django, and will require a demonstrated ability to responsibly receive, keep confidential and act on these notifications.

10.4.5 Requesting notifications If you believe that you, or an organization you are authorized to represent, fall into one of the groups listed above, you can ask to be added to Django’s notification list by emailing [emailprotected] Please use the subject line “Security notification request”. Your request must include the following information:

1772

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

• Your full, real name and the name of the organization you represent, if applicable, as well as your role within that organization. • A detailed explanation of how you or your organization fit at least one set of criteria listed above. • A detailed explanation of why you are requesting security notifications. Again, please keep in mind that this is not simply a list for users of Django, and the overwhelming majority of users should subscribe to djangoannounce to receive advanced notice of when a security release will happen, without the details of the issues, rather than request detailed notifications. • The email address you would like to have added to our notification list. • An explanation of who will be receiving/reviewing mail sent to that address, as well as information regarding any automated actions that will be taken (i.e., filing of a confidential issue in a bug tracker). • For individuals, the ID of a public key associated with your address which can be used to verify email received from you and encrypt email sent to you, as needed. Once submitted, your request will be considered by the Django development team; you will receive a reply notifying you of the result of your request within 30 days. Please also bear in mind that for any individual or organization, receiving security notifications is a privilege granted at the sole discretion of the Django development team, and that this privilege can be revoked at any time, with or without explanation.

10.5 Django’s release process 10.5.1 Official releases Since version 1.0, Django’s release numbering works as follows: • Versions are numbered in the form A.B or A.B.C. • A.B is the feature release version number. Each version will be mostly backwards compatible with the previous release. Exceptions to this rule will be listed in the release notes. • C is the patch release version number, which is incremented for bugfix and security releases. These releases will be 100% backwards-compatible with the previous patch release. The only exception is when a security or data loss issue can’t be fixed without breaking backwards-compatibility. If this happens, the release notes will provide detailed upgrade instructions. • Before a new feature release, we’ll make alpha, beta, and release candidate releases. These are of the form A.B alpha/beta/rc N, which means the Nth alpha/beta/release candidate of version A.B. In git, each Django release will have a tag indicating its version number, signed with the Django release key. Additionally, each release series has its own branch, called stable/A.B.x, and bugfix/security releases will be issued from those branches. For more information about how the Django project issues new releases for security purposes, please see our security policies. Feature release Feature releases (A.B, A.B+1, etc.) will happen roughly every eight months – see release process for details. These releases will contain new features, improvements to existing features, and such. Patch release Patch releases (A.B.C, A.B.C+1, etc.) will be issued as needed, to fix bugs and/or security issues. These releases will be 100% compatible with the associated feature release, unless this is impossible for security reasons or to prevent data loss. So the answer to “should I upgrade to the latest patch release?” will always be “yes.”

10.5. Django’s release process

1773

Django Documentation, Release 2.1.dev20171115023625

Long-term support release Certain feature releases will be designated as long-term support (LTS) releases. These releases will get security and data loss fixes applied for a guaranteed period of time, typically three years. See the download page for the releases that have been designated for long-term support.

10.5.2 Release cadence Starting with Django 2.0, version numbers will use a loose form of semantic versioning such that each version following an LTS will bump to the next “dot zero” version. For example: 2.0, 2.1, 2.2 (LTS), 3.0, 3.1, 3.2 (LTS), etc. SemVer makes it easier to see at a glance how compatible releases are with each other. It also helps to anticipate when compatibility shims will be removed. It’s not a pure form of SemVer as each feature release will continue to have a few documented backwards incompatibilities where a deprecation path isn’t possible or not worth the cost. Also, deprecations started in an LTS release (X.2) will be dropped in a non-dot-zero release (Y.1) to accommodate our policy of keeping deprecation shims for at least two feature releases. Read on to the next section for an example.

10.5.3 Deprecation policy A feature release may deprecate certain features from previous releases. If a feature is deprecated in feature release A.x, it will continue to work in all A.x versions (for all versions of x) but raise warnings. Deprecated features will be removed in the B.0 release, or B.1 for features deprecated in the last A.x feature release to ensure deprecations are done over at least 2 feature releases. So, for example, if we decided to start the deprecation of a function in Django 4.2: • Django 4.2 will contain a backwards-compatible replica of the function which will raise a RemovedInDjango51Warning. • Django 5.0 (the version that follows 4.2) will still contain the backwards-compatible replica. • Django 5.1 will remove the feature outright. The warnings are silent by default. You can turn on display of these warnings with the python -Wd option. A more generic example: • X.0 • X.1 • X.2 LTS • Y.0: Drop deprecation shims added in X.0 and X.1. • Y.1: Drop deprecation shims added in X.2. • Y.2 LTS: No deprecation shims dropped (while Y.0 is no longer supported, third-party apps need to maintain compatibility back to X.2 LTS to ease LTS to LTS upgrades). • Z.0: Drop deprecation shims added in Y.0 and Y.1.

10.5.4 Supported versions At any moment in time, Django’s developer team will support a set of releases to varying levels. See the supported versions section of the download page for the current state of support for each version. • The current development master will get new features and bug fixes requiring non-trivial refactoring. • Patches applied to the master branch must also be applied to the last feature release branch, to be released in the next patch release of that feature series, when they fix critical problems: 1774

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

– Security issues. – Data loss bugs. – Crashing bugs. – Major functionality bugs in new features of the latest stable release. – Regressions from older versions of Django. The rule of thumb is that fixes will be backported to the last feature release for bugs that would have prevented a release in the first place (release blockers). • Security fixes and data loss bugs will be applied to the current master, the last two feature release branches, and any other supported long-term support release branches. • Documentation fixes generally will be more freely backported to the last release branch. That’s because it’s highly advantageous to have the docs for the last release be up-to-date and correct, and the risk of introducing regressions is much less of a concern. As a concrete example, consider a moment in time halfway between the release of Django 5.1 and 5.2. At this point in time: • Features will be added to development master, to be released as Django 5.2. • Critical bug fixes will be applied to the stable/5.1.x branch, and released as 5.1.1, 5.1.2, etc. • Security fixes and bug fixes for data loss issues will be applied to master and to the stable/5.1.x, stable/5.0.x, and stable/4.2.x (LTS) branches. They will trigger the release of 5.1.1, 5.0.5, 4.2.8, etc. • Documentation fixes will be applied to master, and, if easily backported, to the latest stable branch, 5.1.x.

10.5.5 Release process Django uses a time-based release schedule, with feature releases every eight months or so. After each feature release, the release manager will announce a timeline for the next feature release. Release cycle Each release cycle consists of three parts: Phase one: feature proposal The first phase of the release process will include figuring out what major features to include in the next version. This should include a good deal of preliminary work on those features – working code trumps grand design. Major features for an upcoming release will be added to the wiki roadmap page, e.g. https://code.djangoproject.com/ wiki/Version1.11Roadmap. Phase two: development The second part of the release schedule is the “heads-down” working period. Using the roadmap produced at the end of phase one, we’ll all work very hard to get everything on it done. At the end of phase two, any unfinished features will be postponed until the next release.

10.5. Django’s release process

1775

Django Documentation, Release 2.1.dev20171115023625

Phase two will culminate with an alpha release. At this point, the stable/A.B.x branch will be forked from master. Phase three: bugfixes The last part of a release cycle is spent fixing bugs – no new features will be accepted during this time. We’ll try to release a beta release one month after the alpha and a release candidate one month after the beta. The release candidate marks the string freeze, and it happens at least two weeks before the final release. After this point, new translatable strings must not be added. During this phase, committers will be more and more conservative with backports, to avoid introducing regressions. After the release candidate, only release blockers and documentation fixes should be backported. In parallel to this phase, master can receive new features, to be released in the A.B+1 cycle. Bug-fix releases After a feature release (e.g. A.B), the previous release will go into bugfix mode. The branch for the previous feature release (e.g. stable/A.B-1.x) will include bugfixes. Critical bugs fixed on master must also be fixed on the bugfix branch; this means that commits need to cleanly separate bug fixes from feature additions. The developer who commits a fix to master will be responsible for also applying the fix to the current bugfix branch.

10.6 Django Deprecation Timeline This document outlines when various pieces of Django will be removed or altered in a backward incompatible way, following their deprecation, as per the deprecation policy. More details about each item can often be found in the release notes of two versions prior.

10.6.1 3.0 See the Django 2.0 release notes for more details on these changes. • The django.db.backends.postgresql_psycopg2 module will be removed. • django.shortcuts.render_to_response() will be removed. • The DEFAULT_CONTENT_TYPE setting will be removed. • HttpRequest.xreadlines() will be removed. • Support for the context argument convert_value() will be removed.

of

Field.from_db_value()

and

Expression.

• The field_name keyword argument of QuerySet.earliest() and latest() will be removed. See the Django 2.1 release notes for more details on these changes.

10.6.2 2.1 See the Django 1.11 release notes for more details on these changes.

1776

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

• contrib.auth.views.login(), logout(), password_change(), password_change_done(), password_reset(), password_reset_done(), password_reset_confirm(), and password_reset_complete() will be removed. • The extra_context parameter of contrib.auth.views.logout_then_login() will be removed. • django.test.runner.setup_databases() will be removed. • django.utils.translation.string_concat() will be removed. • django.core.cache.backends.memcached.PyLibMCCache will no longer support passing pylibmc behavior settings as top-level attributes of OPTIONS. • The host parameter of django.utils.http.is_safe_url() will be removed. • Silencing of exceptions raised while rendering the {% include %} template tag will be removed. • DatabaseIntrospection.get_indexes() will be removed. • The authenticate() method of authentication backends will require request as the first positional argument. • The django.db.models.permalink() decorator will be removed. • The USE_ETAGS setting will be removed. CommonMiddleware and django.utils.cache. patch_response_headers() will no longer set ETags. • The Model._meta.has_auto_field attribute will be removed. • Support for regular expression groups with iLmsu# in url() will be removed. • Support for Widget.render() methods without the renderer argument will be removed.

10.6.3 2.0 See the Django 1.9 release notes for more details on these changes. • The weak argument to django.dispatch.signals.Signal.disconnect() will be removed. • django.db.backends.base.BaseDatabaseOperations.check_aggregate_support() will be removed. • The django.forms.extras package will be removed. • The assignment_tag helper will be removed. • The host argument to assertsRedirects will be removed. The compatibility layer which allows absolute URLs to be considered equal to relative ones when the path is identical will also be removed. • Field.rel will be removed. • Field.remote_field.to attribute will be removed. • The on_delete argument for ForeignKey and OneToOneField will be required. • django.db.models.fields.add_lazy_relation() will be removed. • When time zone support is enabled, database backends that don’t support time zones won’t convert aware datetimes to naive values in UTC anymore when such values are passed as parameters to SQL queries executed outside of the ORM, e.g. with cursor.execute(). • The django.contrib.auth.tests.utils.skipIfCustomUser() decorator will be removed. • The GeoManager and GeoQuerySet classes will be removed.

10.6. Django Deprecation Timeline

1777

Django Documentation, Release 2.1.dev20171115023625

• The django.contrib.gis.geoip module will be removed. • The supports_recursion check for template loaders will be removed from: – django.template.engine.Engine.find_template() – django.template.loader_tags.ExtendsNode.find_template() – django.template.loaders.base.Loader.supports_recursion() – django.template.loaders.cached.Loader.supports_recursion() • The load_template() and load_template_sources() template loader methods will be removed. • The template_dirs argument for template loaders will be removed: – django.template.loaders.base.Loader.get_template() – django.template.loaders.cached.Loader.cache_key() – django.template.loaders.cached.Loader.get_template() – django.template.loaders.cached.Loader.get_template_sources() – django.template.loaders.filesystem.Loader.get_template_sources() • The django.template.loaders.base.Loader.__call__() method will be removed. • Support for custom error views with a single positional parameter will be dropped. • The mime_type attribute of django.utils.feedgenerator.Atom1Feed and django.utils. feedgenerator.RssFeed will be removed in favor of content_type. • The app_name argument to django.conf.urls.include() will be removed. • Support for passing a 3-tuple as the first argument to include() will be removed. • Support for setting a URL instance namespace without an application namespace will be removed. • Field._get_val_from_obj() will be removed in favor of Field.value_from_object(). • django.template.loaders.eggs.Loader will be removed. • The current_app parameter to the contrib.auth views will be removed. • The callable_obj keyword argument to SimpleTestCase.assertRaisesMessage() will be removed. • Support for the allow_tags attribute on ModelAdmin methods will be removed. • The enclosure keyword argument to SyndicationFeed.add_item() will be removed. • The django.template.loader.LoaderOrigin and django.template.base.StringOrigin aliases for django.template.base.Origin will be removed. See the Django 1.10 release notes for more details on these changes. • The makemigrations --exit option will be removed. • Support for direct assignment to a reverse foreign key or many-to-many relation will be removed. • The get_srid() and set_srid() methods of django.contrib.gis.geos.GEOSGeometry will be removed. • The get_x(), set_x(), get_y(), set_y(), get_z(), and set_z() methods of django. contrib.gis.geos.Point will be removed. • The get_coords() and set_coords() methods of django.contrib.gis.geos.Point will be removed.

1778

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

• The cascaded_union property of django.contrib.gis.geos.MultiPolygon will be removed. • django.utils.functional.allow_lazy() will be removed. • The shell --plain option will be removed. • The django.core.urlresolvers module will be removed. • The model CommaSeparatedIntegerField will be removed. A stub field will remain for compatibility with historical migrations. • Support for the template Context.has_key() method will be removed. • Support for the django.core.files.storage.Storage.accessed_time(), created_time(), and modified_time() methods will be removed. • Support for query lookups using the model name when Meta.default_related_name is set will be removed. • The __search query lookup and the DatabaseOperations.fulltext_search_sql() method will be removed. • The shim for supporting custom related manager classes without a _apply_rel_filters() method will be removed. • Using User.is_authenticated() and User.is_anonymous() as methods will no longer be supported. • The private attribute virtual_fields of Model._meta will be removed. • The private keyword arguments virtual_only in Field.contribute_to_class() and virtual in Model._meta.add_field() will be removed. • The javascript_catalog() and json_catalog() views will be removed. • The django.contrib.gis.utils.precision_wkt() function will be removed. • In multi-table inheritance, implicit promotion of a OneToOneField to a parent_link will be removed. • Support for Widget._format_value() will be removed. • FileField methods get_directory_name() and get_filename() will be removed. • The mark_for_escaping() function and the classes it uses: EscapeData, EscapeBytes, EscapeText, EscapeString, and EscapeUnicode will be removed. • The escape filter will change to use django.utils.html.conditional_escape(). • Manager.use_for_related_fields will be removed. • Model Manager inheritance will follow MRO inheritance rules and manager_inheritance_from_future to opt-in to this behavior will be removed.

the

Meta.

• Support for old-style middleware using settings.MIDDLEWARE_CLASSES will be removed.

10.6.4 1.10 See the Django 1.8 release notes for more details on these changes. • Support for calling a SQLCompiler directly as an alias for calling its quote_name_unless_alias method will be removed. • cycle and firstof template tags will be removed from the future template tag library (used during the 1.6/1.7 deprecation period). • django.conf.urls.patterns() will be removed. 10.6. Django Deprecation Timeline

1779

Django Documentation, Release 2.1.dev20171115023625

• Support for the prefix argument to django.conf.urls.i18n.i18n_patterns() will be removed. • SimpleTestCase.urls will be removed. • Using an incorrect count of unpacked values in the for template tag will raise an exception rather than fail silently. • The ability to reverse URLs using a dotted Python path will be removed. • The ability to use a dotted Python path for the LOGIN_URL and LOGIN_REDIRECT_URL settings will be removed. • Support for optparse will be dropped for custom management commands (replaced by argparse). • The class django.core.management.NoArgsCommand will be removed. Use BaseCommand instead, which takes no arguments by default. • django.core.context_processors module will be removed. • django.db.models.sql.aggregates module will be removed. • django.contrib.gis.db.models.sql.aggregates module will be removed. • The following methods and properties of django.db.sql.query.Query will be removed: – Properties: aggregates and aggregate_select – Methods: add_aggregate, set_aggregate_mask, and append_aggregate_mask. • django.template.resolve_variable will be removed. • The following private APIs will be removed from django.db.models.options.Options (Model. _meta): – get_field_by_name() – get_all_field_names() – get_fields_with_model() – get_concrete_fields_with_model() – get_m2m_with_model() – get_all_related_objects() – get_all_related_objects_with_model() – get_all_related_many_to_many_objects() – get_all_related_m2m_objects_with_model() • The error_message argument of django.forms.RegexField will be removed. • The unordered_list filter will no longer support old style lists. • Support for string view arguments to url() will be removed. • The backward compatible shim has_changed() will be removed.

to

rename

django.forms.Form._has_changed()

to

• The removetags template filter will be removed. • The remove_tags() and strip_entities() functions in django.utils.html will be removed. • The is_admin_site argument to django.contrib.auth.views.password_reset() will be removed. • django.db.models.field.subclassing.SubfieldBase will be removed.

1780

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

• django.utils.checksums will be removed; its functionality is included in django-localflavor 1.1+. • The original_content_type_id InlineAdminForm will be removed.

attribute

on

django.contrib.admin.helpers.

• The backwards compatibility shim to allow FormMixin.get_form() to be defined with no default value for its form_class argument will be removed. • The following settings will be removed: – ALLOWED_INCLUDE_ROOTS – TEMPLATE_CONTEXT_PROCESSORS – TEMPLATE_DEBUG – TEMPLATE_DIRS – TEMPLATE_LOADERS – TEMPLATE_STRING_IF_INVALID • The backwards compatibility alias django.template.loader.BaseLoader will be removed. • Django template objects returned by get_template() and select_template() won’t accept a Context in their render() method anymore. • Template response APIs will enforce the use of dict and backend-dependent template objects instead of Context and Template respectively. • The current_app parameter for the following function and classes will be removed: – django.shortcuts.render() – django.template.Context() – django.template.RequestContext() – django.template.response.TemplateResponse() • The dictionary and context_instance parameters for the following functions will be removed: – django.shortcuts.render() – django.shortcuts.render_to_response() – django.template.loader.render_to_string() • The dirs parameter for the following functions will be removed: – django.template.loader.get_template() – django.template.loader.select_template() – django.shortcuts.render() – django.shortcuts.render_to_response() • Session verification will be enabled regardless of whether or not 'django.contrib.auth. middleware.SessionAuthenticationMiddleware' is in MIDDLEWARE_CLASSES. • Private attribute django.db.models.Field.related will be removed. • The --list option of the migrate management command will be removed. • The ssi template tag will be removed. • Support for the = comparison operator in the if template tag will be removed.

10.6. Django Deprecation Timeline

1781

Django Documentation, Release 2.1.dev20171115023625

• The backwards compatibility shims to allow Storage.get_available_name() and Storage. save() to be defined without a max_length argument will be removed. • Support for the legacy %()s syntax in ModelFormMixin.success_url will be removed. • GeoQuerySet aggregate methods collect(), extent(), extent3d(), make_line(), and unionagg() will be removed. • Ability to specify ContentType.name when creating a content type instance will be removed. • Support for the old signature of allow_migrate will be removed. It changed from allow_migrate(self, db, model) to allow_migrate(self, db, app_label, model_name=None, **hints). • Support for the syntax of {% cycle %} that uses comma-separated arguments will be removed. • The warning that Signer issues when given an invalid separator will become an exception.

10.6.5 1.9 See the Django 1.7 release notes for more details on these changes. • django.utils.dictconfig will be removed. • django.utils.importlib will be removed. • django.utils.tzinfo will be removed. • django.utils.unittest will be removed. • The syncdb command will be removed. • django.db.models.signals.pre_syncdb and django.db.models.signals.post_syncdb will be removed. • allow_syncdb on database routers will no longer automatically become allow_migrate. • Automatic syncing of apps without migrations will be removed. Migrations will become compulsory for all apps unless you pass the --run-syncdb option to migrate. • The SQL management commands for apps without migrations, sqldropindexes, and sqlindexes, will be removed.

sql,

sqlall,

sqlclear,

• Support for automatic loading of initial_data fixtures and initial SQL data will be removed. • All models will need to be defined inside an installed application or declare an explicit app_label. Furthermore, it won’t be possible to import them before their application is loaded. In particular, it won’t be possible to import models inside the root package of their application. • The model and form IPAddressField will be removed. A stub field will remain for compatibility with historical migrations. • AppCommand.handle_app() will no longer be supported. • RequestSite and get_current_site() will no longer be importable from django.contrib. sites.models. • FastCGI support via the runfcgi management command will be removed. Please deploy your project using WSGI. • django.utils.datastructures.SortedDict will OrderedDict from the Python standard library instead.

be

removed.

Use

collections.

• ModelAdmin.declared_fieldsets will be removed.

1782

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

• Instances of util.py in the Django codebase have been renamed to utils.py in an effort to unify all util and utils references. The modules that provided backwards compatibility will be removed: – django.contrib.admin.util – django.contrib.gis.db.backends.util – django.db.backends.util – django.forms.util • ModelAdmin.get_formsets will be removed. • The backward compatibility shim introduced to rename the BaseMemcachedCache. _get_memcache_timeout() method to get_backend_timeout() will be removed. • The --natural and -n options for dumpdata will be removed. • The use_natural_keys argument for serializers.serialize() will be removed. • Private API django.forms.forms.get_declared_fields() will be removed. • The ability to use a SplitDateTimeWidget with DateTimeField will be removed. • The WSGIRequest.REQUEST property will be removed. • The class django.utils.datastructures.MergeDict will be removed. • The zh-cn and zh-tw language codes will be removed and have been replaced by the zh-hans and zh-hant language code respectively. • The internal django.utils.functional.memoize will be removed. • django.core.cache.get_cache will be removed. Add suitable entries to CACHES and use django. core.cache.caches instead. • django.db.models.loading will be removed. • Passing callable arguments to querysets will no longer be possible. • BaseCommand.requires_model_validation will be removed requires_system_checks. Admin validators will be replaced by admin checks.

(Video) Django For Beginners - Full Tutorial

in

favor

of

• The ModelAdmin.validator_class and default_validator_class attributes will be removed. • ModelAdmin.validate() will be removed. • django.db.backends.DatabaseValidation.validate_field will be removed in favor of the check_field method. • The validate management command will be removed. • django.utils.module_loading.import_by_path will be removed in favor of django.utils. module_loading.import_string. • ssi and url template tags will be removed from the future template tag library (used during the 1.3/1.4 deprecation period). • django.utils.text.javascript_quote will be removed. • Database test settings as independent entries in the database settings, prefixed by TEST_, will no longer be supported. • The cache_choices option to ModelChoiceField and ModelMultipleChoiceField will be removed. • The default value of the RedirectView.permanent attribute will change from True to False.

10.6. Django Deprecation Timeline

1783

Django Documentation, Release 2.1.dev20171115023625

• django.contrib.sitemaps.FlatPageSitemap will be removed in favor of django.contrib. flatpages.sitemaps.FlatPageSitemap. • Private API django.test.utils.TestTemplateLoader will be removed. • The django.contrib.contenttypes.generic module will be removed. • Private APIs django.db.models.sql.where.WhereNode.make_atom() and django.db. models.sql.where.Constraint will be removed.

10.6.6 1.8 See the Django 1.6 release notes for more details on these changes. • django.contrib.comments will be removed. • The following transaction management APIs will be removed: – TransactionMiddleware, – the decorators and context managers autocommit, commit_manually, defined in django.db.transaction,

commit_on_success,

and

– the functions commit_unless_managed and rollback_unless_managed, also defined in django.db.transaction, – the TRANSACTIONS_MANAGED setting. • The cycle and firstof template tags will auto-escape their arguments. In 1.6 and 1.7, this behavior is provided by the version of these tags in the future template tag library. • The SEND_BROKEN_LINK_EMAILS setting will be removed. Add the django.middleware.common. BrokenLinkEmailsMiddleware middleware to your MIDDLEWARE_CLASSES setting instead. • django.middleware.doc.XViewMiddleware will be removed. admindocs.middleware.XViewMiddleware instead.

Use django.contrib.

• Model._meta.module_name was renamed to model_name. • Remove the backward compatible shims introduced to rename get_query_set and similar queryset methods. This affects the following classes: BaseModelAdmin, ChangeList, BaseCommentNode, GenericForeignKey, Manager, SingleRelatedObjectDescriptor and ReverseSingleRelatedObjectDescriptor. • Remove the backward compatible shims introduced to rename the attributes ChangeList. root_query_set and ChangeList.query_set. • django.views.defaults.shortcut will be removed, as part of the goal of removing all django. contrib references from the core Django codebase. Instead use django.contrib.contenttypes. views.shortcut. django.conf.urls.shortcut will also be removed. • Support for the Python Imaging Library (PIL) module will be removed, as it no longer appears to be actively maintained & does not work on Python 3. You are advised to install Pillow, which should be used instead. • The following private APIs will be removed: – django.db.backend – django.db.close_connection() – django.db.backends.creation.BaseDatabaseCreation.set_autocommit() – django.db.transaction.is_managed() – django.db.transaction.managed() 1784

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

• django.forms.widgets.RadioInput will be removed in favor of django.forms.widgets. RadioChoiceInput. • The module django.test.simple and the class django.test.simple. DjangoTestSuiteRunner will be removed. Instead use django.test.runner.DiscoverRunner. • The module django.test._doctest will be removed. Instead use the doctest module from the Python standard library. • The CACHE_MIDDLEWARE_ANONYMOUS_ONLY setting will be removed. • Usage of the hard-coded Hold down “Control”, or “Command” on a Mac, to select more than one. string to override or append to user-provided help_text in forms for ManyToMany model fields will not be performed by Django anymore either at the model or forms layer. • The Model._meta.get_(add|change|delete)_permission methods will be removed. • The session key django_language will no longer be read for backwards compatibility. • Geographic Sitemaps will be removed (django.contrib.gis.sitemaps.views.index and django.contrib.gis.sitemaps.views.sitemap). • django.utils.html.fix_ampersands, the fix_ampersands template filter and django. utils.html.clean_html will be removed following an accelerated deprecation.

10.6.7 1.7 See the Django 1.5 release notes for more details on these changes. • The module django.utils.simplejson will be removed. The standard library provides json which should be used instead. • The function django.utils.itercompat.product will be removed. The Python builtin version should be used instead. • Auto-correction of INSTALLED_APPS and TEMPLATE_DIRS settings when they are specified as a plain string instead of a tuple will be removed and raise an exception. • The mimetype argument to the __init__ methods of HttpResponse, SimpleTemplateResponse, and TemplateResponse, will be removed. content_type should be used instead. This also applies to the render_to_response() shortcut and the sitemap views, index() and sitemap(). • When HttpResponse is instantiated with an iterator, or when content is set to an iterator, that iterator will be immediately consumed. • The AUTH_PROFILE_MODULE setting, and the get_profile() method on the User model, will be removed. • The cleanup management command will be removed. It’s replaced by clearsessions. • The daily_cleanup.py script will be removed. • The depth keyword argument will be removed from select_related(). • The undocumented get_warnings_state()/restore_warnings_state() functions from django.test.utils and the save_warnings_state()/ restore_warnings_state() django.test.*TestCase methods are deprecated. Use the warnings.catch_warnings context manager available starting with Python 2.6 instead. • The undocumented check_for_test_cookie method in AuthenticationForm will be removed following an accelerated deprecation. Users subclassing this form should remove calls to this method, and instead ensure that their auth related views are CSRF protected, which ensures that cookies are enabled.

10.6. Django Deprecation Timeline

1785

Django Documentation, Release 2.1.dev20171115023625

• The version of django.contrib.auth.views.password_reset_confirm() that supports base36 encoded user IDs (django.contrib.auth.views.password_reset_confirm_uidb36) will be removed. If your site has been running Django 1.6 for more than PASSWORD_RESET_TIMEOUT_DAYS, this change will have no effect. If not, then any password reset links generated before you upgrade to Django 1.7 won’t work after the upgrade. • The django.utils.encoding.StrAndUnicode mix-in will be removed. Define a __str__ method and apply the python_2_unicode_compatible() decorator instead.

10.6.8 1.6 See the Django 1.4 release notes for more details on these changes. • django.contrib.databrowse will be removed. • django.contrib.localflavor will be removed following an accelerated deprecation. • django.contrib.markup will be removed following an accelerated deprecation. • The compatibility modules django.utils.copycompat and django.utils.hashcompat as well as the functions django.utils.itercompat.all and django.utils.itercompat.any will be removed. The Python builtin versions should be used instead. • The csrf_response_exempt and csrf_view_exempt decorators will be removed. Since 1.4 csrf_response_exempt has been a no-op (it returns the same function), and csrf_view_exempt has been a synonym for django.views.decorators.csrf.csrf_exempt, which should be used to replace it. • The django.core.cache.backends.memcached.CacheClass backend was split into two in Django 1.3 in order to introduce support for PyLibMC. The historical CacheClass will be removed in favor of django.core.cache.backends.memcached.MemcachedCache. • The UK-prefixed objects of django.contrib.localflavor.uk will only be accessible through their GB-prefixed names (GB is the correct ISO 3166 code for United Kingdom). • The IGNORABLE_404_STARTS and IGNORABLE_404_ENDS settings have been superseded by IGNORABLE_404_URLS in the 1.4 release. They will be removed. • The form wizard has been refactored to use class-based views with pluggable backends in 1.4. The previous implementation will be removed. • Legacy ways of calling cache_page() will be removed. • The backward-compatibility shim to automatically add a debug-false filter to the 'mail_admins' logging handler will be removed. The LOGGING setting should include this filter explicitly if it is desired. • The builtin truncation functions django.utils.text.truncate_words() and django.utils. text.truncate_html_words() will be removed in favor of the django.utils.text.Truncator class. • The django.contrib.gis.geoip.GeoIP class was moved to django.contrib.gis.geoip in 1.4 – the shortcut in django.contrib.gis.utils will be removed. • django.conf.urls.defaults will be removed. The functions include(), patterns(), and url(), plus handler404 and handler500 are now available through django.conf.urls. • The functions setup_environ() and execute_manager() will be removed from django.core. management. This also means that the old (pre-1.4) style of manage.py file will no longer work. • Setting the is_safe and needs_autoescape flags as attributes of template filter functions will no longer be supported.

1786

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

• The attribute HttpRequest.raw_post_data was renamed to HttpRequest.body in 1.4. The backward compatibility will be removed – HttpRequest.raw_post_data will no longer work. • The value for the post_url_continue parameter in ModelAdmin.response_add() will have to be either None (to redirect to the newly created object’s edit page) or a pre-formatted url. String formats, such as the previous default '../%s/', will not be accepted any more.

10.6.9 1.5 See the Django 1.3 release notes for more details on these changes. • Starting Django without a SECRET_KEY will result in an exception rather than a DeprecationWarning. (This is accelerated from the usual deprecation path; see the Django 1.4 release notes.) • The mod_python request handler will be removed. The mod_wsgi handler should be used instead. • The template attribute on django.test.client.Response objects returned by the test client will be removed. The templates attribute should be used instead. • The django.test.simple.DjangoTestRunner will be removed. Instead use a unittest-native class. The features of the django.test.simple.DjangoTestRunner (including fail-fast and Ctrl-C test termination) can currently be provided by the unittest-native TextTestRunner. • The undocumented function django.contrib.formtools.utils.security_hash will be removed, instead use django.contrib.formtools.utils.form_hmac • The function-based generic view modules will be removed in favor of their class-based equivalents, outlined here. • The django.core.servers.basehttp.AdminMediaHandler will be removed. In its place use django.contrib.staticfiles.handlers.StaticFilesHandler. • The template tags library adminmedia and the template tag {% admin_media_prefix %} will be removed in favor of the generic static files handling. (This is faster than the usual deprecation path; see the Django 1.4 release notes.) • The url and ssi template tags will be modified so that the first argument to each tag is a template variable, not an implied string. In 1.4, this behavior is provided by a version of the tag in the future template tag library. • The reset and sqlreset management commands will be removed. • Authentication backends will need to support an inactive user being passed to all methods dealing with permissions. The supports_inactive_user attribute will no longer be checked and can be removed from custom backends. • transform() will raise a GEOSException when called on a geometry with no SRID value. • django.http.CompatCookie will be removed in favor of django.http.SimpleCookie. • django.core.context_processors.PermWrapper and django.core. context_processors.PermLookupDict will be removed in favor of the corresponding django.contrib.auth.context_processors.PermWrapper and django.contrib.auth. context_processors.PermLookupDict, respectively. • The MEDIA_URL or STATIC_URL settings will be required to end with a trailing slash to ensure there is a consistent way to combine paths in templates. • django.db.models.fields.URLField.verify_exists will be removed. The feature was deprecated in 1.3.1 due to intractable security and performance issues and will follow a slightly accelerated deprecation timeframe.

10.6. Django Deprecation Timeline

1787

Django Documentation, Release 2.1.dev20171115023625

• Translations located under the so-called project path will be ignored during the translation building process performed at runtime. The LOCALE_PATHS setting can be used for the same task by including the filesystem path to a locale directory containing non-app-specific translations in its value. • The Markup contrib app will no longer support versions of Python-Markdown library earlier than 2.1. An accelerated timeline was used as this was a security related deprecation. • The CACHE_BACKEND setting will be removed. The cache backend(s) should be specified in the CACHES setting.

10.6.10 1.4 See the Django 1.2 release notes for more details on these changes. • CsrfResponseMiddleware and CsrfMiddleware will be removed. Use the {% csrf_token %} template tag inside forms to enable CSRF protection. CsrfViewMiddleware remains and is enabled by default. • The old imports for CSRF functionality (django.contrib.csrf.*), which moved to core in 1.2, will be removed. • The django.contrib.gis.db.backend module will be removed in favor of the specific backends. • SMTPConnection will be removed in favor of a generic Email backend API. • The many to many SQL generation functions on the database backends will be removed. • The ability to use the DATABASE_* family of top-level settings to define database connections will be removed. • The ability to use shorthand notation to specify a database backend (i.e., sqlite3 instead of django.db. backends.sqlite3) will be removed. • The get_db_prep_save, get_db_prep_value and get_db_prep_lookup methods will have to support multiple databases. • The Message model (in django.contrib.auth), its related manager in the User model (user.message_set), and the associated methods (user.message_set.create() and user. get_and_delete_messages()), will be removed. The messages framework should be used instead. The related messages variable returned by the auth context processor will also be removed. Note that this means that the admin application will depend on the messages context processor. • Authentication backends will need to support the obj parameter for permission checking. The supports_object_permissions attribute will no longer be checked and can be removed from custom backends. • Authentication backends will need to support the AnonymousUser class being passed to all methods dealing with permissions. The supports_anonymous_user variable will no longer be checked and can be removed from custom backends. • The ability to specify a callable template loader rather than a Loader class will be removed, as will the load_template_source functions that are included with the built in template loaders for backwards compatibility. • django.utils.translation.get_date_formats() and django.utils.translation. get_partial_date_formats(). These functions will be removed; use the locale-aware django. utils.formats.get_format() to get the appropriate formats. • In django.forms.fields, the constants: DEFAULT_DATE_INPUT_FORMATS, DEFAULT_TIME_INPUT_FORMATS and DEFAULT_DATETIME_INPUT_FORMATS will be removed. Use django.utils.formats.get_format() to get the appropriate formats.

1788

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

• The ability to use a function-based test runner will be removed, along with the django.test.simple. run_tests() test runner. • The views.feed() view and feeds.Feed class in django.contrib.syndication will be removed. The class-based view views.Feed should be used instead. • django.core.context_processors.auth. This release will remove the old method in favor of the new method in django.contrib.auth.context_processors.auth. • The postgresql database backend will be removed, use the postgresql_psycopg2 backend instead. • The no language code will be removed and has been replaced by the nb language code. • Authentication backends will need to define the boolean attribute supports_inactive_user until version 1.5 when it will be assumed that all backends will handle inactive users. • django.db.models.fields.XMLField will be removed. This was deprecated as part of the 1.3 release. An accelerated deprecation schedule has been used because the field hasn’t performed any role beyond that of a simple TextField since the removal of oldforms. All uses of XMLField can be replaced with TextField. • The undocumented mixin parameter to the open() method of django.core.files.storage. Storage (and subclasses) will be removed.

10.6.11 1.3 See the Django 1.1 release notes for more details on these changes. • AdminSite.root(). This method of hooking up the admin URLs will be removed in favor of including admin.site.urls. • Authentication backends need to define the boolean attributes supports_object_permissions and supports_anonymous_user until version 1.4, at which point it will be assumed that all backends will support these options.

10.7 The Django source code repository When deploying a Django application into a real production environment, you will almost always want to use an official packaged release of Django. However, if you’d like to try out in-development code from an upcoming release or contribute to the development of Django, you’ll need to obtain a clone of Django’s source code repository. This document covers the way the code repository is laid out and how to work with and find things in it.

10.7.1 High-level overview The Django source code repository uses Git to track changes to the code over time, so you’ll need a copy of the Git client (a program called git) on your computer, and you’ll want to familiarize yourself with the basics of how Git works. Git’s website offers downloads for various operating systems. The site also contains vast amounts of documentation. The Django Git repository is located online at github.com/django/django. It contains the full source code for all Django releases, which you can browse online. The Git repository includes several branches:

10.7. The Django source code repository

1789

Django Documentation, Release 2.1.dev20171115023625

• master contains the main in-development code which will become the next packaged release of Django. This is where most development activity is focused. • stable/A.B.x are the branches where release preparation work happens. They are also used for bugfix and security releases which occur as necessary after the initial release of a feature version. • soc20XX/ branches were used by students who worked on Django during the 2009 and 2010 Google Summer of Code programs. • attic/ branches were used to develop major or experimental new features without affecting the rest of Django’s code. The Git repository also contains tags. These are the exact revisions from which packaged Django releases were produced, since version 1.0. The source code for the Djangoproject.com website can be found at github.com/django/djangoproject.com.

10.7.2 The master branch If you’d like to try out the in-development code for the next release of Django, or if you’d like to contribute to Django by fixing bugs or developing new features, you’ll want to get the code from the master branch. Note that this will get all of Django: in addition to the top-level django module containing Python code, you’ll also get a copy of Django’s documentation, test suite, packaging scripts and other miscellaneous bits. Django’s code will be present in your clone as a directory named django. To try out the in-development code with your own applications, simply place the directory containing your clone on your Python import path. Then import statements which look for Django will find the django module within your clone. If you’re going to be working on Django’s code (say, to fix a bug or develop a new feature), you can probably stop reading here and move over to the documentation for contributing to Django, which covers things like the preferred coding style and how to generate and submit a patch.

10.7.3 Other branches Django uses branches to prepare for releases of Django. In the past when Django was hosted on Subversion, branches were also used for feature development. Now Django is hosted on Git and feature development is done on contributor’s forks, but the Subversion feature branches remain in Git for historical reference. Stable branches These branches can be found in the repository as stable/A.B.x branches and will be created right after the first alpha is tagged. For example, immediately after Django 1.5 alpha 1 was tagged, the branch stable/1.5.x was created and all further work on preparing the code for the final 1.5 release was done there. These branches also provide limited bugfix support for the most recent released version of Django and security support for the two most recently-released versions of Django. For example, after the release of Django 1.5, the branch stable/1.5.x receives only fixes for security and critical stability bugs, which are eventually released as Django 1.5.1 and so on, stable/1.4.x receives only security fixes, and stable/1.3.x no longer receives any updates.

1790

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

Historical information This policy for handling stable/A.B.x branches was adopted starting with the Django 1.5 release cycle. Previously, these branches weren’t created until right after the releases and the stabilization work occurred on the main repository branch. Thus, no new features development work for the next release of Django could be committed until the final release happened. For example, shortly after the release of Django 1.3 the branch stable/1.3.x was created. Official support for that release has expired, and so it no longer receives direct maintenance from the Django project. However, that and all other similarly named branches continue to exist and interested community members have occasionally used them to provide unofficial support for old Django releases.

Feature-development branches

Historical information Since Django moved to Git in 2012, anyone can clone the repository and create their own branches, alleviating the need for official branches in the source code repository. The following section is mostly useful if you’re exploring the repository’s history, for example if you’re trying to understand how some features were designed. Feature-development branches tend by their nature to be temporary. Some produce successful features which are merged back into Django’s master to become part of an official release, but others do not; in either case there comes a time when the branch is no longer being actively worked on by any developer. At this point the branch is considered closed. Unfortunately, Django used to be maintained with the Subversion revision control system, that has no standard way of indicating this. As a workaround, branches of Django which are closed and no longer maintained were moved into attic. For reference, the following are branches whose code eventually became part of Django itself, and so are no longer separately maintained: • boulder-oracle-sprint: Added support for Oracle databases to Django’s object-relational mapper. This has been part of Django since the 1.0 release. • gis: Added support for geographic/spatial queries to Django’s object-relational mapper. This has been part of Django since the 1.0 release, as the bundled application django.contrib.gis. • i18n: Added internationalization support to Django. This has been part of Django since the 0.90 release. • magic-removal: A major refactoring of both the internals and public APIs of Django’s object-relational mapper. This has been part of Django since the 0.95 release. • multi-auth: A refactoring of Django’s bundled authentication framework which added support for authentication backends. This has been part of Django since the 0.95 release. • new-admin: A refactoring of Django’s bundled administrative application. This became part of Django as of the 0.91 release, but was superseded by another refactoring (see next listing) prior to the Django 1.0 release. • newforms-admin: The second refactoring of Django’s bundled administrative application. This became part of Django as of the 1.0 release, and is the basis of the current incarnation of django.contrib.admin. • queryset-refactor: A refactoring of the internals of Django’s object-relational mapper. This became part of Django as of the 1.0 release.

10.7. The Django source code repository

1791

Django Documentation, Release 2.1.dev20171115023625

• unicode: A refactoring of Django’s internals to consistently use Unicode-based strings in most places within Django and Django applications. This became part of Django as of the 1.0 release. When Django moved from SVN to Git, the information about branch merges wasn’t preserved in the source code repository. This means that the master branch of Django doesn’t contain merge commits for the above branches. However, this information is available as a grafts file. You can restore it by putting the following lines in .git/ info/grafts in your local clone: ac64e91a0cadc57f4bc5cd5d66955832320ca7a1 553a20075e6991e7a60baee51ea68c8adc520d9a ˓→0cb8e31823b2e9f05c4ae868c19f5f38e78a5f2e 79e68c225b926302ebb29c808dda8afa49856f5c d0f57e7c7385a112cb9e19d314352fc5ed5b0747 ˓→aa239e3e5405933af6a29dac3cf587b59a099927 5cf8f684237ab5addaf3549b2347c3adf107c0a7 cb45fd0ae20597306cd1f877efc99d9bd7cbee98 ˓→e27211a0deae2f1d402537f0ebb64ad4ccf6a4da f69cf70ed813a8cd7e1f963a14ae39103e8d5265 d5dbeaa9be359a4c794885c2e9f1b5a7e5e51fb8 ˓→d2fcbcf9d76d5bb8a661ee73dae976c74183098b aab3a418ac9293bb4abd7670f65d930cb0426d58 4ea7a11659b8a0ab07b0d2e847975f7324664f10 ˓→adf4b9311d5d64a2bdd58da50271c121ea22e397 ff60c5f9de3e8690d1e86f3e9e3f7248a15397c8 7ef212af149540aa2da577a960d0d87029fd1514 ˓→45b4288bb66a3cda401b45901e85b645674c3988 9dda4abee1225db7a7b195b84c915fdd141a7260 4fe5c9b7ee09dc25921918a6dbb7605edb374bc9 ˓→3a7c14b583621272d4ef53061287b619ce3c290d a19ed8aea395e8e07164ff7d85bd7dff2f24edca dc375fb0f3b7fbae740e8cfcd791b8bccb8a4e66 ˓→42ea7a5ce8aece67d16c6610a49560c1493d4653 9c52d56f6f8a9cdafb231adf9f4110473099c9b5 c91a30f00fd182faf8ca5c03cd7dbcf8b735b458 ˓→4a5c5c78f2ecd4ed8859cd5ac773ff3a01bccf96 953badbea5a04159adbfa970f5805c0232b6a401 4c958b15b250866b70ded7d82aa532f1e57f96ae ˓→5664a678b29ab04cad425c15b2792f4519f43928 471596fc1afcb9c6258d317c619eaf5fd394e797 4e89105d64bb9e04c409139a41e9c7aac263df4c ˓→3e9035a9625c8a8a5e88361133e87ce455c4fc13 9233d0426537615e06b78d28010d17d5a66adf44 6632739e94c6c38b4c5a86cf5c80c48ae50ac49f ˓→18e151bc3f8a85f2766d64262902a9fcad44d937

Additionally, the following branches are closed, but their code was never merged into Django and the features they aimed to implement were never finished: • full-history • generic-auth • multiple-db-support • per-object-permissions • schema-evolution • schema-evolution-ng • search-api • sqlalchemy All of the above-mentioned branches now reside in attic. Finally, the repository contains soc2009/xxx and soc2010/xxx feature branches, used for Google Summer of Code projects.

10.7.4 Tags Each Django release is tagged and signed by the releaser.

1792

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

The tags can be found on GitHub’s tags page.

10.8 How is Django Formed? This document explains how to release Django. Please, keep these instructions up-to-date if you make changes! The point here is to be descriptive, not prescriptive, so feel free to streamline or otherwise make changes, but update this document accordingly!

10.8.1 Overview There are three types of releases that you might need to make: • Security releases: disclosing and fixing a vulnerability. This’ll generally involve two or three simultaneous releases – e.g. 1.5.x, 1.6.x, and, depending on timing, perhaps a 1.7 alpha/beta/rc. • Regular version releases: either a final release (e.g. 1.5) or a bugfix update (e.g. 1.5.1). • Pre-releases: e.g. 1.6 alpha, beta, or rc. The short version of the steps involved is: 1. If this is a security release, pre-notify the security distribution list one week before the actual release. 2. Proofread the release notes, looking for organization and writing errors. Draft a blog post and email announcement. 3. Update version numbers and create the release package(s). 4. Upload the package(s) to the djangoproject.com server. 5. Upload the new version(s) to PyPI. 6. Declare the new version in the admin on djangoproject.com. 7. Post the blog entry and send out the email announcements. 8. Update version numbers post-release. There are a lot of details, so please read on.

10.8.2 Prerequisites You’ll need a few things before getting started: • A GPG key. If the key you want to use is not your default signing key, you’ll need to add -u [emailprotected] com to every GPG signing command below, where [emailprotected] is the email address associated with the key you want to use. • An install of some required Python packages: $ pip install wheel twine

• Access to Django’s record on PyPI. Create a file with your credentials: /.pypirc [pypi] username:YourUsername password:YourPassword

10.8. How is Django Formed?

1793

Django Documentation, Release 2.1.dev20171115023625

• Access to the djangoproject.com server to upload files. • Access to the admin on djangoproject.com as a “Site maintainer”. • Access to post to django-announce. • If this is a security release, access to the pre-notification distribution list. If this is your first release, you’ll need to coordinate with James and/or Jacob to get all these things lined up.

10.8.3 Pre-release tasks A few items need to be taken care of before even beginning the release process. This stuff starts about a week before the release; most of it can be done any time leading up to the actual release: 1. If this is a security release, send out pre-notification one week before the release. We maintain a list of who gets these pre-notification emails in the private django-core repository. Send the mail to [emailprotected] and BCC the pre-notification recipients. This email should be signed by the key you’ll use for the release and should include CVE IDs (requested with Vendor: djangoproject, Product: django) and patches for each issue being fixed. Also, notify django-announce of the upcoming security release. 2. As the release approaches, watch Trac to make sure no release blockers are left for the upcoming release. 3. Check with the other committers to make sure they don’t have any uncommitted changes for the release. 4. Proofread the release notes, including looking at the online version to catch any broken links or reST errors, and make sure the release notes contain the correct date. 5. Double-check that the release notes mention deprecation timelines for any APIs noted as deprecated, and that they mention any changes in Python version support. 6. Double-check that the release notes index has a link to the notes for the new release; this will be in docs/ releases/index.txt. 7. If this is a feature release, ensure translations from Transifex have been integrated. This is typically done by a separate translation’s manager rather than the releaser, but here are the steps. Provided you have an account on Transifex: $ python scripts/manage_translations.py fetch

and then commit the changed/added files (both .po and .mo). Sometimes there are validation errors which need to be debugged, so avoid doing this task immediately before a release is needed. 8. Update the django-admin manual page: $ $ $ $

cd docs make man man _build/man/django-admin.1 # do a quick sanity check cp _build/man/django-admin.1 man/django-admin.1

and then commit the changed man page.

10.8.4 Preparing for release Write the announcement blog post for the release. You can enter it into the admin at any time and mark it as inactive. Here are a few examples: example security release announcement, example regular release announcement, example pre-release announcement.

1794

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

10.8.5 Actually rolling the release OK, this is the fun part, where we actually push out a release! 1. Check Jenkins is green for the version(s) you’re putting out. You probably shouldn’t issue a release until it’s green. 2. A release always begins from a release branch, so you should make sure you’re on a stable branch and up-to-date. For example: $ git checkout stable/1.5.x $ git pull

3. If this is a security release, merge the appropriate patches from django-private. Rebase these patches as necessary to make each one a simple commit on the release branch rather than a merge commit. To ensure this, merge them with the --ff-only flag; for example: $ git checkout stable/1.5.x $ git merge --ff-only security/1.5.x

(This assumes security/1.5.x is a branch in the django-private repo containing the necessary security patches for the next release in the 1.5 series.) If git refuses to merge with --ff-only, switch to the security-patch branch and rebase it on the branch you are about to merge it into (git checkout security/1.5.x; git rebase stable/1.5.x) and then switch back and do the merge. Make sure the commit message for each security fix explains that the commit is a security fix and that an announcement will follow (example security commit). 4. For a feature release, remove the UNDER DEVELOPMENT header at the top of the release notes and add the release date on the next line. For a patch release, replace *Under Development* with the release date. Make this change on all branches where the release notes for a particular version are located. 5. Update the version number in django/__init__.py for the release. Please see notes on setting the VERSION tuple below for details on VERSION. 6. If this is a pre-release package, update the “Development Status” trove classifier in setup.py to reflect this. Otherwise, make sure the classifier is set to Development Status :: 5 - Production/Stable. 7. Tag the release using git tag. For example: $ git tag --sign --message="Tag 1.5.1" 1.5.1

You can check your work by running git tag --verify . 8. Push your work, including the tag: git push --tags. 9. Make sure you have an absolutely clean tree by running git clean -dfx. 10. Run make -f extras/Makefile to generate the release packages. This will create the release packages in a dist/ directory. 11. Generate the hashes of the release packages: $ $ $ $

cd dist md5sum * sha1sum * sha256sum *

12. Create a “checksums” file, Django-.checksum.txt containing the hashes and release information. Start with this template and insert the correct version, date, GPG key ID (from gpg --list-keys --keyid-format LONG), release URL, and checksums:

10.8. How is Django Formed?

1795

Django Documentation, Release 2.1.dev20171115023625

This file contains MD5, SHA1, and SHA256 checksums for the source-code tarball and wheel files of Django , released . To use this file, you will need a working install of PGP or other compatible public-key encryption software. You will also need to have the Django release manager's public key in your keyring; this key has the ID ``XXXXXXXXXXXXXXXX`` and can be imported from the MIT keyserver. For example, if using the open-source GNU Privacy Guard implementation of PGP: gpg --keyserver pgp.mit.edu --recv-key XXXXXXXXXXXXXXXX Once the key is imported, verify this file:: gpg --verify Once you have verified this file, you can use normal MD5, SHA1, or SHA256 checksumming applications to generate the checksums of the Django package and compare them to the checksums listed below. Release packages: ================= https://www.djangoproject.com/m/releases/ https://www.djangoproject.com/m/releases/ MD5 checksums: ==============

SHA1 checksums: ===============

SHA256 checksums: =================

13. Sign the checksum file (gpg --clearsign --digest-algo SHA256 Django-. checksum.txt). This generates a signed document, Django-.checksum.txt.asc which you can then verify using gpg --verify Django-.checksum.txt.asc. If you’re issuing multiple releases, repeat these steps for each release.

10.8.6 Making the release(s) available to the public Now you’re ready to actually put the release out there. To do this: 1. Upload the release package(s) to the djangoproject server, replacing A.B. with the appropriate version number, e.g. 1.5 for a 1.5.x release:

1796

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

$ scp Django-* djangoproject.com:/home/www/www/media/releases/A.B

2. Upload the checksum file(s): $ scp Django-A.B.C.checksum.txt.asc djangoproject.com:/home/www/www/media/pgp/ ˓→Django-A.B.C.checksum.txt

3. Test that the release packages install correctly using easy_install and pip. Here’s one method (which requires virtualenvwrapper): $ RELEASE_VERSION='1.7.2' $ MAJOR_VERSION=`echo $RELEASE_VERSION| cut -c 1-3` $ mktmpenv $ easy_install https://www.djangoproject.com/m/releases/$MAJOR_VERSION/Django˓→$RELEASE_VERSION.tar.gz $ deactivate $ mktmpenv $ pip install https://www.djangoproject.com/m/releases/$MAJOR_VERSION/Django˓→$RELEASE_VERSION.tar.gz $ deactivate $ mktmpenv $ pip install https://www.djangoproject.com/m/releases/$MAJOR_VERSION/Django˓→$RELEASE_VERSION-py3-none-any.whl $ deactivate

This just tests that the tarballs are available (i.e. redirects are up) and that they install correctly, but it’ll catch silly mistakes. 4. Ask a few people on IRC to verify the checksums by visiting the checksums file (e.g. https://www.djangoproject. com/m/pgp/Django-1.5b1.checksum.txt) and following the instructions in it. For bonus points, they can also unpack the downloaded release tarball and verify that its contents appear to be correct (proper version numbers, no stray .pyc or other undesirable files). 5. Upload the release packages to PyPI (for pre-releases, only upload the wheel file): $ twine upload -s dist/*

6. Go to the Add release page in the admin, enter the new release number exactly as it appears in the name of the tarball (Django-.tar.gz). So for example enter “1.5.1” or “1.4c2”, etc. If the release is part of an LTS branch, mark it so. 7. Make the blog post announcing the release live. 8. For a new version release (e.g. 1.5, 1.6), update the default stable version of the docs by flipping the is_default flag to True on the appropriate DocumentRelease object in the docs.djangoproject. com database (this will automatically flip it to False for all others); you can do this using the site’s admin. Create new DocumentRelease objects for each language that has an entry for the previous release. Update djangoproject.com’s robots.docs.txt file by copying entries from the previous release. 9. Post the release announcement to the django-announce, django-developers, and django-users mailing lists. This should include a link to the announcement blog post. If this is a security release, also include [emailprotected] 10. Add a link to the blog post in the topic of the #django IRC channel: /msg chanserv TOPIC #django new topic goes here.

10.8. How is Django Formed?

1797

Django Documentation, Release 2.1.dev20171115023625

10.8.7 Post-release You’re almost done! All that’s left to do now is: 1. Update the VERSION tuple in django/__init__.py again, incrementing to whatever the next expected release will be. For example, after releasing 1.5.1, update VERSION to VERSION = (1, 5, 2, 'alpha', 0). 2. Add the release in Trac’s versions list if necessary (and make it the default if it’s a final release). Not all versions are declared; take example on previous releases. 3. If this was a security release, update Archive of security issues with details of the issues addressed.

10.8.8 New stable branch tasks There are several items to do in the time following the creation of a new stable branch (often following an alpha release). Some of these tasks don’t need to be done by the releaser. 1. Create a new DocumentRelease object in the docs.djangoproject.com database for the new version’s docs, and update the docs/fixtures/doc_releases.json JSON fixture, so people without access to the production DB can still run an up-to-date copy of the docs site. 2. Create a stub release note for the new feature version. Use the stub from the previous feature release version or copy the contents from the previous feature version and delete most of the contents leaving only the headings. 3. Increase the default PBKDF2 iterations in django.contrib.auth.hashers. PBKDF2PasswordHasher by about 20% (pick a round number). Run the tests, and update the 3 failing hasher tests with the new values. Make sure this gets noted in the release notes (see the 1.8 release notes for an example). 4. Remove features that have reached the end of their deprecation cycle. Each removal should be done in a separate commit for clarity. In the commit message, add a “refs #XXXX” to the original ticket where the deprecation began if possible. 5. Remove .. versionadded::, .. versionadded::, and .. deprecated:: annotations in the documentation from two releases ago. For example, in Django 1.9, notes for 1.7 will be removed. 6. Add the new branch to Read the Docs. Since the automatically generated version names (“stable-A.B.x”) differ from the version numbers we’ve used historically in Read the Docs (“A.B.x”), we currently ask Eric Holscher to add the version for us. Someday the alias functionality may be built-in to the Read the Docs UI.

10.8.9 Notes on setting the VERSION tuple Django’s version reporting is controlled by the VERSION tuple in django/__init__.py. This is a five-element tuple, whose elements are: 1. Major version. 2. Minor version. 3. Micro version. 4. Status – can be one of “alpha”, “beta”, “rc” or “final”. 5. Series number, for alpha/beta/RC packages which run in sequence (allowing, for example, “beta 1”, “beta 2”, etc.). For a final release, the status is always “final” and the series number is always 0. A series number of 0 with an “alpha” status will be reported as “pre-alpha”.

1798

Chapter 10. Django internals

Django Documentation, Release 2.1.dev20171115023625

Some examples: • (1, 2, 1, 'final', 0) → “1.2.1” • (1, 3, 0, 'alpha', 0) → “1.3 pre-alpha” • (1, 3, 0, 'beta', 2) → “1.3 beta 2”

10.8. How is Django Formed?

1799

Django Documentation, Release 2.1.dev20171115023625

1800

Chapter 10. Django internals

CHAPTER

11

Indices, glossary and tables

• genindex • modindex • Glossary

1801

Django Documentation, Release 2.1.dev20171115023625

1802

Chapter 11. Indices, glossary and tables

Python Module Index

a

django.contrib.gis.utils.ogrinspect, 872 django.contrib.humanize, 879 django.contrib.messages, 881 c django.contrib.messages.middleware, 1077 django.contrib.postgres, 887 django.conf.urls, 1375 django.contrib.postgres.aggregates, 887 django.conf.urls.i18n, 462 django.contrib.postgres.indexes, 908 django.contrib.admin, 694 django.contrib.postgres.validators, 914 django.contrib.admindocs, 701 django.contrib.redirects, 915 django.contrib.auth, 408 django.contrib.sessions, 214 django.contrib.auth.backends, 753 django.contrib.sessions.middleware, 1079 django.contrib.auth.forms, 380 django.contrib.sitemaps, 916 django.contrib.auth.hashers, 389 django.contrib.sites, 924 django.contrib.auth.middleware, 1079 django.contrib.auth.password_validation, django.contrib.sites.middleware, 1079 django.contrib.staticfiles, 930 389 django.contrib.syndication, 937 django.contrib.auth.signals, 752 django.core.checks, 528 django.contrib.auth.views, 373 django.core.exceptions, 1001 django.contrib.contenttypes, 755 django.core.files, 1005 django.contrib.contenttypes.admin, 760 django.core.files.storage, 1007 django.contrib.contenttypes.fields, 757 django.core.files.uploadedfile, 1010 django.contrib.contenttypes.forms, 760 django.core.files.uploadhandler, 1011 django.contrib.flatpages, 761 django.core.mail, 433 django.contrib.gis, 766 django.core.management, 535 django.contrib.gis.admin, 874 django.core.paginator, 498 django.contrib.gis.db.backends, 794 django.core.signals, 1297 django.contrib.gis.db.models, 790 django.contrib.gis.db.models.functions, django.core.signing, 431 django.core.validators, 1390 815 django.contrib.gis.feeds, 875 d django.contrib.gis.forms, 801 django.db, 84 django.contrib.gis.forms.widgets, 802 django.db.backends, 1299 django.contrib.gis.gdal, 840 django.db.backends.base.schema, 1242 django.contrib.gis.geoip2, 866 django.db.migrations, 309 django.contrib.gis.geos, 824 django.db.migrations.operations, 1081 django.contrib.gis.measure, 822 django.contrib.gis.serializers.geojson, django.db.models, 84 django.db.models.fields, 1088 872 django.db.models.fields.related, 1103 django.contrib.gis.utils, 869 django.db.models.functions, 1213 django.contrib.gis.utils.layermapping, django.db.models.indexes, 1114 869 django.apps, 625

1803

Django Documentation, Release 2.1.dev20171115023625

django.db.models.lookups, 1190 django.db.models.options, 1115 django.db.models.signals, 1292 django.db.transaction, 146 django.dispatch, 524

f django.forms, 1013 django.forms.fields, 1033 django.forms.formsets, 236 django.forms.models, 247 django.forms.renderers, 1053 django.forms.widgets, 1055

h django.http, 1228

m

django.utils.http, 1384 django.utils.log, 487 django.utils.module_loading, 1385 django.utils.safestring, 1385 django.utils.text, 1386 django.utils.timezone, 1386 django.utils.translation, 443

v django.views, 1394 django.views.decorators.cache, 201 django.views.decorators.csrf, 958 django.views.decorators.gzip, 201 django.views.decorators.http, 200 django.views.decorators.vary, 201 django.views.generic.dates, 653 django.views.i18n, 457

django.middleware, 1075 django.middleware.cache, 1075 django.middleware.clickjacking, 1080 django.middleware.common, 1075 django.middleware.csrf, 1080 django.middleware.exception, 1076 django.middleware.gzip, 1076 django.middleware.http, 1076 django.middleware.locale, 1077 django.middleware.security, 1077

s django.shortcuts, 205

t django.template, 272 django.template.backends, 275 django.template.backends.django, 275 django.template.backends.jinja2, 276 django.template.loader, 273 django.template.response, 1361 django.test, 322 django.test.signals, 1298 django.test.utils, 360

u django.urls, 1370 django.urls.conf, 1373 django.utils, 1376 django.utils.cache, 1376 django.utils.dateparse, 1377 django.utils.decorators, 1378 django.utils.encoding, 1378 django.utils.feedgenerator, 1379 django.utils.functional, 1381 django.utils.html, 1383 1804

Python Module Index

Index

Symbols –add-location [{full,file,never}] makemessages command line option, 985 –addrport ADDRPORT testserver command line option, 995 –admins sendtestemail command line option, 989 –all diffsettings command line option, 979 –all, -a dumpdata command line option, 979 makemessages command line option, 984 –app APP_LABEL loaddata command line option, 981 –backwards sqlmigrate command line option, 990 –blank BLANK ogrinspect command line option, 873 –check makemigrations command line option, 986 –clear, -c collectstatic command line option, 932 –command COMMAND, -c COMMAND shell command line option, 989 –database DATABASE changepassword command line option, 995 createcachetable command line option, 978 createsuperuser command line option, 996 dbshell command line option, 979 dumpdata command line option, 980 flush command line option, 980 inspectdb command line option, 981 loaddata command line option, 981 migrate command line option, 986 remove_stale_contenttypes command line 996 showmigrations command line option, 990 sqlflush command line option, 990 sqlmigrate command line option, 990

sqlsequencereset command line option, 991 –debug-mode test command line option, 993 –debug-sql, -d test command line option, 994 –decimal DECIMAL ogrinspect command line option, 873 –default MODULE diffsettings command line option, 979 –deploy check command line option, 977 –domain DOMAIN, -d DOMAIN makemessages command line option, 984 –dry-run createcachetable command line option, 978 makemigrations command line option, 986 –dry-run, -n collectstatic command line option, 932 –email EMAIL createsuperuser command line option, 996 –empty makemigrations command line option, 986 –exclude EXCLUDE, -e EXCLUDE dumpdata command line option, 979 loaddata command line option, 981 –exclude EXCLUDE, -x EXCLUDE compilemessages command line option, 978 makemessages command line option, 984 –exclude-tag EXCLUDE_TAGS test command line option, 994 –extension EXTENSIONS, -e EXTENSIONS makemessages command line option, 984 startapp command line option, 992 startproject command line option, 993 –fail-level {CRITICAL,ERROR,WARNING,INFO,DEBUG} option, check command line option, 977 –failfast test command line option, 993 –fake migrate command line option, 986 1805

Django Documentation, Release 2.1.dev20171115023625

–fake-initial migrate command line option, 986 –format FORMAT dumpdata command line option, 979 loaddata command line option, 981 –geom-name GEOM_NAME ogrinspect command line option, 873 –ignore PATTERN, -i PATTERN collectstatic command line option, 932 makemessages command line option, 985 –ignorenonexistent, -i loaddata command line option, 981 –indent INDENT dumpdata command line option, 979 –insecure runserver command line option, 933 –interface {ipython,bpython,python}, {ipython,bpython,python} shell command line option, 989 –ipv6, -6 runserver command line option, 988 –keep-pot makemessages command line option, 985 –keepdb, -k test command line option, 993 –layer LAYER_KEY ogrinspect command line option, 873 –link, -l collectstatic command line option, 932 –list, -l showmigrations command line option, 990 –list-tags check command line option, 977 –locale LOCALE, -l LOCALE compilemessages command line option, 978 makemessages command line option, 984 –managers sendtestemail command line option, 989 –mapping ogrinspect command line option, 873 –merge makemigrations command line option, 986 –multi-geom ogrinspect command line option, 874 –name FILES, -n FILES startapp command line option, 992 startproject command line option, 993 –name NAME, -n NAME makemigrations command line option, 986 –name-field NAME_FIELD ogrinspect command line option, 874 –natural-foreign dumpdata command line option, 980 –natural-primary

1806

dumpdata command line option, 980 –no-color command line option, 998 –no-default-ignore collectstatic command line option, 932 makemessages command line option, 985 –no-imports ogrinspect command line option, 874 –no-location makemessages command line option, 985 –no-optimize squashmigrations command line option, 991 –no-post-process collectstatic command line option, 932 –no-wrap makemessages command line option, 985 -i –noinput, –no-input collectstatic command line option, 931 flush command line option, 980 makemigrations command line option, 986 migrate command line option, 987 squashmigrations command line option, 991 test command line option, 993 testserver command line option, 995 –noreload runserver command line option, 987 –nostartup shell command line option, 989 –nostatic runserver command line option, 933 –nothreading runserver command line option, 988 –null NULL ogrinspect command line option, 874 –output OUTPUT, -o OUTPUT dumpdata command line option, 980 –output {hash,unified} diffsettings command line option, 979 –parallel [N] test command line option, 994 –pks PRIMARY_KEYS dumpdata command line option, 980 –plan, -p showmigrations command line option, 990 –pythonpath PYTHONPATH command line option, 997 –reverse, -r test command line option, 993 –run-syncdb migrate command line option, 987 –settings SETTINGS command line option, 997 –squashed-name SQUASHED_NAME squashmigrations command line option, 991

Index

Django Documentation, Release 2.1.dev20171115023625

–srid SRID ogrinspect command line option, 874 –symlinks, -s makemessages command line option, 985 –tag TAGS test command line option, 994 –tag TAGS, -t TAGS check command line option, 977 –template TEMPLATE startapp command line option, 991 startproject command line option, 992 –testrunner TESTRUNNER test command line option, 993 –traceback command line option, 998 –use-fuzzy, -f compilemessages command line option, 978 –username USERNAME createsuperuser command line option, 996 –verbosity {0,1,2,3}, -v {0,1,2,3} command line option, 998 __contains__() (QueryDict method), 1234 __contains__() (backends.base.SessionBase method), 216 __delitem__() (HttpResponse method), 1238 __delitem__() (backends.base.SessionBase method), 216 __eq__() (Model method), 1138 __getattr__() (Area method), 824 __getattr__() (Distance method), 823 __getitem__() (HttpResponse method), 1238 __getitem__() (OGRGeometry method), 847 __getitem__() (QueryDict method), 1234 __getitem__() (SpatialReference method), 853 __getitem__() (backends.base.SessionBase method), 216 __hash__() (Model method), 1139 __init__() (HttpResponse method), 1238 __init__() (QueryDict method), 1234 __init__() (SimpleTemplateResponse method), 1362 __init__() (SyndicationFeed method), 1380 __init__() (TemplateResponse method), 1363 __init__() (requests.RequestSite method), 930 __iter__() (File method), 1006 __iter__() (HttpRequest method), 1233 __iter__() (OGRGeometry method), 847 __len__() (OGRGeometry method), 847 __setitem__() (HttpResponse method), 1238 __setitem__() (QueryDict method), 1234 __setitem__() (backends.base.SessionBase method), 216 __str__() (Model method), 1138 _base_manager (Model attribute), 136 _default_manager (Model attribute), 136 _open() (in module django.core.files.storage), 573 _save() (in module django.core.files.storage), 573

Index

A A (class in django.contrib.gis.measure), 824 ABSOLUTE_URL_OVERRIDES setting, 1245 abstract (Options attribute), 1122 AccessMixin (class in django.contrib.auth.mixins), 372 action_flag (LogEntry attribute), 746 action_time (LogEntry attribute), 745 actions (ModelAdmin attribute), 706 actions_on_bottom (ModelAdmin attribute), 706 actions_on_top (ModelAdmin attribute), 706 actions_selection_counter (ModelAdmin attribute), 706 activate() (in module django.utils.timezone), 1387 activate() (in module django.utils.translation), 1389 add template filter, 1328 add() (GeometryCollection method), 851 add() (RelatedManager method), 1119 add_action() (AdminSite method), 699 add_arguments() (BaseCommand method), 539 add_arguments() (django.test.runner.DiscoverRunner class method), 359 add_error() (Form method), 1015 add_field() (BaseDatabaseSchemaEditor method), 1244 add_form_template (ModelAdmin attribute), 723 add_index() (BaseDatabaseSchemaEditor method), 1243 add_item() (SyndicationFeed method), 1380 add_item_elements() (SyndicationFeed method), 1380 add_message() (in module django.contrib.messages), 883 add_never_cache_headers() (in module django.utils.cache), 1377 add_post_render_callback() (SimpleTemplateResponse method), 1363 add_root_elements() (SyndicationFeed method), 1380 add_view() (ModelAdmin method), 731 AddField (class in django.db.migrations.operations), 1083 AddIndex (class in django.db.migrations.operations), 1083 addslashes template filter, 1328 AdminEmailHandler (class in django.utils.log), 495 AdminPasswordChangeForm (class in django.contrib.auth.forms), 380 ADMINS setting, 1245 AdminSite (class in django.contrib.admin), 741 Aggregate (class in django.db.models), 1197 aggregate() (in module django.db.models.query.QuerySet), 1173 all() (in module django.db.models.query.QuerySet), 1152 allow_database_queries (SimpleTestCase attribute), 337 allow_empty (BaseDateListView attribute), 676

1807

Django Documentation, Release 2.1.dev20171115023625

allow_empty (django.views.generic.list.MultipleObjectMixinappendlist() (QueryDict method), 1235 attribute), 667 application namespace, 195 allow_files (FilePathField attribute), 1043, 1100 AppRegistryNotReady, 1002 allow_folders (FilePathField attribute), 1043, 1100 apps (in module django.apps), 629 allow_future (DateMixin attribute), 675 apps.AdminConfig (class in django.contrib.admin), 705 allow_migrate(), 157 apps.SimpleAdminConfig (class in allow_relation(), 157 django.contrib.admin), 705 allow_unicode (SlugField attribute), 1046, 1102 ArchiveIndexView (built-in class), 683 AllowAllUsersModelBackend (class in ArchiveIndexView (class in django.views.generic.dates), django.contrib.auth.backends), 754 654 AllowAllUsersRemoteUserBackend (class in Area (class in django.contrib.gis.db.models.functions), django.contrib.auth.backends), 754 815 ALLOWED_HOSTS Area (class in django.contrib.gis.measure), 824 setting, 1246 area (GEOSGeometry attribute), 832 alter_db_table() (BaseDatabaseSchemaEditor method), area (OGRGeometry attribute), 848 1244 arg_joiner (Func attribute), 1196 alter_db_tablespace() (BaseDatabaseSchemaEditor args (ResolverMatch attribute), 1372 method), 1244 arity (Func attribute), 1196 alter_field() (BaseDatabaseSchemaEditor method), 1244 ArrayAgg (class in django.contrib.postgres.aggregates), alter_index_together() (BaseDatabaseSchemaEditor 888 method), 1243 ArrayField (class in django.contrib.postgres.fields), 891 alter_unique_together() (BaseDatabaseSchemaEditor arrayfield.contained_by method), 1243 field lookup type, 893 AlterField (class in django.db.migrations.operations), arrayfield.contains 1083 field lookup type, 892 AlterIndexTogether (class in arrayfield.index django.db.migrations.operations), 1082 field lookup type, 893 AlterModelManagers (class in arrayfield.len django.db.migrations.operations), 1083 field lookup type, 893 AlterModelOptions (class in arrayfield.overlap django.db.migrations.operations), 1082 field lookup type, 893 AlterModelTable (class in arrayfield.slice django.db.migrations.operations), 1082 field lookup type, 894 AlterOrderWithRespectTo (class in as_data() (Form.errors method), 1015 django.db.migrations.operations), 1082 as_datetime() (Field method), 846 AlterUniqueTogether (class in as_double() (Field method), 846 django.db.migrations.operations), 1082 as_hidden() (BoundField method), 1029 angular_name (SpatialReference attribute), 855 as_int() (Field method), 846 angular_units (SpatialReference attribute), 855 as_json() (Form.errors method), 1015 annotate() (in module django.db.models.query.QuerySet), as_manager() (in module 1144 django.db.models.query.QuerySet), 1176 apnumber as_p() (Form method), 1020 template filter, 879 as_sql() (Func method), 1197 app_directories.Loader (class in as_sql() (in module django.db.models), 1191 django.template.loaders), 1359 as_string() (Field method), 846 app_index_template (AdminSite attribute), 742 as_table() (Form method), 1021 app_label (ContentType attribute), 755 as_ul() (Form method), 1021 app_label (Options attribute), 1122 as_vendorname() (in module django.db.models), 1191 app_name (ResolverMatch attribute), 1372 as_view() (django.views.generic.base.View class app_names (ResolverMatch attribute), 1372 method), 643 AppCommand (class in django.core.management), 539 as_widget() (BoundField method), 1029 AppConfig (class in django.apps), 627 asc() (Expression method), 1206 APPEND_SLASH AsGeoJSON (class in setting, 1246 django.contrib.gis.db.models.functions),

1808

Index

Django Documentation, Release 2.1.dev20171115023625

815 AsGML (class in django.contrib.gis.db.models.functions), 816 AsKML (class in django.contrib.gis.db.models.functions), 816 assertContains() (SimpleTestCase method), 347 assertFieldOutput() (SimpleTestCase method), 346 assertFormError() (SimpleTestCase method), 347 assertFormsetError() (SimpleTestCase method), 347 assertHTMLEqual() (SimpleTestCase method), 348 assertHTMLNotEqual() (SimpleTestCase method), 348 assertInHTML() (SimpleTestCase method), 349 assertJSONEqual() (SimpleTestCase method), 349 assertJSONNotEqual() (SimpleTestCase method), 349 assertNotContains() (SimpleTestCase method), 347 assertNumQueries() (TransactionTestCase method), 349 assertQuerysetEqual() (TransactionTestCase method), 349 assertRaisesMessage() (SimpleTestCase method), 346 assertRedirects() (SimpleTestCase method), 347 assertTemplateNotUsed() (SimpleTestCase method), 347 assertTemplateUsed() (SimpleTestCase method), 347 assertXMLEqual() (SimpleTestCase method), 348 assertXMLNotEqual() (SimpleTestCase method), 349 AsSVG (class in django.contrib.gis.db.models.functions), 816 Atom1Feed (class in django.utils.feedgenerator), 1381 atomic() (in module django.db.transaction), 147 attr_value() (SpatialReference method), 854 attrs (Widget attribute), 1058 auth() (in module django.contrib.auth.context_processors), 1356 auth_code() (SpatialReference method), 854 auth_name() (SpatialReference method), 854 AUTH_PASSWORD_VALIDATORS setting, 1282 AUTH_USER_MODEL setting, 1280 authenticate() (in module django.contrib.auth), 363 authenticate() (ModelBackend method), 753 authenticate() (RemoteUserBackend method), 754 AUTHENTICATION_BACKENDS setting, 1280 AuthenticationForm (class in django.contrib.auth.forms), 380 AuthenticationMiddleware (class in django.contrib.auth.middleware), 1079 auto_created (Field attribute), 1113 auto_id (BoundField attribute), 1027 auto_id (Form attribute), 1022 auto_now (DateField attribute), 1095 auto_now_add (DateField attribute), 1095 autocomplete_fields (ModelAdmin attribute), 720 autodiscover() (in module django.contrib.admin), 705

Index

autoescape template tag, 1309 AutoField (class in django.db.models), 1094 available_apps (TransactionTestCase attribute), 356 Avg (class in django.db.models), 1186 Azimuth (class in django.contrib.gis.db.models.functions), 817

B backends.base.SessionBase (class in django.contrib.sessions), 216 backends.cached_db.SessionStore (class in django.contrib.sessions), 224 backends.db.SessionStore (class in django.contrib.sessions), 224 backends.smtp.EmailBackend (class in django.core.mail), 440 bands (GDALRaster attribute), 859 base36_to_int() (in module django.utils.http), 1385 base_field (ArrayField attribute), 891 base_field (django.contrib.postgres.forms.BaseRangeField attribute), 903 base_field (RangeField attribute), 903 base_field (SimpleArrayField attribute), 904 base_field (SplitArrayField attribute), 905 base_manager_name (Options attribute), 1122 base_session.AbstractBaseSession (class in django.contrib.sessions), 224 base_session.BaseSessionManager (class in django.contrib.sessions), 224 base_url (FileSystemStorage attribute), 1008 base_widget (RangeWidget attribute), 907 BaseArchiveIndexView (class in django.views.generic.dates), 663 BaseCommand (class in django.core.management), 538 BaseDatabaseSchemaEditor (class in django.db.backends.base.schema), 1242 BaseDateDetailView (class in django.views.generic.dates), 663 BaseDateListView (class in django.views.generic.dates), 675 BaseDayArchiveView (class in django.views.generic.dates), 663 BaseFormSet (class in django.forms.formsets), 236 BaseGenericInlineFormSet (class in django.contrib.contenttypes.forms), 760 BaseGeometryWidget (class in django.contrib.gis.forms.widgets), 803 BaseMonthArchiveView (class in django.views.generic.dates), 663 BaseTodayArchiveView (class in django.views.generic.dates), 663 BaseWeekArchiveView (class in django.views.generic.dates), 663 1809

Django Documentation, Release 2.1.dev20171115023625

BaseYearArchiveView (class in django.views.generic.dates), 663 bbcontains field lookup type, 804 bboverlaps field lookup type, 804 BigAutoField (class in django.db.models), 1094 BigIntegerField (class in django.db.models), 1094 BigIntegerRangeField (class in django.contrib.postgres.fields), 900 bilateral (Transform attribute), 1191 BinaryField (class in django.db.models), 1094 BitAnd (class in django.contrib.postgres.aggregates), 888 BitOr (class in django.contrib.postgres.aggregates), 888 blank (Field attribute), 1089 block template tag, 1310 blocktrans template tag, 452 body (HttpRequest attribute), 1229 BoolAnd (class in django.contrib.postgres.aggregates), 888 BooleanField (class in django.db.models), 1094 BooleanField (class in django.forms), 1038 BoolOr (class in django.contrib.postgres.aggregates), 888 boundary (GEOSGeometry attribute), 832 boundary() (OGRGeometry method), 850 BoundField (class in django.forms), 1027 BoundingCircle (class in django.contrib.gis.db.models.functions), 817 BrinIndex (class in django.contrib.postgres.indexes), 908 BrokenLinkEmailsMiddleware (class in django.middleware.common), 1075 BtreeGinExtension (class in django.contrib.postgres.operations), 910 BtreeGistExtension (class in django.contrib.postgres.operations), 910 buffer() (GEOSGeometry method), 831 build_absolute_uri() (HttpRequest method), 1232 build_suite() (DiscoverRunner method), 359 bulk_create() (in module django.db.models.query.QuerySet), 1169 byteorder (WKBWriter attribute), 838

CACHE_MIDDLEWARE_KEY_PREFIX setting, 1248 CACHE_MIDDLEWARE_SECONDS setting, 1248 cached.Loader (class in django.template.loaders), 1359 cached_property (class in django.utils.functional), 1381 CACHES setting, 1246 CACHES-BACKEND setting, 1247 CACHES-KEY_FUNCTION setting, 1247 CACHES-KEY_PREFIX setting, 1247 CACHES-LOCATION setting, 1247 CACHES-OPTIONS setting, 1248 CACHES-TIMEOUT setting, 1248 CACHES-VERSION setting, 1248 CallbackFilter (class in django.utils.log), 496 callproc() (CursorWrapper method), 145 can_delete (BaseFormSet attribute), 243 can_delete (InlineModelAdmin attribute), 736 can_order (BaseFormSet attribute), 242 capfirst template filter, 1328 CASCADE (in module django.db.models), 1105 Case (class in django.db.models.expressions), 1210 Cast (class in django.db.models.functions), 1213 center template filter, 1328 Centroid (class in django.contrib.gis.db.models.functions), 817 centroid (GEOSGeometry attribute), 832 centroid (Polygon attribute), 851 change_form_template (ModelAdmin attribute), 723 change_list_template (ModelAdmin attribute), 723 change_message (LogEntry attribute), 746 change_view() (ModelAdmin method), 732 changed_data (Form attribute), 1017 changed_objects (models.BaseModelFormSet attribute), 260 C changefreq (Sitemap attribute), 918 changelist_view() (ModelAdmin method), 732 cache changepassword template tag, 418 django-admin command, 995 cache_control() (in module changepassword command line option django.views.decorators.cache), 201 –database DATABASE, 995 cache_key_prefix (backends.cached_db.SessionStore atCharField (class in django.db.models), 1095 tribute), 224 CharField (class in django.forms), 1038 CACHE_MIDDLEWARE_ALIAS charset (HttpResponse attribute), 1237 setting, 1248 1810

Index

Django Documentation, Release 2.1.dev20171115023625

charset (UploadedFile attribute), 1010 check django-admin command, 977 check command line option –deploy, 977 –fail-level {CRITICAL,ERROR,WARNING,INFO,DEBUG}, 977 –list-tags, 977 –tag TAGS, -t TAGS, 977 check() (BaseCommand method), 539 check_for_language() (in module django.utils.translation), 1389 check_password() (in module django.contrib.auth.hashers), 389 check_password() (models.AbstractBaseUser method), 402 check_password() (models.User method), 750 check_test (CheckboxInput attribute), 1064 CheckboxInput (class in django.forms), 1064 CheckboxSelectMultiple (class in django.forms), 1066 CheckMessage (class in django.core.checks), 631 ChoiceField (class in django.forms), 1039 choices (ChoiceField attribute), 1039 choices (Field attribute), 1089 choices (MultipleHiddenInput attribute), 1067 choices (Select attribute), 1064 chunk_size (FileUploadHandler attribute), 1012 chunks() (File method), 1006 chunks() (UploadedFile method), 1010 CICharField (class in django.contrib.postgres.fields), 895 CIEmailField (class in django.contrib.postgres.fields), 895 CIText (class in django.contrib.postgres.fields), 894 CITextExtension (class in django.contrib.postgres.operations), 910 CITextField (class in django.contrib.postgres.fields), 895 city() (GeoIP2 method), 868 classes (InlineModelAdmin attribute), 735 clean() (Field method), 1033 clean() (Form method), 1014 clean() (Model method), 1133 clean() (models.AbstractBaseUser method), 401 clean() (models.AbstractUser method), 402 clean_fields() (Model method), 1132 clean_savepoints() (in module django.db.transaction), 153 clean_username() (RemoteUserBackend method), 754 cleaned_data (Form attribute), 1018 clear() (backends.base.SessionBase method), 217 clear() (RelatedManager method), 1121 clear_cache() (ContentTypeManager method), 757 clear_expired() (backends.base.SessionBase method), 218

Index

ClearableFileInput (class in django.forms), 1067 clearsessions django-admin command, 997 Client (class in django.test), 329 client (Response attribute), 333 client (SimpleTestCase attribute), 340 client.RedirectCycleError, 1005 client_class (SimpleTestCase attribute), 341 clone() (GEOSGeometry method), 832 clone() (OGRGeometry method), 849 clone() (SpatialReference method), 854 close() (FieldFile method), 1099 close() (File method), 1006 close_rings() (OGRGeometry method), 849 closed (HttpResponse attribute), 1237 closed (LineString attribute), 834 closed (MultiLineString attribute), 835 Coalesce (class in django.db.models.functions), 1213 code (EmailValidator attribute), 1391 code (ProhibitNullCharactersValidator attribute), 1394 code (RegexValidator attribute), 1391 codename (models.Permission attribute), 752 coerce (TypedChoiceField attribute), 1039 Collect (class in django.contrib.gis.db.models), 813 collectstatic django-admin command, 931 collectstatic command line option –clear, -c, 932 –dry-run, -n, 932 –ignore PATTERN, -i PATTERN, 932 –link, -l, 932 –no-default-ignore, 932 –no-post-process, 932 –noinput, –no-input, 931 color_interp() (GDALBand method), 862 ComboField (class in django.forms), 1047 command line option –no-color, 998 –pythonpath PYTHONPATH, 997 –settings SETTINGS, 997 –traceback, 998 –verbosity {0,1,2,3}, -v {0,1,2,3}, 998 CommandError, 540 comment template tag, 1310 commit() (in module django.db.transaction), 152 CommonMiddleware (class in django.middleware.common), 1075 CommonPasswordValidator (class in django.contrib.auth.password_validation), 391 compilemessages django-admin command, 978 compilemessages command line option

1811

Django Documentation, Release 2.1.dev20171115023625

–exclude EXCLUDE, -x EXCLUDE, 978 convert_value() (Expression method), 1206 –locale LOCALE, -l LOCALE, 978 convex_hull (GEOSGeometry attribute), 832 –use-fuzzy, -f, 978 convex_hull (OGRGeometry attribute), 850 compress() (MultiValueField method), 1049 cookie_date() (in module django.utils.http), 1384 Concat (class in django.db.models.functions), 1224 cookies (Client attribute), 335 concrete (Field attribute), 1113 COOKIES (HttpRequest attribute), 1230 concrete model, 1405 coord_dim (OGRGeometry attribute), 847 condition (FilteredRelation attribute), 1189 coords (GEOSGeometry attribute), 828 condition() (in module django.views.decorators.http), 201 coords (OGRGeometry attribute), 850 conditional_escape() (in module django.utils.html), 1383 coords() (GeoIP2 method), 868 ConditionalGetMiddleware (class in CoordTransform (class in django.contrib.gis.gdal), 856 django.middleware.http), 1076 copy() (QueryDict method), 1235 configure_user() (RemoteUserBackend method), 754 Corr (class in django.contrib.postgres.aggregates), 889 confirm_login_allowed() (AuthenticationForm method), Count (class in django.db.models), 1186 380 count (Paginator attribute), 500 CONN_MAX_AGE count() (in module django.db.models.query.QuerySet), setting, 1252 1169 connect() (Signal method), 525 country() (GeoIP2 method), 868 connection (SchemaEditor attribute), 1245 country_code() (GeoIP2 method), 868 contained country_name() (GeoIP2 method), 868 field lookup type, 804 coupling contains loose, 1398 field lookup type, 1177 CovarPop (class in django.contrib.postgres.aggregates), contains() (GEOSGeometry method), 830 889 contains() (OGRGeometry method), 850 coveredby contains() (PreparedGeometry method), 836 field lookup type, 805 contains_aggregate (Expression attribute), 1205 covers contains_over_clause (Expression attribute), 1205 field lookup type, 806 contains_properly covers() (GEOSGeometry method), 830 field lookup type, 805 covers() (PreparedGeometry method), 836 contains_properly() (PreparedGeometry method), 836 create() (in module django.db.models.query.QuerySet), content (HttpResponse attribute), 1237 1166 content (Response attribute), 333 create() (RelatedManager method), 1120 content_params (HttpRequest attribute), 1229 create_model() (BaseDatabaseSchemaEditor method), content_type (django.views.generic.base.TemplateResponseMixin 1243 attribute), 664 create_model_instance() (backends.db.SessionStore content_type (HttpRequest attribute), 1229 method), 224 content_type (LogEntry attribute), 745 create_superuser() (models.CustomUserManager content_type (models.Permission attribute), 752 method), 402 content_type (UploadedFile attribute), 1010 create_superuser() (models.UserManager method), 751 content_type_extra (UploadedFile attribute), 1010 create_test_db() (in module ContentFile (class in django.core.files.base), 1007 django.db.connection.creation), 361 ContentType (class in create_unknown_user (RemoteUserBackend attribute), django.contrib.contenttypes.models), 755 754 ContentTypeManager (class in create_user() (models.CustomUserManager method), 402 django.contrib.contenttypes.models), 757 create_user() (models.UserManager method), 751 Context (class in django.template), 1349 createcachetable context (Response attribute), 333 django-admin command, 978 context_data (SimpleTemplateResponse attribute), 1362 createcachetable command line option context_object_name (django.views.generic.detail.SingleObjectMixin –database DATABASE, 978 attribute), 665 –dry-run, 978 context_object_name (django.views.generic.list.MultipleObjectMixin CreateExtension (class in attribute), 668 django.contrib.postgres.operations), 910 ContextPopException, 1353

1812

Index

Django Documentation, Release 2.1.dev20171115023625

CreateModel (class in django.db.migrations.operations), 1081 createsuperuser django-admin command, 996 createsuperuser command line option –database DATABASE, 996 –email EMAIL, 996 –username USERNAME, 996 CreateView (built-in class), 680 Critical (class in django.core.checks), 632 crosses field lookup type, 806 crosses() (GEOSGeometry method), 830 crosses() (OGRGeometry method), 849 crosses() (PreparedGeometry method), 836 CryptoExtension (class in django.contrib.postgres.operations), 910 CSRF_COOKIE_AGE setting, 1249 CSRF_COOKIE_DOMAIN setting, 1249 CSRF_COOKIE_HTTPONLY setting, 1249 CSRF_COOKIE_NAME setting, 1249 CSRF_COOKIE_PATH setting, 1250 CSRF_COOKIE_SECURE setting, 1250 csrf_exempt() (in module django.views.decorators.csrf), 961 CSRF_FAILURE_VIEW setting, 1250 CSRF_HEADER_NAME setting, 1250 csrf_protect() (in module django.views.decorators.csrf), 958 csrf_token template tag, 1310 CSRF_TRUSTED_ORIGINS setting, 1251 CSRF_USE_SESSIONS setting, 1250 CsrfViewMiddleware (class in django.middleware.csrf), 1080 css_classes() (BoundField method), 1029 ct_field (GenericInlineModelAdmin attribute), 761 ct_fk_field (GenericInlineModelAdmin attribute), 761 CumeDist (class in django.db.models.functions), 1226 current_app (HttpRequest attribute), 1231 CurrentSiteMiddleware (class in django.contrib.sites.middleware), 1079 cut template filter, 1328

Index

cycle template tag, 1310 cycle_key() (backends.base.SessionBase method), 218

D D (class in django.contrib.gis.measure), 824 data (BoundField attribute), 1027 data() (GDALBand method), 862 DATA_UPLOAD_MAX_MEMORY_SIZE setting, 1257 DATA_UPLOAD_MAX_NUMBER_FIELDS setting, 1258 DATABASE-ATOMIC_REQUESTS setting, 1251 DATABASE-AUTOCOMMIT setting, 1252 DATABASE-DISABLE_SERVER_SIDE_CURSORS setting, 1253 DATABASE-ENGINE setting, 1252 DATABASE-TEST setting, 1254 DATABASE-TIME_ZONE setting, 1253 DATABASE_ROUTERS setting, 1258 DatabaseError, 1004 DATABASES setting, 1251 DataError, 1004 DATAFILE setting, 1256 DATAFILE_EXTSIZE setting, 1257 DATAFILE_MAXSIZE setting, 1256 DATAFILE_SIZE setting, 1257 DATAFILE_TMP setting, 1256 DATAFILE_TMP_EXTSIZE setting, 1257 DATAFILE_TMP_MAXSIZE setting, 1257 DATAFILE_TMP_SIZE setting, 1257 DataSource (class in django.contrib.gis.gdal), 841 datatype() (GDALBand method), 862 date field lookup type, 1180 template filter, 1329 date_attrs (SplitDateTimeWidget attribute), 1068 date_field (DateMixin attribute), 675 DATE_FORMAT 1813

Django Documentation, Release 2.1.dev20171115023625

setting, 1258 date_format (SplitDateTimeWidget attribute), 1068 date_hierarchy (ModelAdmin attribute), 706 DATE_INPUT_FORMATS setting, 1258 date_joined (models.User attribute), 749 date_list_period (BaseDateListView attribute), 676 DateDetailView (built-in class), 690 DateDetailView (class in django.views.generic.dates), 662 DateField (class in django.db.models), 1095 DateField (class in django.forms), 1040 DateInput (class in django.forms), 1063 DateMixin (class in django.views.generic.dates), 675 DateRangeField (class in django.contrib.postgres.fields), 900 DateRangeField (class in django.contrib.postgres.forms), 907 dates() (in module django.db.models.query.QuerySet), 1151 DATETIME_FORMAT setting, 1259 DATETIME_INPUT_FORMATS setting, 1259 DateTimeField (class in django.db.models), 1096 DateTimeField (class in django.forms), 1040 DateTimeInput (class in django.forms), 1063 DateTimeRangeField (class in django.contrib.postgres.fields), 900 DateTimeRangeField (class in django.contrib.postgres.forms), 906 datetimes() (in module django.db.models.query.QuerySet), 1151 day field lookup type, 1181 day (DayMixin attribute), 674 day_format (DayMixin attribute), 674 DayArchiveView (built-in class), 687 DayArchiveView (class in django.views.generic.dates), 659 DayMixin (class in django.views.generic.dates), 674 db (QuerySet attribute), 1143 db_column (Field attribute), 1090 db_constraint (ForeignKey attribute), 1107 db_constraint (ManyToManyField attribute), 1109 db_for_read(), 157 db_for_write(), 157 db_index (Field attribute), 1091 db_table (ManyToManyField attribute), 1109 db_table (Options attribute), 1122 db_tablespace (Field attribute), 1091 db_tablespace (Index attribute), 1115 db_tablespace (Options attribute), 1123 db_type() (Field method), 1111

1814

dbshell django-admin command, 978 dbshell command line option –database DATABASE, 979 deactivate() (in module django.utils.timezone), 1387 deactivate() (in module django.utils.translation), 1389 deactivate_all() (in module django.utils.translation), 1389 DEBUG setting, 1259 debug template tag, 1312 Debug (class in django.core.checks), 632 debug() (in module django.template.context_processors), 1356 DEBUG_PROPAGATE_EXCEPTIONS setting, 1260 decimal_places (DecimalField attribute), 1041, 1096 DECIMAL_SEPARATOR setting, 1260 DecimalField (class in django.db.models), 1096 DecimalField (class in django.forms), 1041 DecimalValidator (class in django.core.validators), 1393 decompress() (MultiWidget method), 1060 decompress() (RangeWidget method), 907 deconstruct() (Field method), 1113 decorator_from_middleware() (in module django.utils.decorators), 1378 decorator_from_middleware_with_args() (in module django.utils.decorators), 1378 default template filter, 1330 default (Field attribute), 1091 DEFAULT_CHARSET setting, 1260 DEFAULT_CONTENT_TYPE setting, 1260 DEFAULT_EXCEPTION_REPORTER_FILTER setting, 1261 DEFAULT_FILE_STORAGE setting, 1261 DEFAULT_FROM_EMAIL setting, 1261 default_if_none template filter, 1330 DEFAULT_INDEX_TABLESPACE setting, 1261 default_lat (GeoModelAdmin attribute), 874 default_lat (OSMWidget attribute), 803 default_lon (GeoModelAdmin attribute), 874 default_lon (OSMWidget attribute), 803 default_manager_name (Options attribute), 1123 default_permissions (Options attribute), 1126 default_related_name (Options attribute), 1123 default_renderer (Form attribute), 1025

Index

Django Documentation, Release 2.1.dev20171115023625

DEFAULT_TABLESPACE difference() (in module setting, 1261 django.db.models.query.QuerySet), 1153 default_zoom (GeoModelAdmin attribute), 874 difference() (OGRGeometry method), 850 default_zoom (OSMWidget attribute), 803 diffsettings defaults.bad_request() (in module django.views), 1396 django-admin command, 979 defaults.page_not_found() (in module django.views), diffsettings command line option 1395 –all, 979 defaults.permission_denied() (in module django.views), –default MODULE, 979 1396 –output {hash,unified}, 979 defaults.server_error() (in module django.views), 1395 dim (GeometryField attribute), 793 DefaultStorage (class in django.core.files.storage), 1007 dimension (OGRGeometry attribute), 847 defer() (in module django.db.models.query.QuerySet), dims (GEOSGeometry attribute), 828 1162 directory_permissions_mode (FileSystemStorage atdelete() (Client method), 331 tribute), 1008 delete() (FieldFile method), 1099 disable_action() (AdminSite method), 700 delete() (File method), 1007 disabled (Field attribute), 1038 delete() (in module django.db.models.query.QuerySet), DISALLOWED_USER_AGENTS 1175 setting, 1261 delete() (Model method), 1137 disconnect() (Signal method), 528 delete() (Storage method), 1008 DiscoverRunner (class in django.test.runner), 358 delete_confirmation_template (ModelAdmin attribute), disjoint 723 field lookup type, 806 delete_cookie() (HttpResponse method), 1239 disjoint() (GEOSGeometry method), 830 delete_model() (BaseDatabaseSchemaEditor method), disjoint() (OGRGeometry method), 849 1243 disjoint() (PreparedGeometry method), 836 delete_model() (ModelAdmin method), 724 dispatch() (django.views.generic.base.View method), 644 delete_selected_confirmation_template (ModelAdmin at- display_raw (BaseGeometryWidget attribute), 802 tribute), 723 Distance (class in django.contrib.gis.db.models.functions), delete_test_cookie() (backends.base.SessionBase 817 method), 217 Distance (class in django.contrib.gis.measure), 823 delete_view() (ModelAdmin method), 732 distance() (GEOSGeometry method), 832 deleted_objects (models.BaseModelFormSet attribute), distance_gt 260 field lookup type, 811 DeleteModel (class in django.db.migrations.operations), distance_gte 1082 field lookup type, 812 DeleteView (built-in class), 682 distance_lt delimiter (SimpleArrayField attribute), 904 field lookup type, 812 delimiter (StringAgg attribute), 888 distance_lte DenseRank (class in django.db.models.functions), 1226 field lookup type, 812 desc() (Expression method), 1206 distinct (ArrayAgg attribute), 888 description (Field attribute), 1111 distinct (Count attribute), 1186 description (GDALBand attribute), 861 distinct (StringAgg attribute), 888 destroy_test_db() (in module distinct() (in module django.db.models.query.QuerySet), django.db.connection.creation), 361 1147 DetailView (built-in class), 678 divisibleby dict() (QueryDict method), 1235 template filter, 1332 dictsort django (OGRGeomType attribute), 852 template filter, 1331 django-admin command dictsortreversed changepassword, 995 template filter, 1332 check, 977 Difference (class in django.contrib.gis.db.models.functions), clearsessions, 997 817 collectstatic, 931 difference() (GEOSGeometry method), 831 compilemessages, 978 createcachetable, 978

Index

1815

Django Documentation, Release 2.1.dev20171115023625

createsuperuser, 996 dbshell, 978 diffsettings, 979 dumpdata, 979 findstatic, 932 flush, 980 help, 976 inspectdb, 980 loaddata, 981 makemessages, 984 makemigrations, 985 migrate, 986 ogrinspect, 873 ping_google, 923 remove_stale_contenttypes, 996 runserver, 933, 987 sendtestemail, 989 shell, 989 showmigrations, 990 sqlflush, 990 sqlmigrate, 990 sqlsequencereset, 990 squashmigrations, 991 startapp, 991 startproject, 992 test, 993 testserver, 994 version, 977 django.apps (module), 625 django.conf.settings.configure() (built-in function), 522 django.conf.urls (module), 1375 django.conf.urls.i18n (module), 462 django.contrib.admin (module), 694 django.contrib.admindocs (module), 701 django.contrib.auth (module), 408 django.contrib.auth.backends (module), 753 django.contrib.auth.forms (module), 380 django.contrib.auth.hashers (module), 389 django.contrib.auth.middleware (module), 1079 django.contrib.auth.password_validation (module), 389 django.contrib.auth.signals (module), 752 django.contrib.auth.views (module), 373 django.contrib.contenttypes (module), 755 django.contrib.contenttypes.admin (module), 760 django.contrib.contenttypes.fields (module), 757 django.contrib.contenttypes.forms (module), 760 django.contrib.flatpages (module), 761 django.contrib.gis (module), 766 django.contrib.gis.admin (module), 874 django.contrib.gis.db.backends (module), 794 django.contrib.gis.db.models (module), 790, 794 django.contrib.gis.db.models.functions (module), 800, 815 django.contrib.gis.feeds (module), 875

1816

django.contrib.gis.forms (module), 801 django.contrib.gis.forms.widgets (module), 802 django.contrib.gis.gdal (module), 840 django.contrib.gis.geoip2 (module), 866 django.contrib.gis.geos (module), 824 django.contrib.gis.measure (module), 822 django.contrib.gis.serializers.geojson (module), 872 django.contrib.gis.utils (module), 869 django.contrib.gis.utils.layermapping (module), 869 django.contrib.gis.utils.ogrinspect (module), 872 django.contrib.humanize (module), 879 django.contrib.messages (module), 881 django.contrib.messages.middleware (module), 1077 django.contrib.postgres (module), 887 django.contrib.postgres.aggregates (module), 887 django.contrib.postgres.forms.BaseRangeField (class in django.contrib.postgres.fields), 903 django.contrib.postgres.indexes (module), 908 django.contrib.postgres.validators (module), 914 django.contrib.redirects (module), 915 django.contrib.sessions (module), 214 django.contrib.sessions.middleware (module), 1079 django.contrib.sitemaps (module), 916 django.contrib.sites (module), 924 django.contrib.sites.middleware (module), 1079 django.contrib.staticfiles (module), 930 django.contrib.syndication (module), 937 django.core.cache.cache (built-in variable), 420 django.core.cache.caches (built-in variable), 420 django.core.cache.utils.make_template_fragment_key() (built-in function), 419 django.core.checks (module), 528 django.core.exceptions (module), 1001 django.core.files (module), 1005 django.core.files.storage (module), 1007 django.core.files.uploadedfile (module), 1010 django.core.files.uploadhandler (module), 1011 django.core.mail (module), 433 django.core.mail.outbox (in module django.core.mail), 350 django.core.management (module), 535 django.core.management.call_command() (built-in function), 1000 django.core.paginator (module), 498 django.core.serializers.get_serializer() (built-in function), 512 django.core.serializers.json.DjangoJSONEncoder (builtin class), 516 django.core.signals (module), 1297 django.core.signals.got_request_exception (built-in variable), 1298 django.core.signals.request_finished (built-in variable), 1298

Index

Django Documentation, Release 2.1.dev20171115023625

django.core.signals.request_started (built-in variable), 1298 django.core.signing (module), 431 django.core.validators (module), 1390 django.db (module), 84 django.db.backends (module), 1299 django.db.backends.base.schema (module), 1242 django.db.backends.signals.connection_created (built-in variable), 1299 django.db.migrations (module), 309 django.db.migrations.operations (module), 1081 django.db.models (module), 84 django.db.models.fields (module), 1088 django.db.models.fields.related (module), 1103 django.db.models.functions (module), 1213 django.db.models.indexes (module), 1114 django.db.models.lookups (module), 1190 django.db.models.options (module), 1115 django.db.models.signals (module), 1292 django.db.models.signals.class_prepared (built-in variable), 1296 django.db.models.signals.m2m_changed (built-in variable), 1294 django.db.models.signals.post_delete (built-in variable), 1294 django.db.models.signals.post_init (built-in variable), 1293 django.db.models.signals.post_migrate (built-in variable), 1296 django.db.models.signals.post_save (built-in variable), 1293 django.db.models.signals.pre_delete (built-in variable), 1294 django.db.models.signals.pre_migrate (built-in variable), 1296 django.db.models.signals.pre_save (built-in variable), 1293 django.db.transaction (module), 146 django.dispatch (module), 524 django.forms (module), 1013 django.forms.fields (module), 1033 django.forms.formsets (module), 236, 1053 django.forms.models (module), 247, 1052 django.forms.renderers (module), 1053 django.forms.widgets (module), 1055 django.http (module), 1228 django.http.Http404 (built-in class), 199 django.middleware (module), 1075 django.middleware.cache (module), 1075 django.middleware.clickjacking (module), 692, 1080 django.middleware.common (module), 1075 django.middleware.csrf (module), 956, 1080 django.middleware.exception (module), 1076 django.middleware.gzip (module), 1076

Index

django.middleware.http (module), 1076 django.middleware.locale (module), 1077 django.middleware.security (module), 1077 django.shortcuts (module), 205 django.template (module), 272 django.template.backends (module), 275 django.template.backends.django (module), 275 django.template.backends.jinja2 (module), 276 django.template.loader (module), 273 django.template.response (module), 1361 django.test (module), 322 django.test.signals (module), 1298 django.test.signals.setting_changed (built-in variable), 1298 django.test.signals.template_rendered (built-in variable), 1299 django.test.utils (module), 360 django.test.utils.isolate_apps() (built-in function), 1743 django.urls (module), 1370 django.urls.conf (module), 1373 django.utils (module), 1376 django.utils.cache (module), 1376 django.utils.dateparse (module), 1377 django.utils.decorators (module), 1378 django.utils.deprecation.MiddlewareMixin (built-in class), 213 django.utils.encoding (module), 1378 django.utils.feedgenerator (module), 1379 django.utils.functional (module), 1381 django.utils.html (module), 1383 django.utils.http (module), 1384 django.utils.log (module), 487 django.utils.module_loading (module), 1385 django.utils.safestring (module), 1385 django.utils.text (module), 1386 django.utils.timezone (module), 1386 django.utils.translation (module), 443, 1388 django.views (module), 1394 django.views.decorators.cache (module), 201 django.views.decorators.cache.cache_page() (built-in function), 417 django.views.decorators.csrf (module), 958 django.views.decorators.gzip (module), 201 django.views.decorators.http (module), 200 django.views.decorators.vary (module), 201 django.views.generic.base.ContextMixin (built-in class), 663 django.views.generic.base.RedirectView (built-in class), 645 django.views.generic.base.TemplateResponseMixin (built-in class), 664 django.views.generic.base.TemplateView (built-in class), 644 django.views.generic.base.View (built-in class), 643

1817

Django Documentation, Release 2.1.dev20171115023625

django.views.generic.dates (module), 653 dumps() (in module django.core.signing), 433 django.views.generic.detail.DetailView (built-in class), DurationField (class in django.db.models), 1096 647 DurationField (class in django.forms), 1042 django.views.generic.detail.SingleObjectMixin (built-in dwithin class), 665 field lookup type, 813 django.views.generic.detail.SingleObjectTemplateResponseMixin E (built-in class), 666 django.views.generic.edit.CreateView (built-in class), each_context() (AdminSite method), 742 651 earliest() (in module django.db.models.query.QuerySet), django.views.generic.edit.DeleteView (built-in class), 1172 652 editable (Field attribute), 1091 django.views.generic.edit.DeletionMixin (built-in class), ellipsoid (SpatialReference attribute), 855 672 email (models.User attribute), 748 django.views.generic.edit.FormMixin (built-in class), 670 EMAIL_BACKEND django.views.generic.edit.FormView (built-in class), 650 setting, 1261 django.views.generic.edit.ModelFormMixin (built-in EMAIL_FIELD (models.CustomUser attribute), 400 class), 671 EMAIL_FILE_PATH django.views.generic.edit.ProcessFormView (built-in setting, 1262 class), 671 EMAIL_HOST django.views.generic.edit.UpdateView (built-in class), setting, 1262 652 EMAIL_HOST_PASSWORD django.views.generic.list.BaseListView (built-in class), setting, 1262 649 EMAIL_HOST_USER django.views.generic.list.ListView (built-in class), 648 setting, 1262 django.views.generic.list.MultipleObjectMixin (built-in EMAIL_PORT class), 667 setting, 1262 django.views.generic.list.MultipleObjectTemplateResponseMixin EMAIL_SSL_CERTFILE (built-in class), 669 setting, 1263 django.views.i18n (module), 457 EMAIL_SSL_KEYFILE DJANGO_SETTINGS_MODULE, 24, 524, 581, 927, setting, 1263 976, 1552 EMAIL_SUBJECT_PREFIX DjangoTemplates (class in django.forms.renderers), 1054 setting, 1262 DjangoTemplates (class in EMAIL_TIMEOUT django.template.backends.django), 275 setting, 1263 DO_NOTHING (in module django.db.models), 1106 EMAIL_USE_LOCALTIME domain (JavaScriptCatalog attribute), 457 setting, 1262 domain (models.Site attribute), 924 EMAIL_USE_SSL Don’t repeat yourself, 1399 setting, 1263 Driver (class in django.contrib.gis.gdal), 846 EMAIL_USE_TLS driver (GDALRaster attribute), 857 setting, 1263 driver_count (Driver attribute), 846 email_user() (models.User method), 750 DRY, 1399 EmailField (class in django.db.models), 1097 dumpdata EmailField (class in django.forms), 1042 django-admin command, 979 EmailInput (class in django.forms), 1062 dumpdata command line option EmailMessage (class in django.core.mail), 437 –all, -a, 979 EmailValidator (class in django.core.validators), 1391 –database DATABASE, 980 empty (GEOSGeometry attribute), 828 –exclude EXCLUDE, -e EXCLUDE, 979 empty_label (ModelChoiceField attribute), 1050 –format FORMAT, 979 empty_label (SelectDateWidget attribute), 1068 –indent INDENT, 979 empty_value (CharField attribute), 1039 –natural-foreign, 980 empty_value (TypedChoiceField attribute), 1040 –natural-primary, 980 empty_value_display (AdminSite attribute), 742 –output OUTPUT, -o OUTPUT, 980 empty_value_display (ModelAdmin attribute), 706 –pks PRIMARY_KEYS, 980 EmptyPage, 501 1818

Index

Django Documentation, Release 2.1.dev20171115023625

EmptyResultSet, 1002 Enclosure (class in django.utils.feedgenerator), 1380 encode() (base_session.BaseSessionManager method), 224 encoder (JSONField attribute), 898 encoding (HttpRequest attribute), 1229 end_index() (Page method), 502 endswith field lookup type, 1179 Engine (class in django.template), 1347 engines (in module django.template.loader), 275 ensure_csrf_cookie() (in module django.views.decorators.csrf), 961 Envelope (class in django.contrib.gis.db.models.functions), 818 Envelope (class in django.contrib.gis.gdal), 852 envelope (GEOSGeometry attribute), 832 envelope (OGRGeometry attribute), 848 environment variable DJANGO_SETTINGS_MODULE, 24, 520, 524, 581, 927, 976, 1552 PYTHONPATH, 1553 PYTHONSTARTUP, 989 PYTHONWARNINGS, 586 equals field lookup type, 806 equals() (GEOSGeometry method), 830 equals() (OGRGeometry method), 849 equals_exact() (GEOSGeometry method), 830 Error, 1004 Error (class in django.core.checks), 632 error_css_class (Form attribute), 1022 error_messages (Field attribute), 1037, 1092 errors (BoundField attribute), 1027 errors (Form attribute), 1014 escape template filter, 1332 escape() (in module django.utils.html), 1383 escape_uri_path() (in module django.utils.encoding), 1379 escapejs template filter, 1333 etag() (in module django.views.decorators.http), 201 ewkb (GEOSGeometry attribute), 830 ewkt (GEOSGeometry attribute), 829 ewkt (OGRGeometry attribute), 849 exact field lookup type, 806, 1176 ExceptionMiddleware (class in django.middleware.exception), 1076 exclude (ModelAdmin attribute), 707 exclude() (in module django.db.models.query.QuerySet), 1143 execute() (BaseCommand method), 539

Index

execute() (BaseDatabaseSchemaEditor method), 1243 execute_wrapper() (in module django.db.backends.base.DatabaseWrapper), 173 Exists (class in django.db.models), 1200 exists() (in module django.db.models.query.QuerySet), 1173 exists() (Storage method), 1008 expand_to_include() (Envelope method), 853 expire_date (base_session.AbstractBaseSession attribute), 224 Expression (class in django.db.models), 1205 ExpressionWrapper (class in django.db.models), 1199 extends template tag, 1312 Extent (class in django.contrib.gis.db.models), 813 extent (GDALRaster attribute), 859 extent (GEOSGeometry attribute), 832 extent (Layer attribute), 843 extent (OGRGeometry attribute), 848 Extent3D (class in django.contrib.gis.db.models), 814 exterior_ring (Polygon attribute), 851 extra (InlineModelAdmin attribute), 735 extra() (in module django.db.models.query.QuerySet), 1159 extra_context (django.views.generic.base.ContextMixin attribute), 663 extra_js (GeoModelAdmin attribute), 874 Extract (class in django.db.models.functions), 1215 ExtractDay (class in django.db.models.functions), 1217 ExtractHour (class in django.db.models.functions), 1218 ExtractMinute (class in django.db.models.functions), 1218 ExtractMonth (class in django.db.models.functions), 1217 ExtractQuarter (class in django.db.models.functions), 1217 ExtractSecond (class in django.db.models.functions), 1218 ExtractWeek (class in django.db.models.functions), 1217 ExtractWeekDay (class in django.db.models.functions), 1217 ExtractYear (class in django.db.models.functions), 1217

F F (class in django.db.models), 1194 Feature (class in django.contrib.gis.gdal), 844 Feature release, 1773 Feed (class in django.contrib.gis.feeds), 875 FetchFromCacheMiddleware (class django.middleware.cache), 1075 fid (Feature attribute), 844 field, 1405 field (BoundField attribute), 1028

in

1819

Django Documentation, Release 2.1.dev20171115023625

Field (class in django.contrib.gis.gdal), 845 Field (class in django.db.models), 1111 Field (class in django.forms), 1033 field lookup type arrayfield.contained_by, 893 arrayfield.contains, 892 arrayfield.index, 893 arrayfield.len, 893 arrayfield.overlap, 893 arrayfield.slice, 894 bbcontains, 804 bboverlaps, 804 contained, 804 contains, 1177 contains_properly, 805 coveredby, 805 covers, 806 crosses, 806 date, 1180 day, 1181 disjoint, 806 distance_gt, 811 distance_gte, 812 distance_lt, 812 distance_lte, 812 dwithin, 813 endswith, 1179 equals, 806 exact, 806, 1176 gis-contains, 805 gt, 1178 gte, 1178 hour, 1183 hstorefield.contained_by, 896 hstorefield.contains, 896 hstorefield.has_any_keys, 897 hstorefield.has_key, 896 hstorefield.has_keys, 897 hstorefield.key, 895 hstorefield.keys, 897 hstorefield.values, 897 icontains, 1177 iendswith, 1180 iexact, 1176 in, 1177 intersects, 807 iregex, 1185 isnull, 1184 istartswith, 1179 isvalid, 807 jsonfield.contained_by, 899 jsonfield.contains, 899 jsonfield.has_any_keys, 899 jsonfield.has_key, 899

1820

jsonfield.has_keys, 899 jsonfield.key, 898 left, 809 lt, 1179 lte, 1179 minute, 1183 month, 1181 overlaps, 807 overlaps_above, 810 overlaps_below, 810 overlaps_left, 809 overlaps_right, 810 quarter, 1182 range, 1180 rangefield.adjacent_to, 902 rangefield.contained_by, 901 rangefield.contains, 901 rangefield.endswith, 903 rangefield.fully_gt, 902 rangefield.fully_lt, 901 rangefield.isempty, 903 rangefield.not_gt, 902 rangefield.not_lt, 902 rangefield.overlap, 901 rangefield.startswith, 902 regex, 1184 relate, 807 right, 809 same_as, 806 search, 911 second, 1184 startswith, 1179 strictly_above, 811 strictly_below, 811 time, 1183 touches, 808 trigram_similar, 908 unaccent, 909 week, 1182 week_day, 1182 within, 809 year, 1181 field_order (Form attribute), 1025 field_precisions (Layer attribute), 842 field_widths (Layer attribute), 842 FieldDoesNotExist, 1002 FieldError, 1003 FieldFile (class in django.db.models.fields.files), 1098 fields (ComboField attribute), 1047 fields (django.views.generic.edit.ModelFormMixin attribute), 671 fields (Feature attribute), 844 fields (Form attribute), 1017 fields (Index attribute), 1115

Index

Django Documentation, Release 2.1.dev20171115023625

fields (Layer attribute), 842 fields (ModelAdmin attribute), 707 fields (MultiValueField attribute), 1048 fieldsets (ModelAdmin attribute), 708 File (class in django.core.files), 1006 file (File attribute), 1006 FILE_CHARSET setting, 1263 file_complete() (FileUploadHandler method), 1012 file_hash() (storage.ManifestStaticFilesStorage method), 935 file_permissions_mode (FileSystemStorage attribute), 1008 FILE_UPLOAD_DIRECTORY_PERMISSIONS setting, 1264 FILE_UPLOAD_HANDLERS setting, 1263 FILE_UPLOAD_MAX_MEMORY_SIZE setting, 1264 FILE_UPLOAD_PERMISSIONS setting, 1264 FILE_UPLOAD_TEMP_DIR setting, 1264 FileExtensionValidator (class in django.core.validators), 1394 FileField (class in django.db.models), 1097 FileField (class in django.forms), 1042 FileInput (class in django.forms), 1067 filepath_to_uri() (in module django.utils.encoding), 1379 FilePathField (class in django.db.models), 1100 FilePathField (class in django.forms), 1043 FileResponse (class in django.http), 1242 FILES (HttpRequest attribute), 1230 filesizeformat template filter, 1333 filesystem.Loader (class in django.template.loaders), 1358 FileSystemStorage (class in django.core.files.storage), 1008 FileUploadHandler (class in django.core.files.uploadhandler), 1011 filter template tag, 1312 filter() (django.template.Library method), 557 filter() (in module django.db.models.query.QuerySet), 1143 filter_horizontal (ModelAdmin attribute), 710 filter_vertical (ModelAdmin attribute), 710 filterable (Expression attribute), 1205 filterable (Window attribute), 1202 FilteredRelation (class in django.db.models), 1189 findstatic django-admin command, 932 findstatic –first

Index

findstatic command line option, 932 findstatic command line option findstatic –first, 932 first template filter, 1333 first() (in module django.db.models.query.QuerySet), 1172 FIRST_DAY_OF_WEEK setting, 1265 first_name (models.User attribute), 748 firstof template tag, 1313 FirstValue (class in django.db.models.functions), 1227 FixedOffset (class in django.utils.timezone), 1386 FIXTURE_DIRS setting, 1265 fixtures (TransactionTestCase attribute), 341 fk_name (InlineModelAdmin attribute), 735 flags (RegexValidator attribute), 1391 FlatPage (class in django.contrib.flatpages.models), 764 FlatpageFallbackMiddleware (class in django.contrib.flatpages.middleware), 762 FlatPageSitemap (class in django.contrib.flatpages.sitemaps), 765 flatten() (Context method), 1354 FloatField (class in django.db.models), 1100 FloatField (class in django.forms), 1043 floatformat template filter, 1333 FloatRangeField (class in django.contrib.postgres.fields), 900 FloatRangeField (class in django.contrib.postgres.forms), 906 flush django-admin command, 980 flush command line option –database DATABASE, 980 –noinput, –no-input, 980 flush() (backends.base.SessionBase method), 217 flush() (HttpResponse method), 1239 for template tag, 1313 for_concrete_model (GenericForeignKey attribute), 758 force_bytes() (in module django.utils.encoding), 1378 force_escape template filter, 1334 force_login() (Client method), 332 FORCE_SCRIPT_NAME setting, 1265 force_str() (in module django.utils.encoding), 1379 force_text() (in module django.utils.encoding), 1378 ForceRHR (class in django.contrib.gis.db.models.functions), 818 ForeignKey (class in django.db.models), 1104

1821

Django Documentation, Release 2.1.dev20171115023625

form (BoundField attribute), 1028 fromstr() (in module django.contrib.gis.geos), 837 Form (class in django.forms), 1013 full_clean() (Model method), 1132 form (InlineModelAdmin attribute), 735 Func (class in django.db.models), 1196 form (ModelAdmin attribute), 710 func (ResolverMatch attribute), 1372 form_class (django.views.generic.edit.FormMixin at- function (Aggregate attribute), 1198 tribute), 670 function (Func attribute), 1196 form_field (RangeField attribute), 903 form_invalid() (django.views.generic.edit.FormMixin G method), 670 GDAL_LIBRARY_PATH form_invalid() (django.views.generic.edit.ModelFormMixin setting, 866 method), 671 GDALBand (class in django.contrib.gis.gdal), 861 FORM_RENDERER GDALException, 866 setting, 1265 GDALRaster (class in django.contrib.gis.gdal), 856 form_valid() (django.views.generic.edit.FormMixin generate_filename() (Storage method), 1009 method), 670 generic view, 1405 form_valid() (django.views.generic.edit.ModelFormMixin generic_inlineformset_factory() (in module method), 671 django.contrib.contenttypes.forms), 760 format (DateInput attribute), 1063 GenericForeignKey (class in format (DateTimeInput attribute), 1063 django.contrib.contenttypes.fields), 758 format (TimeInput attribute), 1063 GenericInlineModelAdmin (class in format file, 487 django.contrib.contenttypes.admin), 761 format_html() (in module django.utils.html), 1383 GenericIPAddressField (class in django.db.models), 1101 format_html_join() (in module django.utils.html), 1384 GenericIPAddressField (class in django.forms), 1044 format_lazy() (in module django.utils.text), 1386 GenericRelation (class in FORMAT_MODULE_PATH django.contrib.contenttypes.fields), 759 setting, 1265 GenericSitemap (class in django.contrib.sitemaps), 919 format_value() (Widget method), 1058 GenericStackedInline (class in formfield() (Field method), 1113 django.contrib.contenttypes.admin), 761 formfield_for_choice_field() (ModelAdmin method), 729 GenericTabularInline (class in formfield_for_foreignkey() (ModelAdmin method), 728 django.contrib.contenttypes.admin), 761 formfield_for_manytomany() (ModelAdmin method), GeoAtom1Feed (class in django.contrib.gis.feeds), 876 729 geographic (SpatialReference attribute), 855 formfield_overrides (ModelAdmin attribute), 711 geography (GeometryField attribute), 793 formset (InlineModelAdmin attribute), 735 GeoHash (class in django.contrib.gis.db.models.functions), formset_factory() (in module django.forms.formsets), 818 1053 GeoIP2 (class in django.contrib.gis.geoip2), 867 FormView (built-in class), 679 GeoIP2Exception, 869 frame_type (RowRange attribute), 1204 GEOIP_CITY frame_type (ValueRange attribute), 1203 setting, 868 from_bbox() (django.contrib.gis.gdal.OGRGeometry GEOIP_COUNTRY class method), 847 setting, 868 from_bbox() (django.contrib.gis.geos.Polygon class GEOIP_PATH method), 834 setting, 868 from_db() (django.db.models.Model class method), 1130 geojson (GEOSGeometry attribute), 830 from_db_value() (Field method), 1112 geom (Feature attribute), 844 from_esri() (SpatialReference method), 854 geom_count (OGRGeometry attribute), 847 from_gml() (django.contrib.gis.gdal.OGRGeometry class geom_name (OGRGeometry attribute), 847 method), 846 geom_type (BaseGeometryWidget attribute), 802 from_gml() (django.contrib.gis.geos.GEOSGeometry geom_type (Feature attribute), 844 class method), 828 geom_type (Field attribute), 801 from_queryset() (in module django.db.models), 138 geom_type (GEOSGeometry attribute), 828 from_string() (Engine method), 1348 geom_type (Layer attribute), 842 fromfile() (in module django.contrib.gis.geos), 836 geom_type (OGRGeometry attribute), 847 fromkeys() (django.http.QueryDict class method), 1234 geom_typeid (GEOSGeometry attribute), 828 1822

Index

Django Documentation, Release 2.1.dev20171115023625

geometry() (Feed method), 875 get_by_natural_key() (models.BaseUserManager GeometryCollection (class in django.contrib.gis.gdal), method), 403 851 get_cache_key() (in module django.utils.cache), 1377 GeometryCollection (class in django.contrib.gis.geos), get_change_message() (LogEntry method), 746 835 get_changeform_initial_data() (ModelAdmin method), GeometryCollectionField (class in 731 django.contrib.gis.db.models), 792 get_changelist() (ModelAdmin method), 729 GeometryCollectionField (class in get_changelist_form() (ModelAdmin method), 729 django.contrib.gis.forms), 802 get_changelist_formset() (ModelAdmin method), 730 GeometryField (class in django.contrib.gis.db.models), get_connection() (in module django.core.mail), 440 791 get_contents() (Loader method), 1361 GeometryField (class in django.contrib.gis.forms), 801 get_context() (MultiWidget method), 1060 GeoModelAdmin (class in django.contrib.gis.admin), 874 get_context() (Widget method), 1058 GeoRSSFeed (class in django.contrib.gis.feeds), 876 get_context_data() (django.views.generic.base.ContextMixin geos (OGRGeometry attribute), 848 method), 663 geos() (GeoIP2 method), 868 get_context_data() (django.views.generic.detail.SingleObjectMixin GEOS_LIBRARY_PATH method), 666 setting, 840 get_context_data() (django.views.generic.edit.FormMixin GEOSException, 840 method), 670 GEOSGeometry (class in django.contrib.gis.geos), 827 get_context_data() (django.views.generic.list.MultipleObjectMixin geotransform (GDALRaster attribute), 858 method), 669 get (Feature attribute), 844 get_context_data() (Feed method), 939 GET (HttpRequest attribute), 1229 get_context_object_name() get() (backends.base.SessionBase method), 216 (django.views.generic.detail.SingleObjectMixin get() (Client method), 329 method), 666 get() (Context method), 1352 get_context_object_name() get() (django.views.generic.edit.ProcessFormView (django.views.generic.list.MultipleObjectMixin method), 672 method), 669 get() (django.views.generic.list.BaseListView method), get_created_time() (FileSystemStorage method), 1008 649 get_created_time() (Storage method), 1009 get() (in module django.db.models.query.QuerySet), 1166 get_current_language get() (QueryDict method), 1234 template tag, 456 get_absolute_url() (Model method), 1139 get_current_language_bidi get_accessed_time() (Storage method), 1008 template tag, 456 get_actions() (ModelAdmin method), 700 get_current_timezone get_all_permissions() (ModelBackend method), 754 template tag, 481 get_all_permissions() (models.PermissionsMixin get_current_timezone() (in module method), 404 django.utils.timezone), 1387 get_all_permissions() (models.User method), 750 get_current_timezone_name() (in module get_allow_empty() (django.views.generic.list.MultipleObjectMixin django.utils.timezone), 1387 method), 668 get_date_field() (DateMixin method), 675 get_allow_future() (DateMixin method), 675 get_date_list() (BaseDateListView method), 676 get_app_config() (apps method), 629 get_date_list_period() (BaseDateListView method), 676 get_app_configs() (apps method), 629 get_dated_items() (BaseDateListView method), 676 get_autocommit() (in module django.db.transaction), 152 get_dated_queryset() (BaseDateListView method), 676 get_autocomplete_fields() (ModelAdmin method), 725 get_day() (DayMixin method), 674 get_available_languages get_day_format() (DayMixin method), 674 template tag, 456 get_db_prep_save() (Field method), 1112 get_available_name() (in module get_db_prep_value() (Field method), 1112 django.core.files.storage), 573 get_decoded() (base_session.AbstractBaseSession get_available_name() (Storage method), 1009 method), 224 get_bound_field() (Field method), 1030 get_default() (Engine static method), 1348 get_by_natural_key() (ContentTypeManager method), get_default_timezone() (in module 757 django.utils.timezone), 1387

Index

1823

Django Documentation, Release 2.1.dev20171115023625

get_default_timezone_name() (in module get_initial() (django.views.generic.edit.FormMixin django.utils.timezone), 1387 method), 670 get_deferred_fields() (Model method), 1132 get_initial_for_field() (Form method), 1016 get_digit get_inline_instances() (ModelAdmin method), 726 template filter, 1334 get_internal_type() (Field method), 1111 get_edited_object() (LogEntry method), 746 get_json_data() (Form.errors method), 1015 get_email_field_name() (django.contrib.auth.models.AbstractBaseUser get_language() (in module django.utils.translation), 1389 class method), 401 get_language_bidi() (in module django.utils.translation), get_exclude() (ModelAdmin method), 726 1389 get_expire_at_browser_close() (back- get_language_from_request() (in module ends.base.SessionBase method), 218 django.utils.translation), 1389 get_expiry_age() (backends.base.SessionBase method), get_language_info 217 template tag, 456 get_expiry_date() (backends.base.SessionBase method), get_language_info() (in module django.utils.translation), 217 451 get_extra() (InlineModelAdmin method), 736 get_language_info_list get_field() (Options method), 1115 template tag, 456 get_fields() (Layer method), 843 get_latest_by (Options attribute), 1123 get_fields() (ModelAdmin method), 726 get_list_display() (ModelAdmin method), 726 get_fields() (Options method), 1116 get_list_display_links() (ModelAdmin method), 726 get_fieldsets() (ModelAdmin method), 726 get_list_filter() (ModelAdmin method), 726 get_fixed_timezone() (in module django.utils.timezone), get_list_or_404() (in module django.shortcuts), 209 1386 get_list_select_related() (ModelAdmin method), 726 get_flatpages get_login_url() (AccessMixin method), 372 template tag, 765 get_lookup() (in module django.db.models), 1191 get_FOO_display() (Model method), 1140 get_lookup() (lookups.RegisterLookupMixin method), get_for_id() (ContentTypeManager method), 757 1190 get_for_model() (ContentTypeManager method), 757 get_make_object_list() (YearArchiveView method), 655 get_for_models() (ContentTypeManager method), 757 get_max_age() (in module django.utils.cache), 1376 get_form() (django.views.generic.edit.FormMixin get_max_num() (InlineModelAdmin method), 736 method), 670 get_media_prefix get_form() (ModelAdmin method), 728 template tag, 1346 get_form_class() (django.views.generic.edit.FormMixin get_messages() (in module django.contrib.messages), 883 method), 670 get_min_num() (InlineModelAdmin method), 736 get_form_class() (django.views.generic.edit.ModelFormMixin get_model() (AppConfig method), 628 method), 671 get_model() (apps method), 629 get_form_kwargs() (django.views.generic.edit.FormMixin get_model_class() (django.contrib.sessions.backends.db.SessionStore method), 670 class method), 224 get_form_kwargs() (django.views.generic.edit.ModelFormMixin get_models() (AppConfig method), 628 method), 671 get_modified_time() (Storage method), 1009 get_formset() (InlineModelAdmin method), 736 get_month() (MonthMixin method), 673 get_formsets_with_inlines() (ModelAdmin method), 728 get_month_format() (MonthMixin method), 673 get_full_name() (models.CustomUser method), 401 get_next_by_FOO() (Model method), 1141 get_full_name() (models.User method), 750 get_next_day() (DayMixin method), 674 get_full_path() (HttpRequest method), 1232 get_next_month() (MonthMixin method), 673 get_full_path_info() (HttpRequest method), 1232 get_next_week() (WeekMixin method), 675 get_geoms() (Layer method), 843 get_next_year() (YearMixin method), 673 get_group_by_cols() (Expression method), 1206 get_object() (django.views.generic.detail.SingleObjectMixin get_group_permissions() (ModelBackend method), 753 method), 665 get_group_permissions() (models.PermissionsMixin get_object_for_this_type() (ContentType method), 756 method), 404 get_object_or_404() (in module django.shortcuts), 208 get_group_permissions() (models.User method), 750 get_or_create() (in module get_host() (HttpRequest method), 1231 django.db.models.query.QuerySet), 1167

1824

Index

Django Documentation, Release 2.1.dev20171115023625

get_ordering() (django.views.generic.list.MultipleObjectMixin get_static_prefix method), 668 template tag, 1346 get_ordering() (ModelAdmin method), 724 get_storage_class() (in module django.core.files.storage), get_page() (Paginator method), 500 1008 get_paginate_by() (django.views.generic.list.MultipleObjectMixin get_success_message() (views.SuccessMessageMixin method), 668 method), 886 get_paginate_orphans() (django.views.generic.list.MultipleObjectMixin get_success_url() (django.views.generic.edit.DeletionMixin method), 668 method), 672 get_paginator() (django.views.generic.list.MultipleObjectMixin get_success_url() (django.views.generic.edit.FormMixin method), 668 method), 670 get_paginator() (ModelAdmin method), 731 get_success_url() (django.views.generic.edit.ModelFormMixin get_password_validators() (in module method), 671 django.contrib.auth.password_validation), get_tag_uri() (in module django.utils.feedgenerator), 391 1380 get_permission_denied_message() (AccessMixin get_template() (Engine method), 1349 method), 372 get_template() (in module django.template.loader), 273 get_permission_required() (PermissionRequiredMixin get_template() (Loader method), 1361 method), 372 get_template_names() (django.views.generic.base.TemplateResponseMixin get_port() (HttpRequest method), 1232 method), 664 get_post_parameters() (SafeExceptionReporterFilter get_template_names() (django.views.generic.detail.SingleObjectTemplateRe method), 591 method), 666 get_prefix() (django.views.generic.edit.FormMixin get_template_names() (django.views.generic.list.MultipleObjectTemplateRe method), 670 method), 669 get_prep_value() (Field method), 1112 get_template_sources() (Loader method), 1360 get_prepopulated_fields() (ModelAdmin method), 726 get_test_func() (UserPassesTestMixin method), 370 get_prev_week() (WeekMixin method), 675 get_test_runner_kwargs() (DiscoverRunner method), 360 get_previous_by_FOO() (Model method), 1141 get_traceback_frame_variables() (SafeExceptionReget_previous_day() (DayMixin method), 674 porterFilter method), 591 get_previous_month() (MonthMixin method), 673 get_transform() (in module django.db.models), 1191 get_previous_year() (YearMixin method), 673 get_transform() (lookups.RegisterLookupMixin method), get_queryset() (django.views.generic.detail.SingleObjectMixin 1190 method), 665 get_urls() (ModelAdmin method), 726 get_queryset() (django.views.generic.list.MultipleObjectMixin get_user() (in module django.contrib.auth), 755 method), 668 get_user_model() (in module django.contrib.auth), 399 get_queryset() (ModelAdmin method), 730 get_user_permissions() (ModelBackend method), 753 get_readonly_fields() (ModelAdmin method), 725 get_username() (models.AbstractBaseUser method), 401 get_redirect_field_name() (AccessMixin method), 372 get_username() (models.User method), 749 get_redirect_url() (django.views.generic.base.RedirectView get_valid_name() (in module django.core.files.storage), method), 646 573 get_rollback() (in module django.db.transaction), 153 get_valid_name() (Storage method), 1009 get_script_prefix() (in module django.urls), 1373 get_version() (BaseCommand method), 539 get_search_fields() (ModelAdmin method), 726 get_week() (WeekMixin method), 674 get_search_results() (ModelAdmin method), 725 get_week_format() (WeekMixin method), 674 get_session_auth_hash() (models.AbstractBaseUser get_year() (YearMixin method), 673 method), 402 get_year_format() (YearMixin method), 672 get_session_store_class() getlist() (QueryDict method), 1235 (django.contrib.sessions.base_session.AbstractBaseSession gettext() (in module django.utils.translation), 1388 class method), 224 gettext_lazy() (in module django.utils.translation), 1388 get_short_name() (models.CustomUser method), 401 gettext_noop() (in module django.utils.translation), 1388 get_short_name() (models.User method), 750 getvalue() (HttpResponse method), 1239 get_signed_cookie() (HttpRequest method), 1232 GinIndex (class in django.contrib.postgres.indexes), 908 get_slug_field() (django.views.generic.detail.SingleObjectMixin gis-contains method), 666 field lookup type, 805 get_source_expressions() (Expression method), 1205 GistIndex (class in django.contrib.postgres.indexes), 908

Index

1825

Django Documentation, Release 2.1.dev20171115023625

gml (OGRGeometry attribute), 848 Greatest (class in django.db.models.functions), 1214 groups (models.User attribute), 748 gt field lookup type, 1178 gte field lookup type, 1178 gzip_page() (in module django.views.decorators.gzip), 201 GZipMiddleware (class in django.middleware.gzip), 1076

django-admin command, 976 help (BaseCommand attribute), 538 help_text (BoundField attribute), 1028 help_text (Field attribute), 1036, 1092 hex (GEOSGeometry attribute), 829 hex (OGRGeometry attribute), 848 hexewkb (GEOSGeometry attribute), 829 hidden (Field attribute), 1113 HiddenInput (class in django.forms), 1062 history_view() (ModelAdmin method), 732 HOST H setting, 1252 hour handle() (BaseCommand method), 539 field lookup type, 1183 handle_app_config() (AppCommand method), 539 HStoreExtension (class in handle_label() (LabelCommand method), 540 django.contrib.postgres.operations), 910 handle_no_permission() (AccessMixin method), 372 HStoreField (class in django.contrib.postgres.fields), 895 handle_raw_input() (FileUploadHandler method), 1012 HStoreField (class in django.contrib.postgres.forms), 906 handler400 (in module django.conf.urls), 1375 hstorefield.contained_by handler403 (in module django.conf.urls), 1375 field lookup type, 896 handler404 (in module django.conf.urls), 1376 hstorefield.contains handler500 (in module django.conf.urls), 1376 field lookup type, 896 has_add_permission() (ModelAdmin method), 730 hstorefield.has_any_keys has_change_permission() (ModelAdmin method), 730 field lookup type, 897 has_changed() (Field method), 1038 hstorefield.has_key has_changed() (Form method), 1017 field lookup type, 896 has_delete_permission() (ModelAdmin method), 730 hstorefield.has_keys has_error() (Form method), 1015 field lookup type, 897 has_header() (HttpResponse method), 1238 hstorefield.key has_module_permission() (ModelAdmin method), 730 field lookup type, 895 has_module_perms() (ModelBackend method), 754 has_module_perms() (models.PermissionsMixin hstorefield.keys field lookup type, 897 method), 405 hstorefield.values has_module_perms() (models.User method), 750 field lookup type, 897 has_next() (Page method), 501 html_name (BoundField attribute), 1028 has_other_pages() (Page method), 501 html_safe() (in module django.utils.html), 1384 has_perm() (ModelBackend method), 754 http_date() (in module django.utils.http), 1385 has_perm() (models.PermissionsMixin method), 405 http_method_names (django.views.generic.base.View athas_perm() (models.User method), 750 tribute), 643 has_permission() (AdminSite method), 743 has_permission() (PermissionRequiredMixin method), http_method_not_allowed() (django.views.generic.base.View method), 372 644 has_perms() (models.PermissionsMixin method), 405 HttpRequest (class in django.http), 1228 has_perms() (models.User method), 750 HttpResponse (class in django.http), 1236 has_previous() (Page method), 501 has_usable_password() (models.AbstractBaseUser HttpResponseBadRequest (class in django.http), 1240 HttpResponseForbidden (class in django.http), 1240 method), 402 HttpResponseGone (class in django.http), 1240 has_usable_password() (models.User method), 750 HttpResponseNotAllowed (class in django.http), 1240 hasz (GEOSGeometry attribute), 829 HttpResponseNotFound (class in django.http), 1240 head() (Client method), 331 HttpResponseNotModified (class in django.http), 1239 height (GDALBand attribute), 861 HttpResponsePermanentRedirect (class in django.http), height (GDALRaster attribute), 858 1239 height (ImageFile attribute), 1007 HttpResponseRedirect (class in django.http), 1239 height_field (ImageField attribute), 1101 HttpResponseServerError (class in django.http), 1240 help 1826

Index

Django Documentation, Release 2.1.dev20171115023625

I i18n (Sitemap attribute), 919 i18n_patterns() (in module django.conf.urls.i18n), 462 icontains field lookup type, 1177 id_for_label (BoundField attribute), 1028 id_for_label() (Widget method), 1059 identify_epsg() (SpatialReference method), 854 iendswith field lookup type, 1180 iexact field lookup type, 1176 if template tag, 1315 ifchanged template tag, 1318 IGNORABLE_404_URLS setting, 1266 ImageField (class in django.db.models), 1101 ImageField (class in django.forms), 1043 ImageFile (class in django.core.files.images), 1007 import_epsg() (SpatialReference method), 854 import_proj() (SpatialReference method), 854 import_string() (in module django.utils.module_loading), 1385 import_user_input() (SpatialReference method), 854 import_wkt() (SpatialReference method), 854 import_xml() (SpatialReference method), 854 ImproperlyConfigured, 1003 in field lookup type, 1177 in_bulk() (in module django.db.models.query.QuerySet), 1170 include template tag, 1319 include() (in module django.urls), 1374 inclusion_tag() (django.template.Library method), 562 Index (class in django.db.models), 1114 index (Feature attribute), 845 index_template (AdminSite attribute), 742 index_title (AdminSite attribute), 742 index_together (Options attribute), 1128 indexes (Options attribute), 1127 Info (class in django.core.checks), 632 info (GDALRaster attribute), 860 initial (django.views.generic.edit.FormMixin attribute), 670 initial (Field attribute), 1035 initial (Form attribute), 1016 initial (Migration attribute), 312 inlineformset_factory() (in module django.forms.models), 1053 InlineModelAdmin (class in django.contrib.admin), 733 inlines (ModelAdmin attribute), 711 Index

InMemoryUploadedFile (class in django.core.files.uploadedfile), 1011 input_date_formats (SplitDateTimeField attribute), 1049 input_formats (DateField attribute), 1040 input_formats (DateTimeField attribute), 1041 input_formats (TimeField attribute), 1046 input_time_formats (SplitDateTimeField attribute), 1049 inspectdb django-admin command, 980 inspectdb command line option –database DATABASE, 981 INSTALLED_APPS setting, 1266 instance namespace, 195 int_list_validator() (in module django.core.validators), 1393 int_to_base36() (in module django.utils.http), 1385 intcomma template filter, 879 IntegerField (class in django.db.models), 1101 IntegerField (class in django.forms), 1044 IntegerRangeField (class in django.contrib.postgres.fields), 899 IntegerRangeField (class in django.contrib.postgres.forms), 906 IntegrityError, 1004 InterfaceError, 1004 INTERNAL_IPS setting, 1267 InternalError, 1004 internationalization, 487 interpolate() (GEOSGeometry method), 831 interpolate_normalized() (GEOSGeometry method), 831 Intersection (class in django.contrib.gis.db.models.functions), 819 intersection() (GEOSGeometry method), 831 intersection() (in module django.db.models.query.QuerySet), 1153 intersection() (OGRGeometry method), 850 intersects field lookup type, 807 intersects() (GEOSGeometry method), 831 intersects() (OGRGeometry method), 849 intersects() (PreparedGeometry method), 836 intword template filter, 879 InvalidPage, 501 inverse_flattening (SpatialReference attribute), 855 inverse_match (RegexValidator attribute), 1391 iregex field lookup type, 1185 iri_to_uri() (in module django.utils.encoding), 1379 iriencode template filter, 1334

1827

Django Documentation, Release 2.1.dev20171115023625

is_active (in module django.contrib.auth), 404 is_active (models.CustomUser attribute), 401 is_active (models.User attribute), 748 is_active() (SafeExceptionReporterFilter method), 591 is_ajax() (HttpRequest method), 1233 is_anonymous (models.AbstractBaseUser attribute), 401 is_anonymous (models.User attribute), 749 is_authenticated (models.AbstractBaseUser attribute), 401 is_authenticated (models.User attribute), 749 is_aware() (in module django.utils.timezone), 1387 is_bound (Form attribute), 1013 is_hidden (BoundField attribute), 1028 is_installed() (apps method), 629 is_multipart() (Form method), 1031 is_naive() (in module django.utils.timezone), 1387 is_password_usable() (in module django.contrib.auth.hashers), 389 is_protected_type() (in module django.utils.encoding), 1378 is_relation (Field attribute), 1114 is_rendered (SimpleTemplateResponse attribute), 1362 is_secure() (HttpRequest method), 1233 is_staff (in module django.contrib.auth), 404 is_staff (models.User attribute), 748 is_superuser (models.PermissionsMixin attribute), 404 is_superuser (models.User attribute), 749 is_valid() (Form method), 1014 is_vsi_based (GDALRaster attribute), 861 isnull field lookup type, 1184 istartswith field lookup type, 1179 isvalid field lookup type, 807 IsValid (class in django.contrib.gis.db.models.functions), 819 item_attributes() (SyndicationFeed method), 1380 item_geometry() (Feed method), 876 items (Sitemap attribute), 918 items() (backends.base.SessionBase method), 217 items() (QueryDict method), 1234 iterator() (in module django.db.models.query.QuerySet), 1170

J Java, 592 JavaScriptCatalog (class in django.views.i18n), 457 Jinja2 (class in django.forms.renderers), 1054 Jinja2 (class in django.template.backends.jinja2), 276 join template filter, 1335 json (GEOSGeometry attribute), 829 json (OGRGeometry attribute), 848 1828

json() (Response method), 333 JSONBAgg (class in django.contrib.postgres.aggregates), 888 JSONCatalog (class in django.views.i18n), 461 JSONField (class in django.contrib.postgres.fields), 898 JSONField (class in django.contrib.postgres.forms), 906 jsonfield.contained_by field lookup type, 899 jsonfield.contains field lookup type, 899 jsonfield.has_any_keys field lookup type, 899 jsonfield.has_key field lookup type, 899 jsonfield.has_keys field lookup type, 899 jsonfield.key field lookup type, 898 JsonResponse (class in django.http), 1240 JVM, 592 Jython, 592 JYTHONPATH, 593

K keep_lazy() (in module django.utils.functional), 1382 keep_lazy_text() (in module django.utils.functional), 1383 keys() (backends.base.SessionBase method), 217 KeysValidator (class in django.contrib.postgres.validators), 914 kml (GEOSGeometry attribute), 830 kml (OGRGeometry attribute), 848 kwargs (ResolverMatch attribute), 1372

L label (AppConfig attribute), 627 label (BoundField attribute), 1028 label (Field attribute), 1034 label (LabelCommand attribute), 540 label (Options attribute), 1129 label_lower (Options attribute), 1129 label_suffix (Field attribute), 1034 label_suffix (Form attribute), 1024 label_tag() (BoundField method), 1029 LabelCommand (class in django.core.management), 540 Lag (class in django.db.models.functions), 1227 language template tag, 455 language code, 487 language_bidi template filter, 457 LANGUAGE_CODE setting, 1267 LANGUAGE_COOKIE_AGE Index

Django Documentation, Release 2.1.dev20171115023625

setting, 1267 LANGUAGE_COOKIE_DOMAIN setting, 1267 LANGUAGE_COOKIE_NAME setting, 1268 LANGUAGE_COOKIE_PATH setting, 1268 language_name template filter, 457 language_name_local template filter, 457 language_name_translated template filter, 457 LANGUAGE_SESSION_KEY (in module django.utils.translation), 1389 LANGUAGES setting, 1268 last template filter, 1335 last() (in module django.db.models.query.QuerySet), 1172 last_login (models.User attribute), 749 last_modified() (in module django.views.decorators.http), 201 last_name (models.User attribute), 748 lastmod (Sitemap attribute), 918 LastValue (class in django.db.models.functions), 1227 lat_lon() (GeoIP2 method), 868 latest() (in module django.db.models.query.QuerySet), 1171 latest_post_date() (SyndicationFeed method), 1380 Layer (class in django.contrib.gis.gdal), 841 layer_count (DataSource attribute), 841 layer_name (Feature attribute), 844 LayerMapping (class in django.contrib.gis.utils), 870 Lead (class in django.db.models.functions), 1227 learn_cache_key() (in module django.utils.cache), 1377 Least (class in django.db.models.functions), 1215 leave_locale_alone (BaseCommand attribute), 538 left field lookup type, 809 length template filter, 1335 Length (class in django.contrib.gis.db.models.functions), 819 Length (class in django.db.models.functions), 1224 length (GEOSGeometry attribute), 833 length_is template filter, 1335 lhs (Lookup attribute), 1192 lhs (Transform attribute), 1192 limit (Sitemap attribute), 919 limit_choices_to (ForeignKey attribute), 1106 limit_choices_to (ManyToManyField attribute), 1108

Index

linear_name (SpatialReference attribute), 854 linear_units (SpatialReference attribute), 854 LinearRing (class in django.contrib.gis.geos), 834 linebreaks template filter, 1335 linebreaksbr template filter, 1336 LineLocatePoint (class in django.contrib.gis.db.models.functions), 819 linenumbers template filter, 1336 LineString (class in django.contrib.gis.gdal), 851 LineString (class in django.contrib.gis.geos), 834 LineStringField (class in django.contrib.gis.db.models), 791 LineStringField (class in django.contrib.gis.forms), 801 list_display (ModelAdmin attribute), 711 list_display_links (ModelAdmin attribute), 715 list_editable (ModelAdmin attribute), 716 list_filter (ModelAdmin attribute), 716 list_max_show_all (ModelAdmin attribute), 718 list_per_page (ModelAdmin attribute), 719 list_select_related (ModelAdmin attribute), 719 listdir() (Storage method), 1009 lists() (QueryDict method), 1235 ListView (built-in class), 679 LiveServerTestCase (class in django.test), 339 ljust template filter, 1336 ll (Envelope attribute), 852 load template tag, 1320 loaddata django-admin command, 981 loaddata command line option –app APP_LABEL, 981 –database DATABASE, 981 –exclude EXCLUDE, -e EXCLUDE, 981 –format FORMAT, 981 –ignorenonexistent, -i, 981 Loader (class in django.template.loaders.base), 1360 loads() (in module django.core.signing), 433 local (SpatialReference attribute), 855 localdate() (in module django.utils.timezone), 1387 locale name, 487 LOCALE_PATHS setting, 1268 LocaleMiddleware (class in django.middleware.locale), 1077 localization, 487 localize template filter, 476 template tag, 475

1829

Django Documentation, Release 2.1.dev20171115023625

localize (Field attribute), 1037 localtime template filter, 481 template tag, 480 localtime() (in module django.utils.timezone), 1387 location (FileSystemStorage attribute), 1008 location (Sitemap attribute), 918 locmem.Loader (class in django.template.loaders), 1360 LOGGING setting, 1269 LOGGING_CONFIG setting, 1269 login() (Client method), 332 login() (in module django.contrib.auth), 366 login_form (AdminSite attribute), 742 LOGIN_REDIRECT_URL setting, 1281 login_required() (in module django.contrib.auth.decorators), 368 login_template (AdminSite attribute), 742 LOGIN_URL setting, 1281 login_url (AccessMixin attribute), 372 LoginRequiredMixin (class in django.contrib.auth.mixins), 369 LoginView (class in django.contrib.auth.views), 374 logout() (Client method), 333 logout() (in module django.contrib.auth), 367 LOGOUT_REDIRECT_URL setting, 1281 logout_template (AdminSite attribute), 742 logout_then_login() (in module django.contrib.auth.views), 377 LogoutView (class in django.contrib.auth.views), 376 lon_lat() (GeoIP2 method), 868 Long-term support release, 1774 Lookup (class in django.db.models), 1192 lookup_allowed() (ModelAdmin method), 730 lookup_name (Lookup attribute), 1192 lookup_name (Transform attribute), 1192 lookups.RegisterLookupMixin (class in django.db.models), 1190 lorem template tag, 1320 lower template filter, 1336 Lower (class in django.db.models.functions), 1225 lt field lookup type, 1179 lte field lookup type, 1179

M mail_admins() (in module django.core.mail), 435 1830

mail_managers() (in module django.core.mail), 435 make_aware() (in module django.utils.timezone), 1387 make_list template filter, 1337 make_naive() (in module django.utils.timezone), 1388 make_object_list (YearArchiveView attribute), 655 make_password() (in module django.contrib.auth.hashers), 389 make_random_password() (models.BaseUserManager method), 403 MakeLine (class in django.contrib.gis.db.models), 814 makemessages django-admin command, 984 makemessages command line option –add-location [{full,file,never}], 985 –all, -a, 984 –domain DOMAIN, -d DOMAIN, 984 –exclude EXCLUDE, -x EXCLUDE, 984 –extension EXTENSIONS, -e EXTENSIONS, 984 –ignore PATTERN, -i PATTERN, 985 –keep-pot, 985 –locale LOCALE, -l LOCALE, 984 –no-default-ignore, 985 –no-location, 985 –no-wrap, 985 –symlinks, -s, 985 makemigrations django-admin command, 985 makemigrations command line option –check, 986 –dry-run, 986 –empty, 986 –merge, 986 –name NAME, -n NAME, 986 –noinput, –no-input, 986 MakeValid (class in django.contrib.gis.db.models.functions), 819 managed (Options attribute), 1124 Manager (class in django.db.models), 133 MANAGERS setting, 1269 managers.CurrentSiteManager (class in django.contrib.sites), 928 manifest_strict (storage.ManifestStaticFilesStorage attribute), 934 many_to_many (Field attribute), 1114 many_to_one (Field attribute), 1114 ManyToManyField (class in django.db.models), 1107 map_height (BaseGeometryWidget attribute), 802 map_height (GeoModelAdmin attribute), 874 map_srid (BaseGeometryWidget attribute), 802 map_template (GeoModelAdmin attribute), 874 map_width (BaseGeometryWidget attribute), 802 map_width (GeoModelAdmin attribute), 874

Index

Django Documentation, Release 2.1.dev20171115023625

mapping() (in module django.contrib.gis.utils), 872 mark_safe() (in module django.utils.safestring), 1385 match (FilePathField attribute), 1043, 1100 Max (class in django.db.models), 1186 max (GDALBand attribute), 862 max_digits (DecimalField attribute), 1041, 1096 max_length (CharField attribute), 1039, 1095 max_length (SimpleArrayField attribute), 904 max_length (URLField attribute), 1047 max_num (InlineModelAdmin attribute), 735 max_post_process_passes (storage.ManifestStaticFilesStorage attribute), 934 max_value (DecimalField attribute), 1041 max_value (IntegerField attribute), 1044 max_x (Envelope attribute), 852 max_y (Envelope attribute), 852 MaxLengthValidator (class in django.core.validators), 1393 MaxValueValidator (class in django.core.validators), 1393 mean (GDALBand attribute), 862 MEDIA_ROOT setting, 1269 MEDIA_URL setting, 1269 MemoryFileUploadHandler (class in django.core.files.uploadhandler), 1011 MemSize (class in django.contrib.gis.db.models.functions), 820 merged (MultiLineString attribute), 835 message (EmailValidator attribute), 1391 message (ProhibitNullCharactersValidator attribute), 1394 message (RegexValidator attribute), 1391 message file, 487 MESSAGE_LEVEL setting, 1282 MESSAGE_STORAGE setting, 1282 MESSAGE_TAGS setting, 1282 message_user() (ModelAdmin method), 731 MessageMiddleware (class in django.contrib.messages.middleware), 1077 META (HttpRequest attribute), 1230 metadata (GDALBand attribute), 863 metadata (GDALRaster attribute), 860 method (HttpRequest attribute), 1229 method_decorator() (in module django.utils.decorators), 1378 MIDDLEWARE setting, 1270

Index

middleware.RedirectFallbackMiddleware (class in django.contrib.redirects), 916 MiddlewareNotUsed, 1003 migrate django-admin command, 986 migrate command line option –database DATABASE, 986 –fake, 986 –fake-initial, 986 –noinput, –no-input, 987 –run-syncdb, 987 MIGRATION_MODULES setting, 1270 Min (class in django.db.models), 1187 min (GDALBand attribute), 862 min_length (CharField attribute), 1039 min_length (SimpleArrayField attribute), 904 min_length (URLField attribute), 1047 min_num (InlineModelAdmin attribute), 735 min_value (DecimalField attribute), 1041 min_value (IntegerField attribute), 1044 min_x (Envelope attribute), 852 min_y (Envelope attribute), 852 MinimumLengthValidator (class in django.contrib.auth.password_validation), 391 MinLengthValidator (class in django.core.validators), 1393 minute field lookup type, 1183 MinValueValidator (class in django.core.validators), 1393 missing_args_message (BaseCommand attribute), 538 mode (File attribute), 1006 model, 1405 Model (class in django.db.models), 1129 model (ContentType attribute), 756 model (django.views.generic.detail.SingleObjectMixin attribute), 665 model (django.views.generic.edit.ModelFormMixin attribute), 671 model (django.views.generic.list.MultipleObjectMixin attribute), 667 model (Field attribute), 1114 model (InlineModelAdmin attribute), 735 Model.DoesNotExist, 1141 model_class() (ContentType method), 756 ModelAdmin (class in django.contrib.admin), 704 ModelBackend (class in django.contrib.auth.backends), 753 ModelChoiceField (class in django.forms), 1050 ModelForm (class in django.forms), 247 modelform_factory() (in module django.forms.models), 1052

1831

Django Documentation, Release 2.1.dev20171115023625

modelformset_factory() (in module django.forms.models), 1053 ModelMultipleChoiceField (class in django.forms), 1051 models.AbstractBaseUser (class in django.contrib.auth), 401 models.AbstractUser (class in django.contrib.auth), 402 models.AnonymousUser (class in django.contrib.auth), 751 models.BaseInlineFormSet (class in django.forms), 263 models.BaseModelFormSet (class in django.forms), 258 models.BaseUserManager (class in django.contrib.auth), 403 models.CustomUser (class in django.contrib.auth), 400, 404 models.CustomUserManager (class in django.contrib.auth), 402 models.Group (class in django.contrib.auth), 752 models.LogEntry (class in django.contrib.admin), 745 models.Permission (class in django.contrib.auth), 751 models.PermissionsMixin (class in django.contrib.auth), 404 models.ProtectedError, 1005 models.Redirect (class in django.contrib.redirects), 916 models.Site (class in django.contrib.sites), 924 models.User (class in django.contrib.auth), 748, 749 models.UserManager (class in django.contrib.auth), 751 models_module (AppConfig attribute), 628 modifiable (GeoModelAdmin attribute), 874 modify_settings() (in module django.test), 344 modify_settings() (SimpleTestCase method), 343 module (AppConfig attribute), 628 month field lookup type, 1181 month (MonthMixin attribute), 673 MONTH_DAY_FORMAT setting, 1270 month_format (MonthMixin attribute), 673 MonthArchiveView (built-in class), 685 MonthArchiveView (class in django.views.generic.dates), 656 MonthMixin (class in django.views.generic.dates), 673 months (SelectDateWidget attribute), 1068 MTV, 1405 multi_db (TransactionTestCase attribute), 342 MultiLineString (class in django.contrib.gis.geos), 835 MultiLineStringField (class in django.contrib.gis.db.models), 791 MultiLineStringField (class in django.contrib.gis.forms), 802 multiple_chunks() (File method), 1006 multiple_chunks() (UploadedFile method), 1010 MultipleChoiceField (class in django.forms), 1045 MultipleHiddenInput (class in django.forms), 1067 MultipleObjectsReturned, 1002

1832

MultiPoint (class in django.contrib.gis.geos), 835 MultiPointField (class in django.contrib.gis.db.models), 791 MultiPointField (class in django.contrib.gis.forms), 801 MultiPolygon (class in django.contrib.gis.geos), 835 MultiPolygonField (class in django.contrib.gis.db.models), 791 MultiPolygonField (class in django.contrib.gis.forms), 802 MultiValueField (class in django.forms), 1048 MultiWidget (class in django.forms), 1059 MVC, 1405

N NAME setting, 1252 name (AppConfig attribute), 627 name (BoundField attribute), 1028 name (ContentType attribute), 756 name (CreateExtension attribute), 910 name (DataSource attribute), 841 name (Field attribute), 845 name (FieldFile attribute), 1099 name (File attribute), 1006 name (GDALRaster attribute), 857 name (Index attribute), 1115 name (Layer attribute), 842 name (models.Group attribute), 752 name (models.Permission attribute), 751 name (models.Site attribute), 924 name (OGRGeomType attribute), 852 name (Origin attribute), 1361 name (SpatialReference attribute), 854 name (UploadedFile attribute), 1010 namespace (ResolverMatch attribute), 1372 namespaces (ResolverMatch attribute), 1372 naturalday template filter, 880 naturaltime template filter, 880 never_cache() (in module django.views.decorators.cache), 201 new_file() (FileUploadHandler method), 1012 new_objects (models.BaseModelFormSet attribute), 260 next_page_number() (Page method), 501 ngettext() (in module django.utils.translation), 1388 ngettext_lazy() (in module django.utils.translation), 1388 nodata_value (GDALBand attribute), 862 non_atomic_requests() (in module django.db.transaction), 146 NON_FIELD_ERRORS (in module django.core.exceptions), 1004 non_field_errors() (Form method), 1016

Index

Django Documentation, Release 2.1.dev20171115023625

none() (in module django.db.models.query.QuerySet), object_id (LogEntry attribute), 745 1152 object_list (Page attribute), 502 noop (RunSQL attribute), 1084 object_repr (LogEntry attribute), 745 noop() (RunPython static method), 1086 ObjectDoesNotExist, 1002 NoReverseMatch, 1004 objects (Model attribute), 1121 normalize() (GEOSGeometry method), 833 ogr (GEOSGeometry attribute), 830 normalize_email() (django.contrib.auth.models.BaseUserManager OGRGeometry (class in django.contrib.gis.gdal), 846 class method), 403 OGRGeomType (class in django.contrib.gis.gdal), 851 normalize_username() (django.contrib.auth.models.AbstractBaseUser ogrinspect class method), 401 django-admin command, 873 NotSupportedError, 1004 ogrinspect command line option now –blank BLANK, 873 template tag, 1321 –decimal DECIMAL, 873 Now (class in django.db.models.functions), 1219 –geom-name GEOM_NAME, 873 now() (in module django.utils.timezone), 1387 –layer LAYER_KEY, 873 npgettext() (in module django.utils.translation), 1388 –mapping, 873 npgettext_lazy() (in module django.utils.translation), –multi-geom, 874 1388 –name-field NAME_FIELD, 874 NthValue (class in django.db.models.functions), 1227 –no-imports, 874 Ntile (class in django.db.models.functions), 1227 –null NULL, 874 null (Field attribute), 1089 –srid SRID, 874 NullBooleanField (class in django.db.models), 1102 on_commit() (in module django.db.transaction), 149 NullBooleanField (class in django.forms), 1045 on_delete (ForeignKey attribute), 1105 NullBooleanSelect (class in django.forms), 1065 one_to_many (Field attribute), 1114 num (OGRGeomType attribute), 852 one_to_one (Field attribute), 1114 num_coords (GEOSGeometry attribute), 828 OneToOneField (class in django.db.models), 1110 num_coords (OGRGeometry attribute), 847 only() (in module django.db.models.query.QuerySet), num_feat (Layer attribute), 842 1163 num_fields (Feature attribute), 844 open() (django.contrib.gis.geoip2.GeoIP2 class method), num_fields (Layer attribute), 842 867 num_geom (GEOSGeometry attribute), 828 open() (FieldFile method), 1099 num_interior_rings (Polygon attribute), 834 open() (File method), 1006 num_items() (SyndicationFeed method), 1380 open() (Storage method), 1009 num_pages (Paginator attribute), 501 openlayers_url (GeoModelAdmin attribute), 874 num_points (OGRGeometry attribute), 847 OpenLayersWidget (class in number (Page attribute), 502 django.contrib.gis.forms.widgets), 803 NUMBER_GROUPING OperationalError, 1004 setting, 1271 OPTIONS NumberInput (class in django.forms), 1062 setting, 1253 NumericPasswordValidator (class in Options (class in django.db.models.options), 1115 django.contrib.auth.password_validation), options() (Client method), 331 391 options() (django.views.generic.base.View method), 644 NumGeometries (class in order_by() (in module django.contrib.gis.db.models.functions), django.db.models.query.QuerySet), 1145 820 order_fields() (Form method), 1025 NumPoints (class in django.contrib.gis.db.models.functions),order_with_respect_to (Options attribute), 1124 820 ordered (QuerySet attribute), 1143 ordering (django.views.generic.list.MultipleObjectMixin O attribute), 668 ordering (ModelAdmin attribute), 719 object (django.views.generic.edit.CreateView attribute), ordering (Options attribute), 1125 651 ordinal object (django.views.generic.edit.UpdateView attribute), template filter, 880 652 Origin (class in django.template.base), 1361 object_history_template (ModelAdmin attribute), 724 Index

1833

Django Documentation, Release 2.1.dev20171115023625

origin (GDALRaster attribute), 858 OSMGeoAdmin (class in django.contrib.gis.admin), 875 OSMWidget (class in django.contrib.gis.forms.widgets), 803 outdim (WKBWriter attribute), 838 outdim (WKTWriter attribute), 839 OuterRef (class in django.db.models), 1200 output_field (in module django.db.models), 1191 output_field (Transform attribute), 1192 output_transaction (BaseCommand attribute), 538 overlaps field lookup type, 807 overlaps() (GEOSGeometry method), 831 overlaps() (OGRGeometry method), 850 overlaps() (PreparedGeometry method), 836 overlaps_above field lookup type, 810 overlaps_below field lookup type, 810 overlaps_left field lookup type, 809 overlaps_right field lookup type, 810 override() (in module django.utils.timezone), 1387 override() (in module django.utils.translation), 1389 override_settings() (in module django.test), 344

password_change_done_template (AdminSite attribute), 742 password_change_template (AdminSite attribute), 742 password_changed() (in module django.contrib.auth.password_validation), 391 PASSWORD_HASHERS setting, 1281 PASSWORD_RESET_TIMEOUT_DAYS setting, 1281 password_validators_help_text_html() (in module django.contrib.auth.password_validation), 391 password_validators_help_texts() (in module django.contrib.auth.password_validation), 391 PasswordChangeDoneView (class in django.contrib.auth.views), 377 PasswordChangeForm (class in django.contrib.auth.forms), 381 PasswordChangeView (class in django.contrib.auth.views), 377 PasswordInput (class in django.forms), 1062 PasswordResetCompleteView (class in django.contrib.auth.views), 379 PasswordResetConfirmView (class in django.contrib.auth.views), 379 PasswordResetDoneView (class in P django.contrib.auth.views), 378 PasswordResetForm (class in django.contrib.auth.forms), packages (JavaScriptCatalog attribute), 457 381 Page (class in django.core.paginator), 501 PasswordResetView (class in django.contrib.auth.views), page() (Paginator method), 500 377 page_kwarg (django.views.generic.list.MultipleObjectMixin Patch release, 1773 attribute), 668 patch() (Client method), 331 page_range (Paginator attribute), 501 patch_cache_control() (in module django.utils.cache), PageNotAnInteger, 501 1376 paginate_by (django.views.generic.list.MultipleObjectMixin patch_response_headers() (in module django.utils.cache), attribute), 668 1376 paginate_orphans (django.views.generic.list.MultipleObjectMixin patch_vary_headers() (in module django.utils.cache), attribute), 668 paginate_queryset() (django.views.generic.list.MultipleObjectMixin 1377 path (AppConfig attribute), 627 method), 668 path (FilePathField attribute), 1043, 1100 Paginator (class in django.core.paginator), 500 path (HttpRequest attribute), 1229 paginator (ModelAdmin attribute), 719 path() (in module django.urls), 1373 paginator (Page attribute), 502 path() (Storage method), 1009 paginator_class (django.views.generic.list.MultipleObjectMixin path_info (HttpRequest attribute), 1229 attribute), 668 pattern_name (django.views.generic.base.RedirectView parent_link (OneToOneField attribute), 1111 attribute), 646 parse_date() (in module django.utils.dateparse), 1377 PercentRank (class in django.db.models.functions), 1228 parse_datetime() (in module django.utils.dateparse), 1377 Perimeter (class in django.contrib.gis.db.models.functions), parse_duration() (in module django.utils.dateparse), 1377 820 parse_time() (in module django.utils.dateparse), 1377 permanent (django.views.generic.base.RedirectView atPASSWORD tribute), 646 setting, 1253 permission_denied_message (AccessMixin attribute), password (models.User attribute), 748 1834

Index

Django Documentation, Release 2.1.dev20171115023625

372 template filter, 1338 permission_required() (in module pre_init (django.db.models.signals attribute), 1292 django.contrib.auth.decorators), 371 pre_save() (Field method), 1112 PermissionDenied, 1003 precision (Field attribute), 845 PermissionRequiredMixin (class in precision (WKTWriter attribute), 839 django.contrib.auth.mixins), 371 Prefetch (class in django.db.models), 1188 permissions (models.Group attribute), 752 prefetch_related() (in module permissions (Options attribute), 1126 django.db.models.query.QuerySet), 1155 PersistentRemoteUserMiddleware (class in prefetch_related_objects() (in module django.db.models), django.contrib.auth.middleware), 1079 1189 pgettext() (in module django.utils.translation), 1388 prefix (django.views.generic.edit.FormMixin attribute), pgettext_lazy() (in module django.utils.translation), 1388 670 phone2numeric prefix (Form attribute), 1032 template filter, 1337 prepared (GEOSGeometry attribute), 833 ping_google PreparedGeometry (class in django.contrib.gis.geos), 836 django-admin command, 923 PREPEND_WWW ping_google() (in module django.contrib.sitemaps), 923 setting, 1271 pixel_count (GDALBand attribute), 861 prepopulated_fields (ModelAdmin attribute), 719 pk (Model attribute), 1135 preserve_filters (ModelAdmin attribute), 719 pk_url_kwarg (django.views.generic.detail.SingleObjectMixin pretty_wkt (SpatialReference attribute), 855 attribute), 665 previous_page_number() (Page method), 501 pluralize primary_key (Field attribute), 1092 template filter, 1337 priority (Sitemap attribute), 919 Point (class in django.contrib.gis.gdal), 850 process_exception(), 212 Point (class in django.contrib.gis.geos), 833 process_lhs() (Lookup method), 1192 point_count (OGRGeometry attribute), 847 process_rhs() (Lookup method), 1192 point_on_surface (GEOSGeometry attribute), 832 process_template_response(), 212 PointField (class in django.contrib.gis.db.models), 791 process_view(), 211 PointField (class in django.contrib.gis.forms), 801 ProgrammingError, 1004 PointOnSurface (class in ProhibitNullCharactersValidator (class in django.contrib.gis.db.models.functions), django.core.validators), 1394 820 proj (SpatialReference attribute), 855 Polygon (class in django.contrib.gis.gdal), 851 proj4 (SpatialReference attribute), 855 Polygon (class in django.contrib.gis.geos), 834 project, 1405 PolygonField (class in django.contrib.gis.db.models), 791 project() (GEOSGeometry method), 831 PolygonField (class in django.contrib.gis.forms), 801 project_normalized() (GEOSGeometry method), 831 pop() (backends.base.SessionBase method), 217 projected (SpatialReference attribute), 855 pop() (Context method), 1353 property, 1405 pop() (QueryDict method), 1235 PROTECT (in module django.db.models), 1105 popitem() (QueryDict method), 1235 protocol (GenericIPAddressField attribute), 1045, 1101 popup_response_template (ModelAdmin attribute), 724 protocol (Sitemap attribute), 919 PORT proxy (Options attribute), 1127 setting, 1253 push() (Context method), 1353 PositiveIntegerField (class in django.db.models), 1102 put() (Client method), 331 PositiveSmallIntegerField (class in django.db.models), put() (django.views.generic.edit.ProcessFormView 1102 method), 672 POST (HttpRequest attribute), 1229 Python Enhancement Proposals post() (Client method), 330 PEP 20, 1399 post() (django.views.generic.edit.ProcessFormView PEP 234, 1170 method), 672 PEP 249, 145, 149, 152, 967, 1005, 1171, 1411 post_process() (storage.StaticFilesStorage method), 933 PEP 257, 1733 POSTGIS_VERSION PEP 3134, 1005 setting, 877 PEP 318, 344 pprint PEP 3333, 82, 616, 1231

Index

1835

Django Documentation, Release 2.1.dev20171115023625

PEP 343, 343 PEP 420, 629 PEP 440, 977, 1455 PEP 487, 1410 PEP 8, 1723, 1733 python_2_unicode_compatible() (in django.utils.encoding), 1378 PYTHONPATH, 1553 PYTHONSTARTUP, 989 PYTHONWARNINGS, 586

field lookup type, 901 rangefield.isempty field lookup type, 903 rangefield.not_gt field lookup type, 902 module rangefield.not_lt field lookup type, 902 rangefield.overlap field lookup type, 901 rangefield.startswith field lookup type, 902 Q RangeMaxValueValidator (class in django.contrib.postgres.validators), 914 Q (class in django.db.models), 1188 RangeMinValueValidator (class in quarter django.contrib.postgres.validators), 915 field lookup type, 1182 RangeWidget (class in django.contrib.postgres.forms), query_pk_and_slug (django.views.generic.detail.SingleObjectMixin 907 attribute), 665 query_string (django.views.generic.base.RedirectView Rank (class in django.db.models.functions), 1228 RasterField (class in django.contrib.gis.db.models), 792 attribute), 646 raw() (in module django.db.models.query.QuerySet), QueryDict (class in django.http), 1233 1165 queryset, 1405 raw() (Manager method), 140 QuerySet (class in django.db.models.query), 1143 queryset (django.views.generic.detail.SingleObjectMixin raw_id_fields (InlineModelAdmin attribute), 735 raw_id_fields (ModelAdmin attribute), 720 attribute), 665 queryset (django.views.generic.list.MultipleObjectMixin RawSQL (class in django.db.models.expressions), 1202 re_path() (in module django.urls), 1374 attribute), 667 read() (HttpRequest method), 1233 queryset (ModelChoiceField attribute), 1050 read() (UploadedFile method), 1010 queryset (ModelMultipleChoiceField attribute), 1052 readable() (HttpResponse method), 1239 readline() (HttpRequest method), 1233 R readlines() (HttpRequest method), 1233 radio_fields (ModelAdmin attribute), 720 readonly_fields (ModelAdmin attribute), 721 RadioSelect (class in django.forms), 1065 ready (apps attribute), 629 raise_exception (AccessMixin attribute), 372 ready() (AppConfig method), 628 random reason_phrase (HttpResponse attribute), 1237 template filter, 1338 RandomUUID (class in reason_phrase (StreamingHttpResponse attribute), 1242 receive_data_chunk() (FileUploadHandler method), 1011 django.contrib.postgres.functions), 907 receiver() (in module django.dispatch), 525 range recursive (FilePathField attribute), 1043, 1100 field lookup type, 1180 range_type (django.contrib.postgres.forms.BaseRangeField redirect() (in module django.shortcuts), 207 redirect_field_name (AccessMixin attribute), 372 attribute), 903 redirect_to_login() (in module range_type (RangeField attribute), 903 django.contrib.auth.views), 380 RangeField (class in django.contrib.postgres.fields), 903 RedirectView (built-in class), 677 rangefield.adjacent_to refresh_from_db() (Model method), 1131 field lookup type, 902 regex rangefield.contained_by field lookup type, 1184 field lookup type, 901 regex (RegexField attribute), 1046 rangefield.contains regex (RegexValidator attribute), 1391 field lookup type, 901 RegexField (class in django.forms), 1046 rangefield.endswith RegexValidator (class in django.core.validators), 1391 field lookup type, 903 register() (AdminSite method), 743 rangefield.fully_gt register() (in module django.contrib.admin), 705 field lookup type, 902 register() (in module django.core.checks), 529 rangefield.fully_lt 1836

Index

Django Documentation, Release 2.1.dev20171115023625

register_converter() (in module django.urls), 1375 1084 register_lookup() (django.db.models.lookups.RegisterLookupMixin RenameField (class in django.db.migrations.operations), class method), 1190 1083 RegrAvgX (class in django.contrib.postgres.aggregates), RenameModel (class in django.db.migrations.operations), 889 1082 RegrAvgY (class in django.contrib.postgres.aggregates), render() (in module django.shortcuts), 205 889 render() (SimpleTemplateResponse method), 1363 RegrCount (class in django.contrib.postgres.aggregates), render() (Template method), 273, 1349 889 render() (Widget method), 1059 RegrIntercept (class in render_to_response() (django.views.generic.base.TemplateResponseMixin django.contrib.postgres.aggregates), 889 method), 664 regroup render_to_response() (in module django.shortcuts), 206 template tag, 1321 render_to_string() (in module django.template.loader), RegrR2 (class in django.contrib.postgres.aggregates), 890 275 RegrSlope (class in django.contrib.postgres.aggregates), render_value (PasswordInput attribute), 1062 890 rendered_content (SimpleTemplateResponse attribute), RegrSXX (class in django.contrib.postgres.aggregates), 1362 890 request (Response attribute), 333 RegrSXY (class in django.contrib.postgres.aggregates), RequestContext (class in django.template), 1355 890 RequestFactory (class in django.test), 352 RegrSYY (class in django.contrib.postgres.aggregates), requests.RequestSite (class in django.contrib.sites), 930 890 require_all_fields (MultiValueField attribute), 1048 rel_db_type() (Field method), 1112 require_GET() (in module django.views.decorators.http), relabeled_clone() (Expression method), 1205 200 relate require_http_methods() (in module field lookup type, 807 django.views.decorators.http), 200 relate() (GEOSGeometry method), 831 require_POST() (in module relate_pattern() (GEOSGeometry method), 831 django.views.decorators.http), 200 related_model (Field attribute), 1114 require_safe() (in module django.views.decorators.http), related_name (ForeignKey attribute), 1106 200 related_name (ManyToManyField attribute), 1108 required (Field attribute), 1033 related_query_name (ForeignKey attribute), 1106 required_css_class (Form attribute), 1022 related_query_name (GenericRelation attribute), 759 required_db_features (Options attribute), 1127 related_query_name (ManyToManyField attribute), 1108 required_db_vendor (Options attribute), 1127 RelatedManager (class in REQUIRED_FIELDS (models.CustomUser attribute), django.db.models.fields.related), 1119 400 relation_name (FilteredRelation attribute), 1189 RequireDebugFalse (class in django.utils.log), 497 RemoteUserBackend (class in RequireDebugTrue (class in django.utils.log), 497 django.contrib.auth.backends), 754 requires_csrf_token() (in module RemoteUserMiddleware (class in django.views.decorators.csrf), 961 django.contrib.auth.middleware), 1079 requires_migrations_checks (BaseCommand attribute), remove() (RelatedManager method), 1120 538 remove_field() (BaseDatabaseSchemaEditor method), requires_system_checks (BaseCommand attribute), 538 1244 reset_sequences (TransactionTestCase attribute), 356 remove_index() (BaseDatabaseSchemaEditor method), resetcycle 1243 template tag, 1324 remove_stale_contenttypes resolve() (in module django.urls), 1372 django-admin command, 996 resolve_context() (SimpleTemplateResponse method), remove_stale_contenttypes command line option 1362 –database DATABASE, 996 resolve_expression() (Expression method), 1205 remove_trailing_nulls (SplitArrayField attribute), 905 resolve_template() (SimpleTemplateResponse method), RemoveField (class in django.db.migrations.operations), 1362 1083 Resolver404, 1004 RemoveIndex (class in django.db.migrations.operations), resolver_match (HttpRequest attribute), 1230

Index

1837

Django Documentation, Release 2.1.dev20171115023625

resolver_match (Response attribute), 334 rhs (Lookup attribute), 1192 ResolverMatch (class in django.urls), 1372 right Response (class in django.test), 333 field lookup type, 809 response_add() (ModelAdmin method), 731 ring (GEOSGeometry attribute), 829 response_change() (ModelAdmin method), 731 rjust response_class (django.views.generic.base.TemplateResponseMixin template filter, 1338 attribute), 664 rollback() (in module django.db.transaction), 152 response_delete() (ModelAdmin method), 731 root_attributes() (SyndicationFeed method), 1380 response_gone_class (middle- ROOT_URLCONF ware.RedirectFallbackMiddleware attribute), setting, 1271 916 RowNumber (class in django.db.models.functions), 1228 response_redirect_class (CommonMiddleware attribute), RowRange (class in django.db.models.expressions), 1203 1075 Rss201rev2Feed (class in django.utils.feedgenerator), response_redirect_class (LocaleMiddleware attribute), 1381 1077 RssFeed (class in django.utils.feedgenerator), 1381 response_redirect_class (middle- RssUserland091Feed (class in ware.RedirectFallbackMiddleware attribute), django.utils.feedgenerator), 1381 916 run_checks() (DiscoverRunner method), 360 Reverse (class in django.contrib.gis.db.models.functions), run_suite() (DiscoverRunner method), 360 820 run_tests() (DiscoverRunner method), 359 reverse() (in module django.db.models.query.QuerySet), RunPython (class in django.db.migrations.operations), 1146 1085 reverse() (in module django.urls), 1370 runserver reverse_lazy() (in module django.urls), 1371 django-admin command, 933, 987 reverse_ordering() (Expression method), 1206 runserver command line option RFC –insecure, 933 RFC 1034, 1451, 1480 –ipv6, -6, 988 RFC 1123, 1385 –noreload, 987 RFC 2046#section-5.2.1, 438 –nostatic, 933 RFC 2109, 1238, 1284 –nothreading, 988 RFC 2396, 1140 RunSQL (class in django.db.migrations.operations), 1084 RFC 2616, 1438, 1481, 1633 S RFC 2732, 1392 RFC 3987#section-3.1, 1367, 1379 safe RFC 3987#section-3.2, 1368, 1379 template filter, 1338 RFC 4291#section-2.2, 1044, 1101 SafeExceptionReporterFilter (class in RFC 5322, 1329 django.views.debug), 591 RFC 6265, 1238, 1450, 1465, 1493 safeseq RFC 7231, 959, 960, 1481 template filter, 1338 RFC 7231#section-4.2.1, 956, 1168 SafeString (class in django.utils.safestring), 1385 RFC 7231#section-4.3.4, 430 SafeText (class in django.utils.safestring), 1385 RFC 7231#section-4.3.8, 332 same_as RFC 7231#section-6, 1237, 1238, 1242 field lookup type, 806 RFC 7231#section-6.1, 1237, 1242 sample (CovarPop attribute), 889 RFC 7231#section-6.5.3, 1396 sample (StdDev attribute), 1187 RFC 7231#section-7.1.1.1, 1385 sample (Variance attribute), 1187 RFC 7231#section-7.1.4, 426, 1376 save() (base_session.BaseSessionManager method), 224 RFC 7232, 1438 save() (FieldFile method), 1099 RFC 7232#section-2.1, 1076 save() (File method), 1007 RFC 7232#section-4.1, 429 save() (LayerMapping method), 871 RFC 7234, 427 save() (Model method), 1134 RFC 7234#section-4.2.2, 1438 save() (Storage method), 1009 RFC 7234#section-5.2.2.8, 427 save_as (ModelAdmin attribute), 721 RFC 7239#page-7, 1279 save_as_continue (ModelAdmin attribute), 721 1838

Index

Django Documentation, Release 2.1.dev20171115023625

save_formset() (ModelAdmin method), 724 save_model() (ModelAdmin method), 724 save_on_top (ModelAdmin attribute), 722 save_related() (ModelAdmin method), 725 savepoint() (in module django.db.transaction), 153 savepoint_commit() (in module django.db.transaction), 153 savepoint_rollback() (in module django.db.transaction), 153 Scale (class in django.contrib.gis.db.models.functions), 821 scale (GDALRaster attribute), 859 scheme (HttpRequest attribute), 1229 schemes (URLValidator attribute), 1392 search field lookup type, 911 search_fields (ModelAdmin attribute), 722 SearchQuery (class in django.contrib.postgres.search), 912 SearchRank (class in django.contrib.postgres.search), 912 SearchVector (class in django.contrib.postgres.search), 911 SearchVectorField (class in django.contrib.postgres.search), 913 second field lookup type, 1184 SECRET_KEY setting, 1271 SECURE_BROWSER_XSS_FILTER setting, 1272 SECURE_CONTENT_TYPE_NOSNIFF setting, 1272 SECURE_HSTS_INCLUDE_SUBDOMAINS setting, 1272 SECURE_HSTS_PRELOAD setting, 1272 SECURE_HSTS_SECONDS setting, 1273 SECURE_PROXY_SSL_HEADER setting, 1273 SECURE_REDIRECT_EXEMPT setting, 1274 SECURE_SSL_HOST setting, 1274 SECURE_SSL_REDIRECT setting, 1274 SecurityMiddleware (class in django.middleware.security), 1077 seekable() (HttpResponse method), 1239 Select (class in django.forms), 1064 select_for_update() (in module django.db.models.query.QuerySet), 1164 select_on_save (Options attribute), 1127

Index

select_related() (in module django.db.models.query.QuerySet), 1153 select_template() (Engine method), 1349 select_template() (in module django.template.loader), 273 SelectDateWidget (class in django.forms), 1068 SelectMultiple (class in django.forms), 1065 semi_major (SpatialReference attribute), 855 semi_minor (SpatialReference attribute), 855 send() (Signal method), 527 send_email() (PasswordResetForm method), 381 send_mail() (AdminEmailHandler method), 496 send_mail() (in module django.core.mail), 434 send_mass_mail() (in module django.core.mail), 435 send_robust() (Signal method), 527 sendtestemail django-admin command, 989 sendtestemail command line option –admins, 989 –managers, 989 sensitive_post_parameters() (in module django.views.decorators.debug), 590 sensitive_variables() (in module django.views.decorators.debug), 589 SeparateDatabaseAndState (class in django.db.migrations.operations), 1086 SERIALIZATION_MODULES setting, 1274 serializers.JSONSerializer (class in django.contrib.sessions), 218 serializers.PickleSerializer (class in django.contrib.sessions), 218 SERVER_EMAIL setting, 1274 session (Client attribute), 335 session (HttpRequest attribute), 1231 SESSION_CACHE_ALIAS setting, 1283 SESSION_COOKIE_AGE setting, 1283 SESSION_COOKIE_DOMAIN setting, 1283 SESSION_COOKIE_HTTPONLY setting, 1284 SESSION_COOKIE_NAME setting, 1284 SESSION_COOKIE_PATH setting, 1284 SESSION_COOKIE_SECURE setting, 1284 session_data (base_session.AbstractBaseSession attribute), 224 SESSION_ENGINE setting, 1284

1839

Django Documentation, Release 2.1.dev20171115023625

SESSION_EXPIRE_AT_BROWSER_CLOSE setting, 1285 SESSION_FILE_PATH setting, 1285 session_key (base_session.AbstractBaseSession attribute), 224 SESSION_SAVE_EVERY_REQUEST setting, 1285 SESSION_SERIALIZER setting, 1285 SessionMiddleware (class in django.contrib.sessions.middleware), 1079 SET() (in module django.db.models), 1105 set() (RelatedManager method), 1121 set_autocommit() (in module django.db.transaction), 152 set_cookie() (HttpResponse method), 1238 SET_DEFAULT (in module django.db.models), 1105 set_expiry() (backends.base.SessionBase method), 217 set_language() (in module django.views.i18n), 469 SET_NULL (in module django.db.models), 1105 set_password() (models.AbstractBaseUser method), 402 set_password() (models.User method), 750 set_rollback() (in module django.db.transaction), 153 set_signed_cookie() (HttpResponse method), 1238 set_source_expressions() (Expression method), 1205 set_test_cookie() (backends.base.SessionBase method), 217 set_unusable_password() (models.AbstractBaseUser method), 402 set_unusable_password() (models.User method), 750 setdefault() (backends.base.SessionBase method), 217 setdefault() (Context method), 1352 setdefault() (HttpResponse method), 1238 setdefault() (QueryDict method), 1234 setlist() (QueryDict method), 1235 setlistdefault() (QueryDict method), 1235 SetPasswordForm (class in django.contrib.auth.forms), 381 setting ABSOLUTE_URL_OVERRIDES, 1245 ADMINS, 1245 ALLOWED_HOSTS, 1246 APPEND_SLASH, 1246 AUTH_PASSWORD_VALIDATORS, 1282 AUTH_USER_MODEL, 1280 AUTHENTICATION_BACKENDS, 1280 CACHE_MIDDLEWARE_ALIAS, 1248 CACHE_MIDDLEWARE_KEY_PREFIX, 1248 CACHE_MIDDLEWARE_SECONDS, 1248 CACHES, 1246 CACHES-BACKEND, 1247 CACHES-KEY_FUNCTION, 1247 CACHES-KEY_PREFIX, 1247 CACHES-LOCATION, 1247

1840

CACHES-OPTIONS, 1248 CACHES-TIMEOUT, 1248 CACHES-VERSION, 1248 CONN_MAX_AGE, 1252 CSRF_COOKIE_AGE, 1249 CSRF_COOKIE_DOMAIN, 1249 CSRF_COOKIE_HTTPONLY, 1249 CSRF_COOKIE_NAME, 1249 CSRF_COOKIE_PATH, 1250 CSRF_COOKIE_SECURE, 1250 CSRF_FAILURE_VIEW, 1250 CSRF_HEADER_NAME, 1250 CSRF_TRUSTED_ORIGINS, 1251 CSRF_USE_SESSIONS, 1250 DATA_UPLOAD_MAX_MEMORY_SIZE, 1257 DATA_UPLOAD_MAX_NUMBER_FIELDS, 1258 DATABASE-ATOMIC_REQUESTS, 1251 DATABASE-AUTOCOMMIT, 1252 DATABASE-DISABLE_SERVER_SIDE_CURSORS, 1253 DATABASE-ENGINE, 1252 DATABASE-TEST, 1254 DATABASE-TIME_ZONE, 1253 DATABASE_ROUTERS, 1258 DATABASES, 1251 DATAFILE, 1256 DATAFILE_EXTSIZE, 1257 DATAFILE_MAXSIZE, 1256 DATAFILE_SIZE, 1257 DATAFILE_TMP, 1256 DATAFILE_TMP_EXTSIZE, 1257 DATAFILE_TMP_MAXSIZE, 1257 DATAFILE_TMP_SIZE, 1257 DATE_FORMAT, 1258 DATE_INPUT_FORMATS, 1258 DATETIME_FORMAT, 1259 DATETIME_INPUT_FORMATS, 1259 DEBUG, 1259 DEBUG_PROPAGATE_EXCEPTIONS, 1260 DECIMAL_SEPARATOR, 1260 DEFAULT_CHARSET, 1260 DEFAULT_CONTENT_TYPE, 1260 DEFAULT_EXCEPTION_REPORTER_FILTER, 1261 DEFAULT_FILE_STORAGE, 1261 DEFAULT_FROM_EMAIL, 1261 DEFAULT_INDEX_TABLESPACE, 1261 DEFAULT_TABLESPACE, 1261 DISALLOWED_USER_AGENTS, 1261 EMAIL_BACKEND, 1261 EMAIL_FILE_PATH, 1262 EMAIL_HOST, 1262 EMAIL_HOST_PASSWORD, 1262

Index

Django Documentation, Release 2.1.dev20171115023625

EMAIL_HOST_USER, 1262 EMAIL_PORT, 1262 EMAIL_SSL_CERTFILE, 1263 EMAIL_SSL_KEYFILE, 1263 EMAIL_SUBJECT_PREFIX, 1262 EMAIL_TIMEOUT, 1263 EMAIL_USE_LOCALTIME, 1262 EMAIL_USE_SSL, 1263 EMAIL_USE_TLS, 1263 FILE_CHARSET, 1263 FILE_UPLOAD_DIRECTORY_PERMISSIONS, 1264 FILE_UPLOAD_HANDLERS, 1263 FILE_UPLOAD_MAX_MEMORY_SIZE, 1264 FILE_UPLOAD_PERMISSIONS, 1264 FILE_UPLOAD_TEMP_DIR, 1264 FIRST_DAY_OF_WEEK, 1265 FIXTURE_DIRS, 1265 FORCE_SCRIPT_NAME, 1265 FORM_RENDERER, 1265 FORMAT_MODULE_PATH, 1265 GDAL_LIBRARY_PATH, 866 GEOIP_CITY, 868 GEOIP_COUNTRY, 868 GEOIP_PATH, 868 GEOS_LIBRARY_PATH, 840 HOST, 1252 IGNORABLE_404_URLS, 1266 INSTALLED_APPS, 1266 INTERNAL_IPS, 1267 LANGUAGE_CODE, 1267 LANGUAGE_COOKIE_AGE, 1267 LANGUAGE_COOKIE_DOMAIN, 1267 LANGUAGE_COOKIE_NAME, 1268 LANGUAGE_COOKIE_PATH, 1268 LANGUAGES, 1268 LOCALE_PATHS, 1268 LOGGING, 1269 LOGGING_CONFIG, 1269 LOGIN_REDIRECT_URL, 1281 LOGIN_URL, 1281 LOGOUT_REDIRECT_URL, 1281 MANAGERS, 1269 MEDIA_ROOT, 1269 MEDIA_URL, 1269 MESSAGE_LEVEL, 1282 MESSAGE_STORAGE, 1282 MESSAGE_TAGS, 1282 MIDDLEWARE, 1270 MIGRATION_MODULES, 1270 MONTH_DAY_FORMAT, 1270 NAME, 1252 NUMBER_GROUPING, 1271 OPTIONS, 1253

Index

PASSWORD, 1253 PASSWORD_HASHERS, 1281 PASSWORD_RESET_TIMEOUT_DAYS, 1281 PORT, 1253 POSTGIS_VERSION, 877 PREPEND_WWW, 1271 ROOT_URLCONF, 1271 SECRET_KEY, 1271 SECURE_BROWSER_XSS_FILTER, 1272 SECURE_CONTENT_TYPE_NOSNIFF, 1272 SECURE_HSTS_INCLUDE_SUBDOMAINS, 1272 SECURE_HSTS_PRELOAD, 1272 SECURE_HSTS_SECONDS, 1273 SECURE_PROXY_SSL_HEADER, 1273 SECURE_REDIRECT_EXEMPT, 1274 SECURE_SSL_HOST, 1274 SECURE_SSL_REDIRECT, 1274 SERIALIZATION_MODULES, 1274 SERVER_EMAIL, 1274 SESSION_CACHE_ALIAS, 1283 SESSION_COOKIE_AGE, 1283 SESSION_COOKIE_DOMAIN, 1283 SESSION_COOKIE_HTTPONLY, 1284 SESSION_COOKIE_NAME, 1284 SESSION_COOKIE_PATH, 1284 SESSION_COOKIE_SECURE, 1284 SESSION_ENGINE, 1284 SESSION_EXPIRE_AT_BROWSER_CLOSE, 1285 SESSION_FILE_PATH, 1285 SESSION_SAVE_EVERY_REQUEST, 1285 SESSION_SERIALIZER, 1285 SHORT_DATE_FORMAT, 1275 SHORT_DATETIME_FORMAT, 1275 SIGNING_BACKEND, 1275 SILENCED_SYSTEM_CHECKS, 1275 SITE_ID, 1285 STATIC_ROOT, 1286 STATIC_URL, 1286 STATICFILES_DIRS, 1286 STATICFILES_FINDERS, 1287 STATICFILES_STORAGE, 1287 TEMPLATES, 1275 TEMPLATES-APP_DIRS, 1276 TEMPLATES-BACKEND, 1276 TEMPLATES-DIRS, 1276 TEMPLATES-NAME, 1276 TEMPLATES-OPTIONS, 1276 TEST_CHARSET, 1254 TEST_COLLATION, 1254 TEST_CREATE, 1255 TEST_DEPENDENCIES, 1254 TEST_MIRROR, 1254

1841

Django Documentation, Release 2.1.dev20171115023625

TEST_NAME, 1255 TEST_NON_SERIALIZED_APPS, 1277 TEST_PASSWD, 1256 TEST_RUNNER, 1277 TEST_SERIALIZE, 1255 TEST_TBLSPACE, 1256 TEST_TBLSPACE_TMP, 1256 TEST_TEMPLATE, 1255 TEST_USER, 1255 TEST_USER_CREATE, 1255 THOUSAND_SEPARATOR, 1277 TIME_FORMAT, 1277 TIME_INPUT_FORMATS, 1277 TIME_ZONE, 1278 USE_I18N, 1278 USE_L10N, 1278 USE_THOUSAND_SEPARATOR, 1279 USE_TZ, 1279 USE_X_FORWARDED_HOST, 1279 USE_X_FORWARDED_PORT, 1279 USER, 1253 WSGI_APPLICATION, 1279 X_FRAME_OPTIONS, 1280 YEAR_MONTH_FORMAT, 1280 settings() (SimpleTestCase method), 343 setup() (in module django), 630 setup_databases() (DiscoverRunner method), 360 setup_databases() (in module django.test.utils), 360 setup_test_environment() (DiscoverRunner method), 359 setup_test_environment() (in module django.test.utils), 360 setUpTestData() (django.test.TestCase class method), 338 shell django-admin command, 989 shell (Polygon attribute), 851 shell command line option –command COMMAND, -c COMMAND, 989 –interface {ipython,bpython,python}, -i {ipython,bpython,python}, 989 –nostartup, 989 SHORT_DATE_FORMAT setting, 1275 SHORT_DATETIME_FORMAT setting, 1275 shortcuts, 205 shortcuts.get_current_site() (in module django.contrib.sites), 930 show_change_link (InlineModelAdmin attribute), 736 show_full_result_count (ModelAdmin attribute), 723 showmigrations django-admin command, 990 showmigrations command line option –database DATABASE, 990 –list, -l, 990

1842

–plan, -p, 990 sign() (TimestampSigner method), 433 Signal (class in django.dispatch), 527 Signer (class in django.core.signing), 432 SIGNING_BACKEND setting, 1275 SILENCED_SYSTEM_CHECKS setting, 1275 simple (GEOSGeometry attribute), 829 simple_tag() (django.template.Library method), 561 SimpleArrayField (class in django.contrib.postgres.forms), 904 SimpleTemplateResponse (class in django.template.response), 1362 SimpleTestCase (class in django.test), 337 simplify() (GEOSGeometry method), 831 site (HttpRequest attribute), 1231 site_header (AdminSite attribute), 742 SITE_ID setting, 1285 site_title (AdminSite attribute), 742 site_url (AdminSite attribute), 742 Sitemap (class in django.contrib.sitemaps), 918 size (ArrayField attribute), 891 size (FieldFile attribute), 1099 size (File attribute), 1006 size (SplitArrayField attribute), 905 size (UploadedFile attribute), 1010 size() (Storage method), 1010 skew (GDALRaster attribute), 859 skipIfDBFeature() (in module django.test), 352 skipUnlessDBFeature() (in module django.test), 352 slice template filter, 1339 slug, 1405 slug_field (django.views.generic.detail.SingleObjectMixin attribute), 665 slug_url_kwarg (django.views.generic.detail.SingleObjectMixin attribute), 665 SlugField (class in django.db.models), 1102 SlugField (class in django.forms), 1046 slugify template filter, 1339 slugify() (in module django.utils.text), 1386 SmallIntegerField (class in django.db.models), 1102 smart_bytes() (in module django.utils.encoding), 1378 smart_str() (in module django.utils.encoding), 1379 smart_text() (in module django.utils.encoding), 1378 SnapToGrid (class in django.contrib.gis.db.models.functions), 821 spaceless template tag, 1324 spatial_filter (Layer attribute), 843 spatial_index (BaseSpatialField attribute), 793

Index

Django Documentation, Release 2.1.dev20171115023625

SpatialReference (class in django.contrib.gis.gdal), 853 SplitArrayField (class in django.contrib.postgres.forms), 905 SplitDateTimeField (class in django.forms), 1049 SplitDateTimeWidget (class in django.forms), 1068 SplitHiddenDateTimeWidget (class in django.forms), 1068 sqlflush django-admin command, 990 sqlflush command line option –database DATABASE, 990 sqlmigrate django-admin command, 990 sqlmigrate command line option –backwards, 990 –database DATABASE, 990 sqlsequencereset django-admin command, 990 sqlsequencereset command line option –database DATABASE, 991 squashmigrations django-admin command, 991 squashmigrations command line option –no-optimize, 991 –noinput, –no-input, 991 –squashed-name SQUASHED_NAME, 991 srid (BaseSpatialField attribute), 792 srid (Field attribute), 801 srid (GDALRaster attribute), 858 srid (GEOSGeometry attribute), 829 srid (OGRGeometry attribute), 848 srid (SpatialReference attribute), 854 srid (WKBWriter attribute), 838 srs (GDALRaster attribute), 858 srs (GEOSGeometry attribute), 833 srs (Layer attribute), 843 srs (OGRGeometry attribute), 848 SRSException, 866 StackedInline (class in django.contrib.admin), 733 staff_member_required() (in module django.contrib.admin.views.decorators), 747 start_index() (Page method), 501 startapp django-admin command, 991 startapp command line option –extension EXTENSIONS, -e EXTENSIONS, 992 –name FILES, -n FILES, 992 –template TEMPLATE, 991 startproject django-admin command, 992 startproject command line option –extension EXTENSIONS, -e EXTENSIONS, 993 –name FILES, -n FILES, 993 –template TEMPLATE, 992

Index

startswith field lookup type, 1179 static template tag, 1345 static() (in module django.template.context_processors), 1357 static.serve() (in module django.views), 1394 static.static() (in module django.conf.urls), 1375 STATIC_ROOT setting, 1286 STATIC_URL setting, 1286 STATICFILES_DIRS setting, 1286 STATICFILES_FINDERS setting, 1287 STATICFILES_STORAGE setting, 1287 statistics() (GDALBand method), 861 status_code (HttpResponse attribute), 1237 status_code (Response attribute), 334 status_code (StreamingHttpResponse attribute), 1242 std (GDALBand attribute), 862 StdDev (class in django.db.models), 1187 Storage (class in django.core.files.storage), 1008 storage (FileField attribute), 1098 storage.base.BaseStorage (class in django.contrib.messages), 882 storage.base.Message (class in django.contrib.messages), 884 storage.CachedStaticFilesStorage (class in django.contrib.staticfiles), 935 storage.cookie.CookieStorage (class in django.contrib.messages), 881 storage.fallback.FallbackStorage (class in django.contrib.messages), 882 storage.ManifestStaticFilesStorage (class in django.contrib.staticfiles), 934 storage.session.SessionStorage (class in django.contrib.messages), 881 storage.StaticFilesStorage (class in django.contrib.staticfiles), 933 streaming (HttpResponse attribute), 1237 streaming (StreamingHttpResponse attribute), 1242 streaming_content (StreamingHttpResponse attribute), 1242 StreamingHttpResponse (class in django.http), 1241 strictly_above field lookup type, 811 strictly_below field lookup type, 811 StrIndex (class in django.db.models.functions), 1225 StringAgg (class in django.contrib.postgres.aggregates), 888

1843

Django Documentation, Release 2.1.dev20171115023625

stringfilter() (django.template.defaultfilters method), 558 stringformat template filter, 1339 strip (CharField attribute), 1039 strip (RegexField attribute), 1046 strip_tags() (in module django.utils.html), 1384 striptags template filter, 1339 style (BaseCommand attribute), 538 Subquery (class in django.db.models), 1199 Substr (class in django.db.models.functions), 1226 success_url (django.views.generic.edit.DeletionMixin attribute), 672 success_url (django.views.generic.edit.FormMixin attribute), 670 success_url (django.views.generic.edit.ModelFormMixin attribute), 671 suite_result() (DiscoverRunner method), 360 Sum (class in django.db.models), 1187 supports_3d (BaseGeometryWidget attribute), 802 supports_microseconds (Widget attribute), 1058 SuspiciousOperation, 1002 swappable (ForeignKey attribute), 1107 swappable (ManyToManyField attribute), 1110 sym_difference() (GEOSGeometry method), 832 sym_difference() (OGRGeometry method), 850 SymDifference (class in django.contrib.gis.db.models.functions), 821 symmetrical (ManyToManyField attribute), 1108 SyndicationFeed (class in django.utils.feedgenerator), 1380

T TabularInline (class in django.contrib.admin), 733 teardown_databases() (DiscoverRunner method), 360 teardown_databases() (in module django.test.utils), 360 teardown_test_environment() (DiscoverRunner method), 360 teardown_test_environment() (in module django.test.utils), 360 tell() (HttpResponse method), 1239 template, 1406 template (Aggregate attribute), 1197 Template (class in django.template), 1349 template (Func attribute), 1196 template (InlineModelAdmin attribute), 736 template (Window attribute), 1202 template filter add, 1328 addslashes, 1328 apnumber, 879 capfirst, 1328 center, 1328 1844

cut, 1328 date, 1329 default, 1330 default_if_none, 1330 dictsort, 1331 dictsortreversed, 1332 divisibleby, 1332 escape, 1332 escapejs, 1333 filesizeformat, 1333 first, 1333 floatformat, 1333 force_escape, 1334 get_digit, 1334 intcomma, 879 intword, 879 iriencode, 1334 join, 1335 language_bidi, 457 language_name, 457 language_name_local, 457 language_name_translated, 457 last, 1335 length, 1335 length_is, 1335 linebreaks, 1335 linebreaksbr, 1336 linenumbers, 1336 ljust, 1336 localize, 476 localtime, 481 lower, 1336 make_list, 1337 naturalday, 880 naturaltime, 880 ordinal, 880 phone2numeric, 1337 pluralize, 1337 pprint, 1338 random, 1338 rjust, 1338 safe, 1338 safeseq, 1338 slice, 1339 slugify, 1339 stringformat, 1339 striptags, 1339 time, 1340 timesince, 1340 timeuntil, 1340 timezone, 482 title, 1341 truncatechars, 1341 truncatechars_html, 1341

Index

Django Documentation, Release 2.1.dev20171115023625

truncatewords, 1341 truncatewords_html, 1342 unlocalize, 476 unordered_list, 1342 upper, 1342 urlencode, 1343 urlize, 1343 urlizetrunc, 1343 utc, 481 wordcount, 1344 wordwrap, 1344 yesno, 1344 template tag autoescape, 1309 block, 1310 blocktrans, 452 cache, 418 comment, 1310 csrf_token, 1310 cycle, 1310 debug, 1312 extends, 1312 filter, 1312 firstof, 1313 for, 1313 get_available_languages, 456 get_current_language, 456 get_current_language_bidi, 456 get_current_timezone, 481 get_flatpages, 765 get_language_info, 456 get_language_info_list, 456 get_media_prefix, 1346 get_static_prefix, 1346 if, 1315 ifchanged, 1318 include, 1319 language, 455 load, 1320 localize, 475 localtime, 480 lorem, 1320 now, 1321 regroup, 1321 resetcycle, 1324 spaceless, 1324 static, 1345 templatetag, 1325 timezone, 481 trans, 452 url, 1325 verbatim, 1326 widthratio, 1327 with, 1327

Index

template_engine (django.views.generic.base.TemplateResponseMixin attribute), 664 template_name (BaseGeometryWidget attribute), 802 template_name (django.views.generic.base.TemplateResponseMixin attribute), 664 template_name (Origin attribute), 1361 template_name (OSMWidget attribute), 803 template_name (SimpleTemplateResponse attribute), 1362 template_name_field (django.views.generic.detail.SingleObjectTemplateRes attribute), 666 template_name_suffix (django.views.generic.detail.SingleObjectTemplateRe attribute), 666 template_name_suffix (django.views.generic.edit.CreateView attribute), 651 template_name_suffix (django.views.generic.edit.DeleteView attribute), 653 template_name_suffix (django.views.generic.edit.UpdateView attribute), 652 template_name_suffix (django.views.generic.list.MultipleObjectTemplateRe attribute), 669 TemplateDoesNotExist, 273 TemplateResponse (class in django.template.response), 1363 TEMPLATES setting, 1275 templates (Response attribute), 334 TEMPLATES-APP_DIRS setting, 1276 TEMPLATES-BACKEND setting, 1276 TEMPLATES-DIRS setting, 1276 TEMPLATES-NAME setting, 1276 TEMPLATES-OPTIONS setting, 1276 TemplatesSetting (class in django.forms.renderers), 1054 TemplateSyntaxError, 273 templatetag template tag, 1325 TemplateView (built-in class), 677 templatize() (in module django.utils.translation), 1389 temporary_file_path() (TemporaryUploadedFile method), 1011 TemporaryFileUploadHandler (class in django.core.files.uploadhandler), 1011 TemporaryUploadedFile (class in django.core.files.uploadedfile), 1011 test django-admin command, 993 test command line option –debug-mode, 993 –debug-sql, -d, 994

1845

Django Documentation, Release 2.1.dev20171115023625

–exclude-tag EXCLUDE_TAGS, 994 –failfast, 993 –keepdb, -k, 993 –noinput, –no-input, 993 –parallel [N], 994 –reverse, -r, 993 –tag TAGS, 994 –testrunner TESTRUNNER, 993 test_capability() (Layer method), 844 TEST_CHARSET setting, 1254 TEST_COLLATION setting, 1254 test_cookie_worked() (backends.base.SessionBase method), 217 TEST_CREATE setting, 1255 TEST_DEPENDENCIES setting, 1254 test_func() (UserPassesTestMixin method), 370 test_loader (DiscoverRunner attribute), 359 TEST_MIRROR setting, 1254 TEST_NAME setting, 1255 TEST_NON_SERIALIZED_APPS setting, 1277 TEST_PASSWD setting, 1256 TEST_RUNNER setting, 1277 test_runner (DiscoverRunner attribute), 359 TEST_SERIALIZE setting, 1255 test_suite (DiscoverRunner attribute), 359 TEST_TBLSPACE setting, 1256 TEST_TBLSPACE_TMP setting, 1256 TEST_TEMPLATE setting, 1255 TEST_USER setting, 1255 TEST_USER_CREATE setting, 1255 TestCase (class in django.test), 338 testing.StaticLiveServerTestCase (class in django.contrib.staticfiles), 937 testserver django-admin command, 994 testserver command line option –addrport ADDRPORT, 995 –noinput, –no-input, 995 Textarea (class in django.forms), 1064

1846

TextField (class in django.db.models), 1103 TextInput (class in django.forms), 1061 THOUSAND_SEPARATOR setting, 1277 through (ManyToManyField attribute), 1108 through_fields (ManyToManyField attribute), 1109 time field lookup type, 1183 template filter, 1340 time_attrs (SplitDateTimeWidget attribute), 1068 TIME_FORMAT setting, 1277 time_format (SplitDateTimeWidget attribute), 1068 TIME_INPUT_FORMATS setting, 1277 TIME_ZONE setting, 1278 TimeField (class in django.db.models), 1103 TimeField (class in django.forms), 1046 TimeInput (class in django.forms), 1063 timesince template filter, 1340 TimestampSigner (class in django.core.signing), 433 timeuntil template filter, 1340 timezone template filter, 482 template tag, 481 title template filter, 1341 to_esri() (SpatialReference method), 854 to_field (ForeignKey attribute), 1107 to_field_name (ModelChoiceField attribute), 1050 to_field_name (ModelMultipleChoiceField attribute), 1052 to_locale() (in module django.utils.translation), 1389 to_python() (Field method), 1113 TodayArchiveView (built-in class), 689 TodayArchiveView (class in django.views.generic.dates), 661 total_error_count() (BaseFormSet method), 239 touches field lookup type, 808 touches() (GEOSGeometry method), 831 touches() (OGRGeometry method), 849 touches() (PreparedGeometry method), 836 trace() (Client method), 332 trans template tag, 452 TransactionManagementError, 1005 TransactionNow (class in django.contrib.postgres.functions), 907 TransactionTestCase (class in django.test), 338

Index

Django Documentation, Release 2.1.dev20171115023625

Transform (class in django.contrib.gis.db.models.functions), field lookup type, 909 821 UnaccentExtension (class in Transform (class in django.db.models), 1191 django.contrib.postgres.operations), 911 transform() (GDALRaster method), 860 unary_union (GEOSGeometry attribute), 832 transform() (GEOSGeometry method), 833 ungettext() (in module django.utils.translation), 1388 transform() (OGRGeometry method), 849 ungettext_lazy() (in module django.utils.translation), Translate (class in django.contrib.gis.db.models.functions), 1388 821 Union (class in django.contrib.gis.db.models), 814 translation string, 487 Union (class in django.contrib.gis.db.models.functions), trigram_similar 822 field lookup type, 908 union() (GEOSGeometry method), 832 TrigramDistance (class in union() (in module django.db.models.query.QuerySet), django.contrib.postgres.search), 914 1152 TrigramExtension (class in union() (OGRGeometry method), 850 django.contrib.postgres.operations), 910 unique (Field attribute), 1092 TrigramSimilarity (class in unique_for_date (Field attribute), 1093 django.contrib.postgres.search), 913 unique_for_month (Field attribute), 1093 trim (WKTWriter attribute), 839 unique_for_year (Field attribute), 1093 Trunc (class in django.db.models.functions), 1219 unique_together (Options attribute), 1128 truncatechars unit_attname() (django.contrib.gis.measure.Area class template filter, 1341 method), 824 truncatechars_html unit_attname() (django.contrib.gis.measure.Distance template filter, 1341 class method), 824 truncatewords units (SpatialReference attribute), 855 template filter, 1341 unlocalize truncatewords_html template filter, 476 template filter, 1342 unordered_list TruncDate (class in django.db.models.functions), 1222 template filter, 1342 TruncDay (class in django.db.models.functions), 1222 unpack_ipv4 (GenericIPAddressField attribute), 1045, TruncHour (class in django.db.models.functions), 1222, 1101 1223 UnreadablePostError, 1005 TruncMinute (class in django.db.models.functions), 1222, unsign() (TimestampSigner method), 433 1223 update() (Context method), 1353 TruncMonth (class in django.db.models.functions), 1221 update() (in module django.db.models.query.QuerySet), TruncQuarter (class in django.db.models.functions), 1221 1174 TruncSecond (class in django.db.models.functions), update() (QueryDict method), 1234 1222, 1223 update_or_create() (in module TruncTime (class in django.db.models.functions), 1222 django.db.models.query.QuerySet), 1168 TruncYear (class in django.db.models.functions), 1221 update_session_auth_hash() (in module tuple (Envelope attribute), 852 django.contrib.auth), 373 tuple (OGRGeometry attribute), 850 UpdateCacheMiddleware (class in type (Field attribute), 845 django.middleware.cache), 1075 type_name (Field attribute), 845 UpdateView (built-in class), 681 TypedChoiceField (class in django.forms), 1039 upload_complete() (FileUploadHandler method), 1012 TypedMultipleChoiceField (class in django.forms), 1045 upload_to (FileField attribute), 1097 tz() (in module django.template.context_processors), UploadedFile (class in django.core.files.uploadedfile), 1357 1010 upper U template filter, 1342 Upper (class in django.db.models.functions), 1226 ugettext() (in module django.utils.translation), 1388 ur (Envelope attribute), 852 ugettext_lazy() (in module django.utils.translation), 1388 uri_to_iri() (in module django.utils.encoding), 1379 ugettext_noop() (in module django.utils.translation), url 1388 template tag, 1325 unaccent Index

1847

Django Documentation, Release 2.1.dev20171115023625

url (django.views.generic.base.RedirectView attribute), 646 url (FieldFile attribute), 1099 url (HttpResponseRedirect attribute), 1239 url() (in module django.conf.urls), 1375 url() (Storage method), 1010 url_name (ResolverMatch attribute), 1372 urlconf (HttpRequest attribute), 1231 urlencode template filter, 1343 urlencode() (in module django.utils.http), 1384 urlencode() (QueryDict method), 1236 URLField (class in django.db.models), 1103 URLField (class in django.forms), 1047 URLInput (class in django.forms), 1062 urlize template filter, 1343 urlizetrunc template filter, 1343 urls definitive, 1400 urls.staticfiles_urlpatterns() (in module django.contrib.staticfiles), 936 urlsafe_base64_decode() (in module django.utils.http), 1385 urlsafe_base64_encode() (in module django.utils.http), 1385 URLValidator (class in django.core.validators), 1392 USE_I18N setting, 1278 USE_L10N setting, 1278 use_required_attribute (Form attribute), 1025 use_required_attribute() (Widget method), 1059 USE_THOUSAND_SEPARATOR setting, 1279 USE_TZ setting, 1279 USE_X_FORWARDED_HOST setting, 1279 USE_X_FORWARDED_PORT setting, 1279 USER setting, 1253 user (HttpRequest attribute), 1231 user (LogEntry attribute), 745 user_can_authenticate() (ModelBackend method), 754 user_can_authenticate() (RemoteUserBackend method), 754 user_logged_in() (in module django.contrib.auth.signals), 752 user_logged_out() (in module django.contrib.auth.signals), 753

1848

user_login_failed() (in module django.contrib.auth.signals), 753 user_passes_test() (in module django.contrib.auth.decorators), 369 user_permissions (models.User attribute), 748 UserAttributeSimilarityValidator (class in django.contrib.auth.password_validation), 391 UserChangeForm (class in django.contrib.auth.forms), 381 UserCreationForm (class in django.contrib.auth.forms), 381 username (models.User attribute), 748 USERNAME_FIELD (models.CustomUser attribute), 400 username_validator (models.User attribute), 749 UserPassesTestMixin (class in django.contrib.auth.mixins), 370 using() (in module django.db.models.query.QuerySet), 1164 utc template filter, 481 utc (in module django.utils.timezone), 1386 UUIDField (class in django.db.models), 1103 UUIDField (class in django.forms), 1047

V valid (GEOSGeometry attribute), 829 valid_reason (GEOSGeometry attribute), 829 validate() (SpatialReference method), 854 validate_comma_separated_integer_list (in module django.core.validators), 1393 validate_email (in module django.core.validators), 1392 validate_image_file_extension (in module django.core.validators), 1394 validate_ipv46_address (in module django.core.validators), 1392 validate_ipv4_address (in module django.core.validators), 1392 validate_ipv6_address (in module django.core.validators), 1392 validate_password() (in module django.contrib.auth.password_validation), 391 validate_slug (in module django.core.validators), 1392 validate_unicode_slug (in module django.core.validators), 1392 validate_unique() (Model method), 1134 ValidationError, 1004 validators (Field attribute), 1037, 1093 validators.ASCIIUsernameValidator (class in django.contrib.auth), 752 validators.UnicodeUsernameValidator (class in django.contrib.auth), 752 Index

Django Documentation, Release 2.1.dev20171115023625

Value (class in django.db.models), 1198 value (Field attribute), 845 value() (BoundField method), 1029 value_from_datadict() (Widget method), 1059 value_omitted_from_data() (Widget method), 1059 value_to_string() (Field method), 1113 ValueRange (class in django.db.models.expressions), 1203 values() (in module django.db.models.query.QuerySet), 1148 values() (QueryDict method), 1235 values_list() (in module django.db.models.query.QuerySet), 1150 Variance (class in django.db.models), 1187 vary_on_cookie() (in module django.views.decorators.vary), 201 vary_on_headers() (in module django.views.decorators.vary), 201 verbatim template tag, 1326 verbose_name (AppConfig attribute), 627 verbose_name (Field attribute), 1093 verbose_name (InlineModelAdmin attribute), 736 verbose_name (Options attribute), 1128 verbose_name_plural (InlineModelAdmin attribute), 736 verbose_name_plural (Options attribute), 1129 version django-admin command, 977 view, 1406 View (built-in class), 676 view_name (ResolverMatch attribute), 1372 view_on_site (ModelAdmin attribute), 723 ViewDoesNotExist, 1003 views.Feed (class in django.contrib.syndication), 942 views.index() (in module django.contrib.sitemaps), 921 views.serve() (in module django.contrib.staticfiles), 936 views.sitemap() (in module django.contrib.sitemaps), 917 views.SuccessMessageMixin (class in django.contrib.messages), 886 vsi_buffer (GDALRaster attribute), 861

W

WeekMixin (class in django.views.generic.dates), 674 When (class in django.db.models.expressions), 1209 whitelist (EmailValidator attribute), 1391 Widget (class in django.forms), 1058 widget (Field attribute), 1036 widget (MultiValueField attribute), 1049 widgets (MultiWidget attribute), 1060 width (Field attribute), 845 width (GDALBand attribute), 861 width (GDALRaster attribute), 857 width (ImageFile attribute), 1007 width_field (ImageField attribute), 1101 widthratio template tag, 1327 Window (class in django.db.models.expressions), 1202 window_compatible (Aggregate attribute), 1198 window_compatible (Expression attribute), 1205 with template tag, 1327 within field lookup type, 809 within() (GEOSGeometry method), 831 within() (OGRGeometry method), 849 within() (PreparedGeometry method), 836 wkb (GEOSGeometry attribute), 830 wkb (OGRGeometry attribute), 849 wkb_size (OGRGeometry attribute), 849 WKBReader (class in django.contrib.gis.geos), 837 WKBWriter (class in django.contrib.gis.geos), 837 wkt (Envelope attribute), 853 wkt (GEOSGeometry attribute), 830 wkt (OGRGeometry attribute), 849 wkt (SpatialReference attribute), 855 WKTReader (class in django.contrib.gis.geos), 837 WKTWriter (class in django.contrib.gis.geos), 839 wordcount template filter, 1344 wordwrap template filter, 1344 writable() (HttpResponse method), 1239 write() (HttpResponse method), 1239 write() (SyndicationFeed method), 1380 write() (WKBWriter method), 837 write() (WKTWriter method), 839 write_hex() (WKBWriter method), 838 writelines() (HttpResponse method), 1239 writeString() (SyndicationFeed method), 1380 WSGI_APPLICATION setting, 1279 wsgi_request (Response attribute), 334

W3CGeoFeed (class in django.contrib.gis.feeds), 876 Warning (class in django.core.checks), 632 warp() (GDALRaster method), 859 week field lookup type, 1182 week (WeekMixin attribute), 674 week_day field lookup type, 1182 week_format (WeekMixin attribute), 674 X WeekArchiveView (built-in class), 686 WeekArchiveView (class in django.views.generic.dates), x (LineString attribute), 851 658 x (Point attribute), 850 Index

1849

Django Documentation, Release 2.1.dev20171115023625

X_FRAME_OPTIONS setting, 1280 XFrameOptionsMiddleware (class django.middleware.clickjacking), 1080 xml suckiness of, 1401 xml (SpatialReference attribute), 855

in

Y y (LineString attribute), 851 y (Point attribute), 850 year field lookup type, 1181 year (YearMixin attribute), 672 year_format (YearMixin attribute), 672 YEAR_MONTH_FORMAT setting, 1280 YearArchiveView (built-in class), 684 YearArchiveView (class in django.views.generic.dates), 655 YearMixin (class in django.views.generic.dates), 672 years (SelectDateWidget attribute), 1068 yesno template filter, 1344

Z z (LineString attribute), 851 z (Point attribute), 851

1850

Index

(Video) Python Django Crash Course

Videos

1. Python Django Tutorial for Beginners
(Programming with Mosh)
2. Django E-commerce Product Filter Prototype
(Very Academy)
3. Django REST Framework - Build an API from Scratch
(Caleb Curry)
4. Django Blog Application - Full Tutorial 2022
(Code With Stein)
5. Django To Do List App With User Registration & Login
(Dennis Ivy)
6. Build a Django REST API with the Django Rest Framework. Complete Tutorial.
(CodingEntrepreneurs)
Top Articles
Latest Posts
Article information

Author: Tyson Zemlak

Last Updated: 07/16/2023

Views: 6305

Rating: 4.2 / 5 (43 voted)

Reviews: 90% of readers found this page helpful

Author information

Name: Tyson Zemlak

Birthday: 1992-03-17

Address: Apt. 662 96191 Quigley Dam, Kubview, MA 42013

Phone: +441678032891

Job: Community-Services Orchestrator

Hobby: Coffee roasting, Calligraphy, Metalworking, Fashion, Vehicle restoration, Shopping, Photography

Introduction: My name is Tyson Zemlak, I am a excited, light, sparkling, super, open, fair, magnificent person who loves writing and wants to share my knowledge and understanding with you.