Django 1.6 release notes¶
Observera
Tillägnad Malcolm Tredinnick
Den 17 mars 2013 förlorade Djangoprojektet och den fria programvarugemenskapen en mycket kär vän och utvecklare.
Malcolm var en långvarig bidragsgivare till Django, en föredömlig medlem av communityt, ett briljant sinne och en vän. Hans bidrag till Django - och till många andra projekt med öppen källkod - är nästan omöjliga att räkna upp. Många i Djangos kärnteam fick sina första patchar granskade av honom; hans mentorskap berikade oss. Hans omtanke, tålamod och hängivenhet kommer alltid att vara en inspiration för oss.
Denna version av Django är för Malcolm.
– Django-utvecklarna
6 november 2013
Välkommen till Django 1.6!
Dessa release notes täcker nya funktioner, samt några bakåtkompatibla ändringar som du bör vara medveten om när du uppgraderar från Django 1.5 eller äldre versioner. Vi har också tagit bort några funktioner, som beskrivs i vår utfasningsplan, och vi har börjat utfasningsprocessen för vissa funktioner.
Kompatibilitet med Python¶
Django 1.6, precis som Django 1.5, kräver Python 2.6.5 eller senare. Python 3 stöds också officiellt. Vi rekommenderar starkt den senaste mindre utgåvan för varje Python-serie som stöds (2.6.X, 2.7.X, 3.2.X och 3.3.X).
Django 1.6 kommer att vara den sista utgåvan som stöder Python 2.6; från och med Django 1.7 kommer den minsta Python-versionen som stöds att vara 2.7.
Python 3.4 stöds inte, men stöd kommer att läggas till i Django 1.7.
Vad är nytt i Django 1.6¶
Förenklade standardmallar för projekt och appar¶
De standardmallar som används av startproject
och startapp
har förenklats och moderniserats. Ramverket admin är nu aktiverat som standard i nya projekt; ramverket sites är det inte längre. Ramverket clickjacking prevention är nu aktiverat och databasen använder SQLite som standard.
Om standardmallarna inte passar din smak kan du använda :ref:``anpassade projekt- och appmallar <custom-app-and-project-templates>`.
Förbättrad transaktionshantering¶
Djangos transaktionshantering har setts över. Autocommit på databasnivå är nu aktiverat som standard. Detta gör transaktionshanteringen mer explicit och bör förbättra prestandan. De befintliga API:erna utrangerades och nya API:er infördes, enligt beskrivningen i transaktionshanteringsdokument.
Beständiga databasanslutningar¶
Django har nu stöd för att återanvända samma databasanslutning för flera förfrågningar. Detta undviker omkostnaderna för att återupprätta en anslutning i början av varje begäran. För bakåtkompatibilitet är den här funktionen inaktiverad som standard. Se Beständiga anslutningar för detaljer.
Upptäckt av tester i valfri testmodul¶
Django 1.6 levereras med en ny testlöpare som tillåter mer flexibilitet i placeringen av tester. Den tidigare löparen (django.test.simple.DjangoTestSuiteRunner
) hittade bara tester i modulerna models.py
och tests.py
i ett Python-paket i INSTALLED_APPS
.
Den nya löparen (django.test.runner.DiscoverRunner
) använder de testupptäcktsfunktioner som är inbyggda i unittest2
(versionen av unittest
i Python 2.7+ standardbiblioteket och levereras med Django). Med testupptäckt kan tester placeras i vilken modul som helst vars namn matchar mönstret test*.py
.
Dessutom måste de testetiketter som tillhandahålls till ./manage.py test
för att nominera specifika tester att köra nu vara fullständiga Python-punktade sökvägar (eller katalogsökvägar), snarare än applabel.TestCase.test_method_name
pseudosökvägar. Detta gör det möjligt att köra tester var som helst i din kodbas, snarare än bara i INSTALLED_APPS
. För mer information, se Testning i Django.
Denna ändring är bakåtkompatibel; se :ref:``backwards-incompatibility notes<new-test-runner>`.
Aggregering med hänsyn till tidszon¶
Stödet för tidszoner som infördes i Django 1.4 fungerade inte bra med QuerySet.dates()
: aggregering utfördes alltid i UTC. Denna begränsning upphävdes i Django 1.6. Använd QuerySet.datetimes()
för att utföra tidszonmedveten aggregering på en DateTimeField
.
Stöd för sparpunkter i SQLite¶
Django 1.6 lägger till stöd för sparpunkter i SQLite, med vissa begränsningar.
modellfältet BinaryField
¶
Ett nytt django.db.models.BinaryField
modellfält tillåter lagring av rå binär data i databasen.
Widgets för GeoDjango-formulär¶
GeoDjango tillhandahåller nu formfält och widgets för sina geospecialiserade fält. De är OpenLayers-baserade som standard, men de kan anpassas för att använda något annat JS-ramverk.
kommandot check
har lagts till för att verifiera kompatibilitet¶
Ett check
-hanteringskommando har lagts till, så att du kan kontrollera om din aktuella konfiguration (för närvarande inriktad på inställningar) är kompatibel med den aktuella versionen av Django.
Model.save()
algoritm ändrad¶
Metoden Model.save()
försöker nu att direkt UPDATE
databasen om instansen har ett primärnyckelvärde. Tidigare utfördes SELECT
för att avgöra om UPDATE
eller INSERT
behövdes. Den nya algoritmen behöver bara en fråga för att uppdatera en befintlig rad medan den gamla algoritmen behövde två. Se Model.save()
för mer information.
I vissa sällsynta fall rapporterar databasen inte att en matchande rad hittades när du gör en `` UPPDATERING``. Ett exempel är PostgreSQL ON UPDATE
trigger som returnerar NULL
. I sådana fall är det möjligt att ställa in django.db.models.Options.select_on_save
-flaggan för att tvinga sparandet att använda den gamla algoritmen.
Mindre funktioner¶
Autentiseringsbackends kan höja
PermissionDenied
för att omedelbart misslyckas med autentiseringskedjan.Flaggan
HttpOnly
kan ställas in på CSRF-cookien medCSRF_COOKIE_HTTPONLY
.assertQuerysetEqual()
kontrollerar nu för odefinierad ordning och ger upphov tillValueError
om odefinierad ordning upptäcks. Ordningen ses som odefinierad om den givnaQuerySet
inte är ordnad och det finns mer än ett ordnat värde att jämföra mot.Lagt till
earliest()
för symmetri medlatest()
.Förutom
year
,month
ochday
stöder ORM nu ävenhour
,minute
ochsecond
.Django omsluter nu alla PEP 249 undantag.
Standardwidgetarna för
EmailField
,URLField
,IntegerField
,FloatField
ochDecimalField
använder de nya typattributen som finns tillgängliga i HTML5 (type='email'
,type='url'
,type='number'
). Observera att på grund av oregelbundet stöd för inmatningstypennumber
med lokaliserade siffror i nuvarande webbläsare, använder Django den endast när numeriska fält inte är lokaliserade.Argumentet
number
för :ref:lazy plural translations <lazy-plural-translations>
kan anges vid översättningstidpunkten snarare än vid definitionstidpunkten.För anpassade hanteringskommandon: Verifiering av giltiga inställningar i kommandon som begär det med hjälp av det interna alternativet
BaseCommand.can_import_settings
utförs nu oberoende av hanteringen av den lokala inställningen som ska vara aktiv när kommandot körs. Det senare kan nu påverkas av det nya interna alternativetBaseCommand.leave_locale_alone
. Se Hanteringskommandon och lokala språk för mer information.success_url
iDeletionMixin
interpoleras nu med dessobjekts` ``__dict__
.HttpResponseRedirect
ochHttpResponsePermanentRedirect
tillhandahåller nu etturl
-attribut (motsvarande URL:en som svaret kommer att omdirigeras till).Cachebackend
MemcachedCache
använder nu det senastepickle
-protokollet som finns tillgängligt.Lagt till
SuccessMessageMixin
som tillhandahåller ettuccess_message
-attribut förFormView
-baserade klasser.Lagt till alternativen
django.db.models.ForeignKey.db_constraint
ochdjango.db.models.ManyToManyField.db_constraint
.Det jQuery-bibliotek som är inbäddat i admin har uppgraderats till version 1.9.1.
Syndikeringsflöden (
django.contrib.syndication
) kan nu skicka extra kontext till flödesmallar med hjälp av en nyFeed.get_context_data()
callback.Kolumnerna i adminlistan har en klass
column-<field_name>
i HTML så att kolumnrubriken kan stylas med CSS, t.ex. för att ange en kolumnbredd.isoleringsnivå kan anpassas under PostgreSQL.
Malltaggen
blocktrans
respekterar nuTEMPLATE_STRING_IF_INVALID
för variabler som inte finns i sammanhanget, precis som andra mallkonstruktioner.SimpleLazyObject
kommer nu att presentera mer användbara representationer i felsökningssituationer i skalet.Generic
GeometryField
är nu redigerbar med OpenLayers-widgeten i admin.Dokumentationen innehåller en checklista för distribution.
Kommandot
diffsettings
har fått ett alternativ--all
.django.forms.fields.Field.__init__
anropar nusuper()
, vilket gör det möjligt för fältmixins att implementera__init__()
-metoder som kommer att anropas på ett tillförlitligt sätt.Parametern
validate_max
lades till iBaseFormSet
ochformset_factory()
, ochModelForm
och inline-versioner av desamma. Valideringsbeteendet för formuläruppsättningar medmax_num
har förtydligats. Det tidigare odokumenterade beteendet som härdade formuläruppsättningar mot minnesutmattningsattacker dokumenterades, och den odokumenterade gränsen för det högsta av 1000 ellermax_num
formulär ändrades så att det alltid är 1000 mer änmax_num
.Lagt till
BCryptSHA256PasswordHasher
för att lösa problemet med trunkering av lösenord med bcrypt.Pillow är nu det föredragna bildmanipuleringsbiblioteket att använda med Django. PIL är i väntan på utfasning (stöd kommer att tas bort i Django 1.8). För att uppgradera bör du först avinstallera PIL och därefter installera Pillow.
ModelForm
accepterar flera nyaMeta
alternativ.Fält som ingår i listan
localized_fields
kommer att lokaliseras (genom att ställa inlocalize
på formulärfältet).Alternativen
labels
,help_texts
ocherror_messages
kan användas för att anpassa standardfälten, se Åsidosätta standardfälten för mer information.
Argumentet
choices
till modellfält accepterar nu en iterabel av iterabler i stället för att kräva en iterabel av listor eller tupler.Orsaksfrasen kan anpassas i HTTP-svar med hjälp av
reason_phrase
.När du anger webbadressen till nästa sida för
django.contrib.auth.views.logout()
,django.contrib.auth.views.password_reset()
,django.contrib.auth.views.password_reset_confirm()
ochdjango.contrib.auth.views.password_change()
kan du nu ange URL-namn och de kommer att lösas upp.Det nya alternativet
dumpdata --pks
anger primärnycklarna för de objekt som ska dumpas. Detta alternativ kan endast användas med en modell.Lagt till
QuerySet
metodernafirst()
ochlast()
som är bekvämlighetsmetoder som returnerar det första eller sista objektet som matchar filtren. ReturnerarNone
om det inte finns några objekt som matchar.View
ochRedirectView
stöder nu HTTP-metodenPATCH
.GenericForeignKey
tar nu ett valfrittfor_concrete_model
argument, som när det är inställt påFalse
tillåter fältet att referera till proxy-modeller. Standardvärdet ärTrue
för att behålla det gamla beteendet.Klassen:~django.middleware.locale.LocaleMiddleware lagrar nu det aktiva språket i sessionen om det inte redan finns där. Detta förhindrar förlust av språkinställningar efter sessionspolning, t.ex. utloggning.
SuspiciousOperation
har delats upp i ett antal underklasser, och var och en kommer att loggas till en matchande namngiven logger underdjango.security
loggningshierarkin. Tillsammans med denna förändring används enhandler400
mekanism och standardvy när enSuspiciousOperation
når WSGI-handlaren för att returnera enHttpResponseBadRequest
.Undantaget
DoesNotExist
innehåller nu ett meddelande som anger namnet på det attribut som används för uppslagningen.Metoden
get_or_create()
kräver inte längre minst ett nyckelordsargument.Klassen
SimpleTestCase
innehåller en ny assertion-hjälpare för att testa formulärfel:django.test.SimpleTestCase.assertFormsetError()
.Listan över relaterade fält som läggs till i en
QuerySet
avselect_related()
kan rensas medselect_related(None)
.Metoderna
get_extra()
ochget_max_num()
påInlineModelAdmin
kan åsidosättas för att anpassa det extra och maximala antalet inline-formulär.Formset har nu en
total_error_count()
-metod.ModelForm
-fält kan nu åsidosätta felmeddelanden som definieras i modellfält genom att användaerror_messages
-argumentet i enField
-konstruktör. För att dra nytta av den här nya funktionen med dina anpassade fält, :ref:se den uppdaterade rekommendationen <raising-validation-error>
för att skapa ettValidationError
.ModelAdmin
bevarar nu filter i listvyn efter att ett objekt har skapats, redigerats eller tagits bort. Det är möjligt att återställa det tidigare beteendet att rensa filter genom att ställa in attributetpreserve_filters
tillFalse
.Lagt till
FormMixin.get_prefix
(som returnerarFormMixin.prefix
som standard) för att möjliggöra anpassning avprefix
för formuläret.Råa frågor (
Manager.raw()
ellercursor.execute()
) kan nu använda parameterstilen ”pyformat”, där platshållare i frågan ges som'%(name)s'
och parametrarna skickas som en ordbok snarare än en lista (utom på SQLite). Detta har länge varit möjligt (men inte officiellt stöds) på MySQL och PostgreSQL, och är nu också tillgängligt på Oracle.Standardantalet iterationer för PBKDF2-lösenordshasher har ökats med 20%. Denna bakåtkompatibla ändring kommer inte att påverka befintliga lösenord eller användare som har underklassat
django.contrib.auth.hashers.PBKDF2PasswordHasher
för att ändra standardvärdet. Lösenord :ref:` kommer att uppgraderas <password-upgrades>` för att använda det nya iterationsantalet vid behov.
Bakåtkompatibla ändringar i 1.6¶
Varning
Utöver de ändringar som beskrivs i det här avsnittet bör du granska deprecation plan för alla funktioner som har tagits bort. Om du inte har uppdaterat din kod inom utfasningstiden för en viss funktion kan borttagningen av den framstå som en bakåtkompatibel ändring.
Ny modell för transaktionshantering¶
Förändringar i beteendet¶
Autocommit på databasnivå är aktiverat som standard i Django 1.6. Även om detta inte ändrar den allmänna andan i Djangos transaktionshantering, finns det några bakåtkompatibiliteter.
Sparpunkter och assertNumQueries
¶
Ändringarna i transaktionshanteringen kan resultera i ytterligare uttalanden för att skapa, frigöra eller rulla tillbaka sparpunkter. Det är mer troligt att detta händer med SQLite, eftersom det inte hade stöd för sparpunkter förrän i den här versionen.
Om tester som använder assertNumQueries()
misslyckas på grund av ett högre antal frågor än förväntat, kontrollera att de extra frågorna är relaterade till sparpunkter och justera det förväntade antalet frågor i enlighet med detta.
Alternativ för autocommit för PostgreSQL¶
I tidigare versioner var autocommit på databasnivå endast ett alternativ för PostgreSQL, och det inaktiverades som standard. Detta alternativ ignoreras nu och kan tas bort.
Ny testkörare¶
För att upprätthålla större överensstämmelse med Pythons unittest
-modul stöder den nya testköraren (django.test.runner.DiscoverRunner
) inte automatiskt vissa typer av tester som stöddes av den tidigare köraren:
Tester i filerna
models.py
ochtests/__init__.py
kommer inte längre att hittas och köras. Flytta dem till en fil vars namn börjar medtest
.Doctests kommer inte längre att upptäckas automatiskt. För att integrera doctests i din testsvit, följ rekommendationerna i Python-dokumentationen.
Django innehåller en modifierad version av doctest
-modulen från Pythons standardbibliotek (i django.test._doctest
) och innehåller några ytterligare doctest-verktyg. Dessa verktyg är föråldrade och kommer att tas bort i Django 1.8; doctest-sviter bör uppdateras för att fungera med standardbibliotekets doctest-modul (eller konverteras till unittest
-kompatibla tester).
Om du vill fördröja uppdateringar av din testsvit kan du ställa in din TEST_RUNNER
-inställning till django.test.simple.DjangoTestSuiteRunner
för att helt återställa det gamla testbeteendet. DjangoTestSuiteRunner
är föråldrad men kommer inte att tas bort från Django förrän version 1.8.
Borttagning av django.contrib.gis.tests.GeoDjangoTestSuiteRunner
GeoDjango anpassad testlöpare¶
Detta är för utvecklare som arbetar med själva GeoDjango-applikationen och relaterat till punkten ovan om ändringar i testlöparna:
Testlöparen django.contrib.gis.tests.GeoDjangoTestSuiteRunner
har tagits bort och den fristående GeoDjango-testkörningsinställningen som den implementerade stöds inte längre. För att köra GeoDjango-testerna använder du helt enkelt den nya DiscoverRunner
och anger appen django.contrib.gis
.
Anpassade användarmodeller i tester¶
Införandet av den nya testköraren har också något förändrat sättet som testmodeller importeras på. Som ett resultat måste alla tester som åsidosätter AUTH_USER_MODEL
för att testa beteende med en av Djangos testanvändarmodeller ( django.contrib.auth.tests.custom_user.CustomUser
och django.contrib.auth.tests.custom_user.ExtensionUser
) nu uttryckligen importera användarmodellen i din testmodul:
from django.contrib.auth.tests.custom_user import CustomUser
@override_settings(AUTH_USER_MODEL="auth.CustomUser")
class CustomUserFeatureTests(TestCase):
def test_something(self):
# Test code here
...
Denna import tvingar den anpassade användarmodellen att registreras. Utan denna import kommer testet inte att kunna byta in den anpassade användarmodellen och du kommer att få en felrapportering:
ImproperlyConfigured: AUTH_USER_MODEL refers to model 'auth.CustomUser' that has not been installed
Tidszonmedvetna uppslagningar av dag
, månad
och veckodag
¶
Django 1.6 introducerar stöd för tidszoner för day
, month
och week_day
när USE_TZ
är True
. Dessa uppslagningar utfördes tidigare i UTC oavsett aktuell tidszon.
Detta kräver tidszonsdefinitioner i databasen. Om du använder SQLite måste du installera pytz. Om du använder MySQL måste du installera pytz och ladda tidszontabellerna med mysql_tzinfo_to_sql.
Tillägg av QuerySet.datetimes()
¶
När time zone support som lades till i Django 1.4 var aktivt gav QuerySet.dates()
oväntade resultat, eftersom aggregeringen utfördes i UTC. För att åtgärda detta introducerar Django 1.6 ett nytt API, QuerySet.datetimes()
. Detta kräver några ändringar i din kod.
QuerySet.dates()
returnerar datum
-objekt¶
QuerySet.dates()
returnerar nu en lista med date
. Den brukade returnera en lista med datetime
.
QuerySet.datetimes()
returnerar en lista med datetime
.
QuerySet.dates()
inte längre användbar på DateTimeField
¶
QuerySet.dates()
ger upphov till ett fel om det används på DateTimeField
när tidszonsstöd är aktivt. Använd QuerySet.datetimes()
istället.
date_hierarchy
kräver definitioner av tidszoner¶
Funktionen date_hierarchy
i admin förlitar sig nu på QuerySet.datetimes()
när den används på en DateTimeField
.
Detta kräver tidszonsdefinitioner i databasen när USE_TZ
är True
. Learn more.
date_list
i generiska vyer kräver tidszonsdefinitioner¶
Av samma anledning kräver åtkomst till date_list
i samband med en datumbaserad generisk vy tidszonsdefinitioner i databasen när vyn är baserad på en DateTimeField
och USE_TZ
är True
. Learn more.
Nya uppslagsord kan krocka med modellfält¶
Django 1.6 introducerar hour
, minute
och second
lookups på DateTimeField
. Om du hade modellfält som heter hour
, minute
eller second
kommer de nya uppslagningarna att krocka med dina fältnamn. Lägg till en explicit exact
lookup om detta är ett problem.
BooleanField
har inte längre False
som standard¶
När en BooleanField
inte har en explicit default
, är det implicita standardvärdet None
. I tidigare versioner av Django var det False
, men det representerade inte exakt avsaknaden av ett värde.
Kod som förlitar sig på att standardvärdet är False
kan ge upphov till ett undantag när nya modellinstanser sparas i databasen, eftersom None
inte är ett acceptabelt värde för en BooleanField
. Du bör antingen ange default=False
i fältdefinitionen eller se till att fältet är inställt på True
eller False
innan du sparar objektet.
Översättningar och kommentarer i mallar¶
Extrahering av översättningar efter kommentarer¶
Extrahering av översättningsbara bokstäver från mallar med kommandot makemessages
upptäcker nu korrekt i18n-konstruktioner när de finns efter en kommentar av typen {#
/ #}
på samma rad. T.ex:
{# A comment #}{% trans "This literal was incorrectly ignored. Not anymore" %}
Plats för översättarens kommentarer¶
Kommentarer för översättare i mallar som anges med {#
/ #}
måste vara i slutet av en rad. Om de inte gör det ignoreras kommentarerna och makemessages
genererar en varning. Ett exempel:
{# Translators: This is ignored #}{% trans "Translate me" %}
{{ title }}{# Translators: Extracted and associated with 'Welcome' below #}
<h1>{% trans "Welcome" %}</h1>
Citat i reverse()
¶
Vid omvända webbadresser tillämpade Django inte django.utils.http.urlquote
på argument innan de interpolerades i URL-mönster. Denna bugg är åtgärdad i Django 1.6. Om du arbetade runt denna bugg genom att tillämpa URL-citering innan du skickar argument till reverse()
, kan detta resultera i dubbelcitering. Om detta händer, ta helt enkelt bort URL-citeringen från din kod. Du kommer också att behöva ersätta specialtecken i URL:er som används i assertRedirects()
med deras kodade versioner.
Lagring av IP-adresser i kommentarsappen¶
Kommentarsappen använder nu ett GenericIPAddressField
för att lagra kommentatorernas IP-adresser, för att stödja kommentarer som skickas från IPv6-adresser. Hittills har de lagrats i en ”IPAddressField”, som endast är avsedd att stödja IPv4. När du sparar en kommentar från en IPv6-adress skulle adressen trunkeras i tysthet i MySQL-databaser och ge upphov till ett undantag i Oracle. Du måste ändra kolumntypen i din databas för att dra nytta av den här ändringen.
För MySQL kör du den här frågan på projektets databas:
ALTER TABLE django_comments MODIFY ip_address VARCHAR(39);
För Oracle, kör den här frågan:
ALTER TABLE DJANGO_COMMENTS MODIFY (ip_address VARCHAR2(39));
Om du inte tillämpar den här ändringen är beteendet oförändrat: på MySQL trunkeras IPv6-adresser tyst; på Oracle genereras ett undantag. Ingen databasändring behövs för SQLite- eller PostgreSQL-databaser.
Procentenheter i cursor.execute
-frågor¶
När du kör råa SQL-frågor genom metoden cursor.execute har regeln om att dubbla procentlitteraler (%
) inuti frågan förenhetligats. Tidigare berodde beteendet på databasens backend. Nu, i alla backends, behöver du bara dubbla bokstavliga procenttecken om du också tillhandahåller ersättningsparametrar. Till exempel:
# No parameters, no percent doubling
cursor.execute("SELECT foo FROM bar WHERE baz = '30%'")
# Parameters passed, non-placeholders have to be doubled
cursor.execute("SELECT foo FROM bar WHERE baz = '30%%' and id = %s", [self.id])
SQLite
-användare måste kontrollera och uppdatera sådana frågor.
Hjälptext för modellformulärsfält för ManyToManyField-fält¶
HTML-rendering av modellformulärfält som motsvarar ManyToManyField
modellfält som används för att få den hårdkodade meningen:
Håll ned ”Control”, eller ”Command” på en Mac, för att välja mer än en.
(eller dess översättning till den aktiva språkdräkten) införs som den hjälptext som visas längs dem om varken attributen model
eller form
help_text
specificerades av användaren (eller om denna sträng bifogades till någon help_text
som tillhandahölls).
Eftersom detta skedde på modellagret fanns det inget sätt att förhindra att texten visades i fall där den inte var tillämplig, t.ex. formulärfält som implementerar användarinteraktioner som inte involverar ett tangentbord och/eller en mus.
Från och med Django 1.6, som en tillfällig bestämmelse om bakåtkompatibilitet, har logiken för att lägga till meningen ”Håll ner…” flyttats till fältlagret för modellformulär och ändrats för att lägga till texten endast när den associerade widgeten är SelectMultiple
eller valda underklasser.
Ändringen kan påverka dig på ett bakåtkompatibelt sätt om du använder anpassade modellformulärsfält och/eller widgetar för modellfält av typen ManyToManyField
vars användargränssnitt förlitar sig på automatisk tillhandahållande av den nämnda hårdkodade meningen. Dessa formulärfältimplementeringar måste anpassa sig till det nya scenariot genom att tillhandahålla sin egen hantering av attributet help_text
.
Program som använder Django model form faciliteter tillsammans med Django inbyggda formulär fields och widgets påverkas inte men måste vara medvetna om vad som beskrivs i Ändring av hjälptexten för modellformulärsfält för ManyToManyField-fält nedan.
QuerySet iteration¶
QuerySet
-iterationen ändrades så att alla hämtade rader omedelbart konverterades till Model
-objekt. I Django 1.5 och tidigare konverterades de hämtade raderna till Model
-objekt i bitar om 100.
Befintlig kod kommer att fungera, men antalet rader som konverteras till objekt kan ändras i vissa användningsfall. Sådana användningar inkluderar delvis loopning över en frågeuppsättning eller all användning som slutar med att göra __bool__
eller __contains__
.
I synnerhet hämtade de flesta databasbackends alla rader på en gång redan i 1.5.
Det är fortfarande möjligt att konvertera de hämtade raderna till Model
-objekt lättsamt genom att använda iterator()
-metoden.
BoundField.label_tag
inkluderar nu formulärets label_suffix
¶
Detta överensstämmer med hur metoder som Form.as_p
och Form.as_ul
återger etiketter.
Om du manuellt renderar label_tag
i dina mallar:
{{ form.my_field.label_tag }}: {{ form.my_field }}
vill du ta bort kolon (eller vilken annan separator du än använder) för att undvika att duplicera den när du uppgraderar till Django 1.6. Följande mall i Django 1.6 kommer att återges identiskt med ovanstående mall i Django 1.5, förutom att kolon kommer att visas inuti elementet <label>
.
{{ form.my_field.label_tag }} {{ form.my_field }}
kommer att rendera något liknande:
<label for="id_my_field">My Field:</label> <input id="id_my_field" type="text" name="my_field" />
Om du vill behålla det nuvarande beteendet att rendera label_tag
utan label_suffix
, instansiera formuläret label_suffix=''
. Du kan också anpassa label_suffix
per fält med hjälp av den nya parametern label_suffix
på label_tag()
.
GET-parameter för administratörsvyer _changelist_filters
¶
För att kunna bevara och återställa filter i listvyer skickar adminvyer nu runt GET-parametern _changelist_filters
. Det är viktigt att du tar hänsyn till den här ändringen om du har anpassade adminmallar eller om dina tester förlitar sig på de tidigare webbadresserna. Om du vill återgå till det ursprungliga beteendet kan du ställa in attributet preserve_filters
till False
.
django.contrib.auth
lösenordsåterställning använder bas 64-kodning av User
PK¶
Tidigare versioner av Django använde bas 36-kodning av primärnyckeln User
i vyerna och webbadresserna för återställning av lösenord (django.contrib.auth.views.password_reset_confirm()
). Base 36-kodning är tillräcklig om användarens primära nyckel är ett heltal, men med införandet av anpassade användarmodeller i Django 1.5 kanske detta antagande inte längre är sant.
django.contrib.auth.views.password_reset_confirm()
har ändrats för att ta en uidb64
parameter istället för uidb36
. Om du vänder på den här vyn, till exempel i en anpassad mall password_reset_email.html
, se till att uppdatera din kod.
En tillfällig shim för django.contrib.auth.views.password_reset_confirm()
som gör det möjligt för lösenordsåterställningslänkar som genererats före Django 1.6 att fortsätta fungera har lagts till för att ge bakåtkompatibilitet; detta kommer att tas bort i Django 1.7. Så länge som din webbplats har kört Django 1.6 i mer än PASSWORD_RESET_TIMEOUT_DAYS
kommer denna ändring inte att ha någon effekt. Om inte (till exempel om du uppgraderar direkt från Django 1.5 till Django 1.7), kommer alla länkar för återställning av lösenord som genereras innan du uppgraderar till Django 1.7 eller senare inte att fungera efter uppgraderingen.
Dessutom, om du har några anpassade URL:er för återställning av lösenord måste du uppdatera dem genom att ersätta uidb36
med uidb64
och bindestrecket som följer det mönstret med ett snedstreck. Lägg också till _\-
i listan över tecken som kan matcha mönstret uidb64
.
Till exempel:
url(
r"^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$",
"django.contrib.auth.views.password_reset_confirm",
name="password_reset_confirm",
),
blir:
url(
r"^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$",
"django.contrib.auth.views.password_reset_confirm",
name="password_reset_confirm",
),
Du kanske också vill lägga till shim för att stödja återställningslänkar i gammal stil. Med hjälp av exemplet ovan skulle du ändra den befintliga webbadressen genom att ersätta django.contrib.auth.views.password_reset_confirm
med django.contrib.auth.views.password_reset_confirm_uidb36
och även ta bort argumentet name
så att det inte står i konflikt med den nya webbadressen:
url(
r"^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$",
"django.contrib.auth.views.password_reset_confirm_uidb36",
),
Du kan ta bort detta URL-mönster efter att din app har distribuerats med Django 1.6 för PASSWORD_RESET_TIMEOUT_DAYS
.
Standard serialisering av sessioner ändras till JSON¶
Historiskt sett har django.contrib.sessions
använt pickle
för att serialisera sessionsdata innan de lagras i backend. Om du använder signed cookie session backend och SECRET_KEY
är känd av en angripare (det finns inte en inneboende sårbarhet i Django som skulle göra att den läcker), kan angriparen infoga en sträng i sessionen som, när den avplockas, exekverar godtycklig kod på servern. Tekniken för att göra detta är enkel och lätt tillgänglig på internet. Även om cookie-sessionslagringen signerar de cookie-lagrade data för att förhindra manipulering, eskalerar en SECRET_KEY
-läcka omedelbart till en sårbarhet för fjärrkörning av kod.
Denna attack kan motverkas genom att serialisera sessionsdata med JSON istället för pickle
. För att underlätta detta introducerade Django 1.5.3 en ny inställning, SESSION_SERIALIZER
, för att anpassa sessionens serialiseringsformat. För bakåtkompatibilitet var standardinställningen att använda pickle
i Django 1.5.3, men vi har ändrat standardinställningen till JSON i 1.6. Om du uppgraderar och byter från pickle till JSON kommer sessioner som skapats före uppgraderingen att gå förlorade. Även om JSON-serialisering inte stöder alla Python-objekt som pickle
gör, rekommenderar vi starkt att du använder JSON-serialiserade sessioner. Var uppmärksam på följande när du kontrollerar din kod för att avgöra om JSON-serialisering fungerar för din applikation:
JSON kräver strängnycklar, så du kommer sannolikt att stöta på problem om du använder nycklar som inte är strängar i
request.session
.Att ställa in sessionens utgång genom att skicka
datetime
-värden tillset_expiry()
kommer inte att fungera eftersomdatetime
-värden inte är serialiserbara i JSON. Du kan använda heltalsvärden istället.
Se Serialisering av session-dokumentationen för mer information.
Ändringar i Object Relational Mapper¶
Django 1.6 innehåller många förändringar av ORM. Dessa förändringar faller mestadels i tre kategorier:
Buggfixar (t.ex. korrekta join-klausuler för generiska relationer, query combining, join promotion och join trimming)
Förberedelse för nya funktioner. Till exempel är ORM nu internt redo för utländska nycklar i flera kolumner.
Allmän uppstädning.
Dessa ändringar kan leda till vissa kompatibilitetsproblem. Till exempel kommer vissa frågor nu att generera olika tabellaliaser. Detta kan påverka QuerySet.extra()
. Dessutom kommer vissa frågor nu att producera olika resultat. Ett exempel är exclude(condition)
där villkoret är komplext (refererar till multijoins inuti Q objects
). I många fall gav de berörda frågorna inte korrekta resultat i Django 1.5 men gör det nu. Tyvärr finns det också fall som ger olika resultat, men varken Django 1.5 eller 1.6 ger korrekta resultat.
Slutligen har det gjorts många ändringar i ORM:s interna API:er.
Diverse¶
django.db.models.query.EmptyQuerySet
kan inte instansieras längre - den är endast användbar som en markörklass för att kontrollera omnone()
har anropats:isinstance(qs.none(), EmptyQuerySet)
Om din CSS/JavaScript-kod används för att komma åt HTML-inmatningswidgets efter typ, bör du se över den eftersom
type='text'
-widgets nu kan matas ut somtype='email'
,type='url'
ellertype='number'
beroende på deras motsvarande fälttyp.Formulärfältens
error_messages
som innehåller en platshållare ska nu alltid använda en namngiven platshållare ("Värdet '%(value)s' är för stort"
istället för"Värdet '%s' är för stort"
). Se dokumentationen för motsvarande fält för mer information om namnen på platshållarna. Ändringarna i 1.6 påverkar särskiltDecimalField
ochModelMultipleChoiceField
.Vissa
error_messages
förIntegerField
,EmailField
,IPAddressField
,GenericIPAddressField
ochSlugField
har undertryckts eftersom de duplicerade felmeddelanden som redan tillhandahålls av validerare knutna till fälten.På grund av en förändring i arbetsflödet för formulärvalidering bör metoden
TypedChoiceField
coerce
alltid returnera ett värde som finns i fältattributetchoices
. Denna begränsning bör lyftas igen i Django 1.7.Det har skett förändringar i hur timeouts hanteras i cache-backends. Att explicit skicka in
timeout=None
resulterar inte längre i att standardtimeouten används. Det kommer nu att ställa in en timeout som inte löper ut. Om 0 anges i memcache-backend används inte längre standardtimeouten, utan värdet kommer nu att ställas in och upphöra omedelbart.Appen
django.contrib.flatpages
brukade ställa in anpassade HTTP-rubriker för felsökningsändamål. Denna funktionalitet var inte dokumenterad och gjorde cachelagring ineffektiv så den har tagits bort, tillsammans med dess generiska implementering, tidigare tillgänglig idjango.core.xheaders
.XViewMiddleware
har flyttats fråndjango.middleware.doc
tilldjango.contrib.admindocs.middleware
eftersom det är en implementationsdetalj av admindocs, som visat sig inte vara återanvändbar i allmänhet.GenericIPAddressField
tillåter nu endastblank
-värden omnull
-värden också är tillåtna. Att skapa enGenericIPAddressField
därblank
är tillåtet mennull
inte är det kommer att utlösa ett modellvalideringsfel eftersomblank
-värden alltid lagras somnull
. Tidigare kunde lagring av ettblank
-värde i ett fält som inte tillätnull
orsaka ett databasundantag vid körning.Om ett
NoReverseMatch
-undantag uppstår från en metod vid rendering av en mall, tystas det inte. Till exempel kommer{{ obj.view_href }}
att orsaka att mallrenderingen misslyckas omview_href()
ger upphov tillNoReverseMatch
. Det finns ingen förändring av{% url %}
taggen, den orsakar mallrendering att misslyckas som alltid närNoReverseMatch
är upphöjd.django.test.Client.logout()
anropar nudjango.contrib.auth.logout()
som skickar signalenuser_logged_out()
.Authentication views är nu omvända efter namn, inte deras platser i
django.contrib.auth.views
. Om du använder vyerna utan ettnamn
bör du uppdatera dinaurlpatterns
för att användadjango.conf.urls.url()
med parameternnamn
. Till exempel:(r"^reset/done/$", "django.contrib.auth.views.password_reset_complete")
blir:
url( r"^reset/done/$", "django.contrib.auth.views.password_reset_complete", name="password_reset_complete", )
RedirectView
har nu ettpattern_name
-attribut som gör det möjligt att välja mål genom att vända på URL:en.I Django 1.4 och 1.5 ansågs en tom sträng oavsiktligt inte vara ett giltigt lösenord. Detta innebar att
set_password()
skulle spara ett tomt lösenord som ett oanvändbart lösenord somset_unusable_password()
gör, och därmedcheck_password()
alltid returneradeFalse
för tomma lösenord. Detta har korrigerats i denna utgåva: tomma lösenord är nu giltiga.Admin
changelist_view
accepterade tidigare enpop
GET-parameter för att ange att den skulle visas i en popup. Denna parameter har bytt namn till_popup
för att vara konsekvent med resten av admin-vyerna. Du bör uppdatera dina anpassade mallar om de använder det tidigare parameternamnet.validate_email()
accepterar nu e-postadresser medlocalhost
som domän.Det nya alternativet
makemessages --keep-pot
förhindrar att den temporära filen.pot
som genereras innan filen.po
skapas raderas.Den odokumenterade
django.core.servers.basehttp.WSGIServerException
har tagits bort. Använd`socket.error
som tillhandahålls av standardbiblioteket istället. Denna ändring släpptes också i Django 1.5.5.Signaturen för
django.views.generic.base.RedirectView.get_redirect_url()
har ändrats och accepterar nu även positionella argument (*args, **kwargs
). Alla icke namngivna fångade grupper kommer nu att skickas tillget_redirect_url()
vilket kan resultera i ettTypeError
om du inte uppdaterar signaturen för din anpassade metod.
Funktioner som inte längre är aktuella i 1.6¶
API:er för transaktionshantering¶
Transaktionshanteringen reviderades helt i Django 1.6 och de nuvarande API:erna är föråldrade:
django.middleware.transaction.TransactionMiddleware
django.db.transaction.autocommit
django.db.transaction.commit_on_success
django.db.transaction.commit_manually
inställningen
TRANSACTIONS_MANAGED
django.contrib.comments
¶
Djangos ramverk för kommentarer har utgått och stöds inte längre. Det kommer att finnas tillgängligt i Django 1.6 och 1.7, och tas bort i Django 1.8. De flesta användare kommer att vara bättre betjänta av en anpassad lösning eller en värdprodukt som Disqus.
Koden som tidigare var känd som django.contrib.comments
är fortfarande tillgänglig i ett externt arkiv.
Stöd för PostgreSQL-versioner äldre än 8.4¶
Slutet på uppströms stödperioder nåddes i december 2011 för PostgreSQL 8.2 och i februari 2013 för 8.3. Som en följd av detta ställer Django 1.6 8.4 som den minsta PostgreSQL-versionen som den officiellt stöder.
Du uppmuntras starkt att använda den senaste versionen av PostgreSQL som finns tillgänglig på grund av prestandaförbättringar och för att dra nytta av den inbyggda streamingreplikeringen som finns i PostgreSQL 9.x.
Ändringar av cycle
och firstof
¶
Mallsystemet escapar i allmänhet alla variabler för att undvika XSS-attacker. På grund av en historisk olyckshändelse återger dock taggarna cycle
och firstof
sina argument som de är.
Django 1.6 startar en process för att korrigera denna inkonsekvens. Mallbiblioteket future
tillhandahåller alternativa implementationer av cycle
och firstof
som autoescape sina inmatningar. Om du använder dessa taggar, uppmuntras du att inkludera följande rad längst upp i dina mallar för att aktivera det nya beteendet:
{% load cycle from future %}
eller:
{% load firstof from future %}
De taggar som implementerar det gamla beteendet har utgått och i Django 1.8 kommer det gamla beteendet att ersättas med det nya beteendet. För att säkerställa kompatibilitet med framtida versioner av Django bör befintliga mallar ändras för att använda future
-versionerna.
Om det behövs kan du tillfälligt inaktivera auto-escaping med mark_safe()
eller {% autoescape off %}
.
CACHE_MIDDLEWARE_ANONYMOUS_ONLY
inställning¶
CacheMiddleware
och UpdateCacheMiddleware
brukade tillhandahålla ett sätt att cacha förfrågningar endast om de inte gjordes av en inloggad användare. Denna mekanism var i stort sett ineffektiv eftersom mellanvaran korrekt tar hänsyn till Vary: Cookie
HTTP header, och denna header ställs in vid en mängd olika tillfällen, t.ex:
komma åt sessionen, eller
med hjälp av CSRF-skydd, som är aktiverat som standard, eller
använder ett bibliotek på klientsidan som ställer in cookies, som Google Analytics.
Detta gör att cachen fungerar effektivt per session oavsett inställningen CACHE_MIDDLEWARE_ANONYMOUS_ONLY
.
inställning för SEND_BROKEN_LINK_EMAILS
¶
CommonMiddleware
används för att tillhandahålla grundläggande rapportering av brutna länkar via e-post när SEND_BROKEN_LINK_EMAILS
är inställt på True
.
På grund av svårlösta ordningsproblem mellan CommonMiddleware
och LocaleMiddleware
, delades denna funktion upp i en ny middleware: BrokenLinkEmailsMiddleware
.
Om du förlitar dig på den här funktionen bör du lägga till 'django.middleware.common.BrokenLinkEmailsMiddleware'
till din MIDDLEWARE_CLASSES
-inställning och ta bort SEND_BROKEN_LINK_EMAILS
från dina inställningar.
_has_changed
metod för widgets¶
Om du har definierat dina egna formulärwidgetar och definierat metoden _has_changed
för en widget, bör du nu definiera denna metod för själva formulärfältet.
modul_namn
modell _meta attribut¶
Model._meta.module_name
döptes om till model_name
. Trots att det är ett privat API kommer det att gå igenom en vanlig deprecation-väg.
get_(add|change|delete)_permission
modell _meta metoder¶
metoderna Model._meta.get_(add|change|delete)_permission
utrangerades. Även om de inte var en del av det offentliga API:et kommer de också att gå igenom en vanlig deprecation-väg. Du kan ersätta dem med django.contrib.auth.get_permission_codename('action', Model._meta)
där 'action'
är 'add'
, 'change'
eller 'delete'
.
get_query_set
och liknande metoder byter namn till get_queryset
¶
Metoder som returnerar en QuerySet
såsom Manager.get_query_set
eller ModelAdmin.queryset
har bytt namn till get_queryset
.
Om du skriver ett bibliotek som implementerar till exempel en metod Manager.get_query_set
och du behöver stödja gamla Django-versioner, bör du byta namn på metoden och villkorligt lägga till ett alias med det gamla namnet:
class CustomManager(models.Manager):
def get_queryset(self):
pass # ...
if django.VERSION < (1, 6):
get_query_set = get_queryset
# For Django >= 1.6, models.Manager provides a get_query_set fallback
# that emits a warning when used.
Om du skriver ett bibliotek som behöver anropa metoden get_queryset
och måste stödja gamla Django-versioner, bör du skriva:
get_queryset = (
some_manager.get_query_set
if hasattr(some_manager, "get_query_set")
else some_manager.get_queryset
)
return get_queryset() # etc
I det allmänna fallet med en anpassad manager som både implementerar sin egen metod get_queryset
och anropar den metoden, och behöver arbeta med äldre Django-versioner och bibliotek som inte har uppdaterats ännu, är det användbart att definiera en get_queryset_compat
-metod enligt nedan och använda den internt i din 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()
Detta hjälper till att minimera de ändringar som behövs, men fungerar också korrekt när det gäller underklasser (t.ex. RelatedManagers
från Django 1.5) som kan åsidosätta antingen get_query_set
eller get_queryset
.
vyn shortcut
och URLconf¶
Vyn shortcut
flyttades från django.views.defaults
till django.contrib.contenttypes.views
strax efter 1.0-utgåvan, men den gamla platsen blev aldrig föråldrad. Detta förbiseende korrigerades i Django 1.6 och du bör nu använda den nya platsen.
URLconf django.conf.urls.shortcut
var också föråldrad. Om du inkluderar den i en URLconf, ersätt helt enkelt:
(r"^prefix/", include("django.conf.urls.shortcut")),
med:
(
r"^prefix/(?P<content_type_id>\d+)/(?P<object_id>.*)/$",
"django.contrib.contenttypes.views.shortcut",
),
ModelForm
utan fields
eller exclude
¶
Tidigare, om du ville att en ModelForm
skulle använda alla fält i modellen, kunde du helt enkelt utelämna attributet Meta.fields
, och alla fält skulle användas.
Detta kan leda till säkerhetsproblem där fält läggs till i modellen och oavsiktligt automatiskt blir redigerbara för slutanvändare. I vissa fall, särskilt med booleska fält, är det möjligt att detta problem är helt osynligt. Detta är en form av Mass assignment vulnerability.
Av denna anledning är detta beteende föråldrat och det är starkt avrått från att använda alternativet Meta.exclude
. Istället bör alla fält som är avsedda att ingå i formuläret listas explicit i attributet fields
.
Om detta säkerhetsproblem verkligen inte gäller i ditt fall finns det en genväg för att uttryckligen ange att alla fält ska användas - använd specialvärdet "__all__"
för fields-attributet:
class MyModelForm(ModelForm):
class Meta:
fields = "__all__"
model = MyModel
Om du har anpassade ModelForms
som bara behöver användas i admin, finns det ett annat alternativ. Administratören har sina egna metoder för att definiera fält (fieldsets
etc.), och därför är det överflödigt att lägga till en lista över fält till ModelForm
. Istället kan man helt enkelt utelämna den inre klassen Meta
i ModelForm
, eller utelämna attributet Meta.model
. Eftersom underklassen ModelAdmin
vet vilken modell den är för, kan den lägga till de nödvändiga attributen för att härleda en fungerande ModelForm
. Detta beteende fungerar även för tidigare Django-versioner.
UpdateView
och CreateView
utan explicita fält¶
De generiska vyerna CreateView
och UpdateView
, och allt annat som härrör från ModelFormMixin
, är sårbara för det säkerhetsproblem som beskrivs i avsnittet ovan, eftersom de automatiskt kan skapa en ModelForm
som använder alla fält för en modell.
Av denna anledning, om du använder dessa vyer för att redigera modeller, måste du också tillhandahålla attributet fields
(nytt i Django 1.6), som är en lista över modellfält och fungerar på samma sätt som attributet ModelForm
Meta.fields
. Alternativt kan du ställa in attributet form_class
till en ModelForm
som uttryckligen definierar de fält som ska användas. Att definiera en subklass av UpdateView
eller CreateView
som ska användas med en modell men utan en explicit lista över fält är föråldrat.
Ändring av hjälptexten för modellformulärsfält för ManyToManyField
-fält¶
All speciell hantering av attributet help_text
för modellfälten ManyToManyField
som utförs av standardmodell- eller modellformulärfält enligt beskrivningen i Hjälptext för modellformulärsfält för ManyToManyField-fält ovan är föråldrad och kommer att tas bort i Django 1.8.
Hjälptexten i dessa fält måste hanteras antingen av applikationer, anpassade formulärfält eller widgets, precis som med resten av modellfälttyperna.