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.
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.
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.
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.
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:
ready() method of their configuration.models.py. You don’t have to set
app_label explicitly any more.models.py entirely if an application doesn’t
have any models.label
attribute of application configurations, to work around label conflicts.verbose_name of application configurations.autodiscover()
when Django starts. You can consequently remove this line from your
URLconf.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 modelpath: A dotted, Python path to the class of this field, including the class name.args: Positional arguments, as a listkwargs: Keyword arguments, as a dictThese 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.
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.
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:
QuerySet and its custom methods were lost after the first
call to values() or values_list().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()
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() # Default Manager
entries = EntryManager() # Custom Manager
b = Blog.objects.get(id=1)
b.entry_set(manager='entries').all()
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.
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.
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()
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.
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.
Form error handling¶Form.add_error()¶Previously there were two main patterns for handling errors in forms:
ValidationError from within certain
functions (e.g. Field.clean(), Form.clean_<fieldname>(), or
Form.clean() for non-field errors.)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().
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.
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.
django.contrib.admin¶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!django.contrib.admin now use the border-radius CSS
property for rounded corners rather than GIF background images.app-<app_name> and model-<model_name>
classes in their <body> tag to allow customizing the CSS per app or per
model.field-<field_name> class in the
HTML to enable style customizations.django.contrib.admin.ModelAdmin.get_search_fields() method.ModelAdmin.get_fields() method may be overridden to
customize the value of ModelAdmin.fields.admin.site.register syntax, you can use the
new register() decorator to register a
ModelAdmin.ModelAdmin.list_display_links = None to disable
links on the change list page grid.ModelAdmin.view_on_site to control whether or not to
display the 《View on site》 link.ModelAdmin.list_display value by prefixing the
admin_order_field value with a hyphen.ModelAdmin.get_changeform_initial_data() method may be
overridden to define custom behavior for setting initial change form data.django.contrib.auth¶**kwargs passed to
email_user() are passed to the
underlying send_mail() call.permission_required() decorator can
take a list of permissions as well as a single permission.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.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 패스워드 변경시 세션 무효화 for more details.django.contrib.formtools¶WizardView.done() now include a form_dict to allow easier
access to forms by their step name.django.contrib.gis¶crosses, disjoint,
overlaps, touches and within predicates, if GEOS 3.3 or later is
installed.django.contrib.messages¶django.contrib.messages that use cookies, will now
follow the SESSION_COOKIE_SECURE and
SESSION_COOKIE_HTTPONLY settings.DEFAULT_MESSAGE_LEVELS.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¶"django.contrib.sessions.backends.cached_db" session backend now
respects SESSION_CACHE_ALIAS. In previous versions, it always used
the default cache.django.contrib.sitemaps¶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¶django.contrib.sites.middleware.CurrentSiteMiddleware allows
setting the current site on each request.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¶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).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.django.core.cache.caches now yields
different instances per thread.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.CSRF_COOKIE_AGE setting facilitates the use of session-based
CSRF cookies.send_mail() now accepts an html_message
parameter for sending a multipart text/plain and
text/html email.EmailBackend now accepts a
timeout parameter.UploadedFile.content_type_extra attribute
contains extra parameters passed to the content-type header on a file
upload.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.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.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.<label> and <input> 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.<textarea> 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.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.TypedChoiceField coerce method return an arbitrary
value.SelectDateWidget.months can be used to
customize the wording of the months displayed in the select widget.min_num and validate_min parameters were added to
formset_factory() to allow validating
a minimum number of submitted forms.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.Form when subclassing by
setting the name to None.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.django.middleware.locale.LocaleMiddleware.response_redirect_class
attribute allows you to customize the redirects issued by the middleware.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.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.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.makemessages command now always adds the --previous
command line flag to the msgmerge command, keeping previously translated
strings in po files for fuzzy strings.LANGUAGE_COOKIE_AGE, LANGUAGE_COOKIE_DOMAIN
and LANGUAGE_COOKIE_PATH.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:
compilemessages.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).
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.
QuerySet.update_or_create() method was added.default_permissions model
Meta option allows you to customize (or disable) creation of the default
add, change, and delete permissions.OneToOneField for
다중 테이블 상속 are now discovered in abstract classes.OneToOneField by setting its
related_name to
'+' or ending it with '+'.F expressions support the power operator
(**).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.None as a query value for the iexact
lookup.limit_choices_to when defining a
ForeignKey or ManyToManyField.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).index_together
(rather than a list of lists) when specifying a single set of fields.ManyToManyField.through_fields
argument.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.order_by()
a relation _id field by using its attribute name.enter argument was added to the
setting_changed signal.str of the
'app_label.ModelName' form – just like related fields – to lazily
reference their senders.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.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).widthratio template tag now accepts an "as" parameter to
capture the result in a variable.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.include templates recursively.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.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()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.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.truncatechars_html filter truncates a string to be no
longer than the specified number of characters, taking HTML into account.HttpRequest.scheme attribute
specifies the scheme of the request (http or https normally).redirect() now supports
relative URLs.JsonResponse subclass of
HttpResponse helps easily create JSON-encoded responses.DiscoverRunner has two new attributes,
test_suite and
test_runner, which facilitate
overriding the way tests are collected and run.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.assertRedirects().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.WSGIRequest instance generated by the test handler is now attached to
the django.test.Response.wsgi_request attribute.TEST.strip_tags() accuracy (but it still cannot
guarantee an HTML-safe result, as stated in the documentation).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 example@[2001:db8::1], as specified in RFC 5321.경고
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.
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.
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