Django 4.2 release notes¶
3 april 2023
Välkommen till Django 4.2!
Dessa release notes täcker nya funktioner, samt några bakåtkompatibla ändringar som du vill vara medveten om när du uppgraderar från Django 4.1 eller tidigare. Vi har börjat utfasningsprocessen för vissa funktioner.
Se guiden Så här uppgraderar du Django till en nyare version om du ska uppdatera ett befintligt projekt.
Django 4.2 betecknas som en long-term support release. Den kommer att få säkerhetsuppdateringar i minst tre år efter att den släppts. Stöd för den tidigare LTS, Django 3.2, kommer att upphöra i april 2024.
Kompatibilitet med Python¶
Django 4.2 stöder Python 3.8, 3.9, 3.10, 3.11 och 3.12 (från och med 4.2.8). Vi rekommenderar starkt och stöder endast officiellt den senaste utgåvan av varje serie.
Vad är nytt i Django 4.2¶
Psycopg 3 stöd¶
Django stöder nu psycopg version 3.1.8 eller högre. För att uppdatera din kod, installera psycopg-biblioteket, du behöver inte ändra :inställningen:`ENGINE <DATABASE-ENGINE>` eftersom django.db.backends.postgresql
stöder båda biblioteken.
Stöd för psycopg2
kommer sannolikt att bli föråldrat och tas bort någon gång i framtiden.
Var medveten om att psycopg
3 introducerar vissa förändringar jämfört med psycopg2
. Som en följd av detta kan du behöva göra några ändringar för att ta hänsyn till skillnader från psycopg2.
Kommentarer till kolumner och tabeller¶
De nya alternativen Field.db_comment
och Meta.db_table_comment
gör det möjligt att skapa kommentarer om kolumner respektive tabeller. Till exempel:
from django.db import models
class Question(models.Model):
text = models.TextField(db_comment="Poll question")
pub_date = models.DateTimeField(
db_comment="Date and time when the question was published",
)
class Meta:
db_table_comment = "Poll questions"
class Answer(models.Model):
question = models.ForeignKey(
Question,
on_delete=models.CASCADE,
db_comment="Reference to a question",
)
answer = models.TextField(db_comment="Question answer")
class Meta:
db_table_comment = "Question answers"
Den nya operationen AlterModelTableComment
gör det också möjligt att ändra tabellkommentarer som definieras i Meta.db_table_comment
.
Begränsning av BREACH-attacken¶
GZipMiddleware
innehåller nu en begränsning för BREACH-attacken. Det kommer att lägga till upp till 100 slumpmässiga byte till gzip-svar för att göra BREACH-attacker svårare. Läs mer om begränsningstekniken i dokumentet Heal The Breach (HTB) paper.
Lagring av filer i minnet¶
Den nya django.core.files.storage.InMemoryStorage
-klassen tillhandahåller en icke-beständig lagring som är användbar för att påskynda tester genom att undvika diskåtkomst.
Anpassad förvaring av filer¶
Den nya inställningen STORAGES
gör det möjligt att konfigurera flera anpassade backends för fillagring. Den styr också lagringsmotorer för hantering av files (nyckeln "default"
) och static files (nyckeln "staticfiles"
).
De gamla inställningarna DEFAULT_FILE_STORAGE
och STATICFILES_STORAGE
är föråldrade från och med denna utgåva.
Mindre funktioner¶
django.contrib.admin
¶
Administratörens ljusa eller mörka färgtema kan nu växlas i användargränssnittet och kan även ställas in så att det följer systeminställningen.
Administratörens teckensnittsstapel föredrar nu systemgränssnittets teckensnitt och kräver inte längre nedladdning av teckensnitt. Dessutom finns CSS-variabler tillgängliga för att lättare åsidosätta standardteckensnittsfamiljerna.
Mallen admin/delete_confirmation.html har nu några ytterligare block och skriptkrokar för att underlätta anpassningen.
De valda alternativen för widgetarna
filter_horizontal
ochfilter_vertical
är nu filtrerbara.Mallen
admin/base.html
har nu ett nytt blocknav-breadcrumbs
som innehåller navigationslandmärket och blocketbreadcrumbs
.ModelAdmin.list_editable
använder nu atomära transaktioner när redigeringar görs.jQuery uppgraderas från version 3.6.0 till 3.6.4.
django.contrib.auth
¶
Standardantalet iterationer för PBKDF2-lösenordshashen ökas från 390.000 till 600.000.
UserCreationForm
sparar nu många-till-många formulärfält för en anpassad användarmodell.Den nya
BaseUserCreationForm
är nu den rekommenderade basklassen för att anpassa formuläret för att skapa användare.
django.contrib.gis
¶
Den GeoJSON serializer nu utmatar
id
nyckel för serialiserade funktioner, som standard till den primära nyckeln för objekt.Klassen
GDALRaster
har nu stöd förpathlib.Path
.Klassen
GeoIP2
stöder nu.mmdb
-filer som laddats ner från DB-IP.OpenLayers mallwidget innehåller inte längre inline CSS (vilket också tar bort det tidigare
map_css
-blocket) för att bättre följa en strikt Content Security Policy.OpenLayersWidget
är nu baserad på OpenLayers 7.2.2 (tidigare 4.6.5).Det nya uttrycket
isempty
lookup ochIsEmpty()
gör det möjligt att filtrera tomma geometrier i PostGIS.De nya funktionerna
FromWKB()
ochFromWKT()
gör det möjligt att skapa geometrier från välkända binära (WKB) och välkända text (WKT) representationer.
django.contrib.postgres
¶
Den nya
trigram_strict_word_similar
lookupen ochTrigramStrictWordSimilarity()
ochTrigramStrictWordDistance()
uttrycken tillåter användning av trigramstrikt ordlikhet.Uppslagsfunktionen
arrayfield.overlap
stöder nuQuerySet.values()
ochvalues_list()
som höger sida.
django.contrib.sitemaps
¶
Med den nya metoden
Sitemap.get_languages_for_item()
kan du anpassa listan över språk som objektet visas på.
django.contrib.staticfiles
¶
ManifestStaticFilesStorage
har nu experimentellt stöd för att ersätta sökvägar till JavaScript-moduler iimport
ochexport
-satser med deras hashade motsvarigheter. Om du vill prova det, underklassaManifestStaticFilesStorage
och sätt attributetupport_js_module_import_aggregation
tillTrue
.Det nya attributet
ManifestStaticFilesStorage.manifest_hash
ger en hash över alla filer i manifestet och ändras när någon av filerna ändras.
Databas backends¶
Det nya alternativet `` ”assume_role” `` stöds nu i
OPTIONS
på PostgreSQL för att möjliggöra specificering av session roll.Det nya alternativet
"server_side_binding"
stöds nu iOPTIONS
på PostgreSQL medpsycopg
3.1.8+ för att tillåta användning av :ref:``server-side binding cursors <database-server-side-parameters-binding>`.
Felrapportering¶
Felsökningssidan visar nu exception notes och fine-grained error locations på Python 3.11+.
Sessionscookies behandlas nu som autentiseringsuppgifter och döljs därför och ersätts med stjärnor (
**********
) i felrapporter.
Formulär¶
ModelForm
accepterar nu det nyaMeta
-alternativetformfield_callback
för att anpassa formulärfält.modelform_factory()
respekterar nu attributetformfield_callback
iformulärets
Meta
.
Internationalisering¶
Stöd och översättningar för språket centralkurdiska (sorani) har lagts till.
Loggning¶
Loggern django.db.backends loggar nu frågor om transaktionshantering (
BEGIN
,COMMIT
ochROLLBACK
) på nivånDEBUG
.
Kommandon för hantering¶
kommandot
makemessages
stöder nu lokala språk med privata undertaggar somnl_NL-x-informal
.Det nya
makemigrations --update
-alternativet sammanfogar modelländringar i den senaste migreringen och optimerar de resulterande operationerna.
Migreringar¶
Migrationer stöder nu serialisering av
enum.Flag
-objekt.
Modeller¶
QuerySet
har nu omfattande stöd för filtrering mot Fönsterfunktioner med undantag för disjunktiva filteruppslagningar mot fönsterfunktioner vid aggregering.prefetch_related()
stöder nuPrefetch
-objekt med skivade querysets.Registrering av lookups på
Field
instanser stöds nu.Det nya
robust
-argumentet föron_commit()
gör det möjligt att utföra åtgärder som kan misslyckas efter att en databastransaktion har genomförts.Det nya
KT()
-uttrycket representerar textvärdet för en nyckel-, index- eller sökvägstransformation avJSONField
.Now
stöder nu mikrosekundsprecision på MySQL och millisekundsprecision på SQLite.F()
uttryck som gerBooleanField
kan nu negeras med hjälp av~F()
(inversionsoperator).Model
tillhandahåller nu asynkrona versioner av vissa metoder som använder databasen, med prefixeta
:adelete()
,arefresh_from_db()
, ochasave()
.Related managers tillhandahåller nu asynkrona versioner av metoder som ändrar en uppsättning relaterade objekt, med prefixet
a
:aadd()
,aclear()
,aremove()
ochaset()
.CharField.max_length
behöver inte längre ställas in på PostgreSQL, som stöder obegränsadeVARCHAR
-kolumner.
Förfrågningar och svar¶
StreamingHttpResponse
stöder nu asynkrona iteratorer när Django serveras via ASGI.
Tester¶
Alternativet
test --debug-sql
formaterar nu SQL-frågor medsqlparse
.Klasserna
RequestFactory
,AsyncRequestFactory
,Client
ochAsyncClient
stöder nu parameternheaders
, som accepterar en ordbok med namn och värden på rubriker. Detta ger en mer naturlig syntax för att deklarera headers.# Before: self.client.get("/home/", HTTP_ACCEPT_LANGUAGE="fr") await self.async_client.get("/home/", ACCEPT_LANGUAGE="fr") # After: self.client.get("/home/", headers={"accept-language": "fr"}) await self.async_client.get("/home/", headers={"accept-language": "fr"})
Verktyg¶
Den nya parametern
encoder
för funktionendjango.utils.html.json_script()
gör det möjligt att anpassa en JSON-kodningsklass.Den privata interna vendored-kopian av
urllib.parse.urlsplit()
tar nu bort'\r'
,'\n'
och'\t'
(se CVE 2022-0391 och bpo-43882). Detta för att skydda projekt som kanske felaktigt använder den interna funktionenurl_has_allowed_host_and_scheme()
, istället för att använda någon av de dokumenterade funktionerna för att hantera URL-omdirigeringar. Django-funktionerna påverkades inte.Den nya funktionen
django.utils.http.content_disposition_header()
returnerar ett HTTP-huvudvärde förContent-Disposition
enligt specifikationen i RFC 6266.
Validerare¶
Listan över vanliga lösenord som används av
CommonPasswordValidator
uppdateras till den senaste versionen.
Bakåtkompatibla ändringar i 4.2¶
Databas backend API¶
I det här avsnittet beskrivs ändringar som kan behövas i tredjeparts databasbackends.
DatabaseFeatures.allows_group_by_pk
tas bort eftersom det bara fanns kvar för att tillgodose ett MySQL-tillägg som har ersatts av korrekt funktionell beroendedetektering i MySQL 5.7.15. Observera attDatabaseFeatures.allows_group_by_selected_pks
fortfarande stöds och bör aktiveras om din backend stöder funktionell beroendedetektering iGROUP BY
-klausuler enligt specifikationen iSQL:1999
-standarden.inspectdb
använder nudisplay_size
frånDatabaseIntrospection.get_table_description()
istället förinternal_size
förCharField
.
Upphört stöd för MariaDB 10.3¶
Uppströmsstöd för MariaDB 10.3 upphör i maj 2023. Django 4.2 stöder MariaDB 10.4 och senare.
Borttaget stöd för MySQL 5.7¶
Uppströmsstöd för MySQL 5.7 slutar i oktober 2023. Django 4.2 stöder MySQL 8 och högre.
Slopat stöd för PostgreSQL 11¶
Uppströmsstöd för PostgreSQL 11 slutar i november 2023. Django 4.2 stöder PostgreSQL 12 och högre.
Det kan nu vara nödvändigt att ställa in update_fields
i Model.save()
¶
För att undvika uppdatering av onödiga kolumner skickar QuerySet.update_or_create()
nu update_fields
till Model.save()
-anropen. Som en konsekvens bör alla fält som ändras i de anpassade save()
-metoderna läggas till i update_fields
nyckelordsargumentet innan du anropar super()
. Se Åsidosätta fördefinierade modellmetoder för mer information.
Borttaget stöd för råa aggregeringar på MySQL¶
MySQL 8+ tillåter funktionella beroenden på GROUP BY
-kolumner, så lösningen före Django 4.2 att gruppera efter primärnycklar i huvudtabellen tas bort. Som en konsekvens stöds inte längre användning av RawSQL()
-aggregeringar på MySQL eftersom det inte finns något sätt att avgöra om sådana aggregeringar behövs eller är giltiga i GROUP BY
-klausulen. Använd Aggregeringsfunktioner istället.
Diverse¶
Den odokumenterade funktionen
django.http.multipartparser.parse_header()
har tagits bort. Använddjango.utils.http.parse_header_parameters()
istället.{% blocktranslate asvar ... %}
resultat är nu markerat som säkert för (HTML) utmatningsändamål.HTML-attributet
autofokus
i sökrutan för administratörer har tagits bort eftersom det kan vara förvirrande för skärmläsare.Alternativet
makemigrations --check
skapar inte längre saknade migreringsfiler.Argumentet
alias
förExpression.get_group_by_cols()
har tagits bort.Den minsta versionen av
sqlparse
som stöds har ökats från 0.2.2 till 0.3.1.Den odokumenterade parametern
negated
i uttrycketExists
har tagits bort.Argumentet
is_summary
i den odokumenterade metodenQuery.add_annotation()
har tagits bort.Den lägsta versionen av SQLite som stöds har höjts från 3.9.0 till 3.21.0.
Den lägsta versionen av
asgiref
som stöds har ökats från 3.5.2 till 3.6.0.UserCreationForm
avvisar nu användarnamn som skiljer sig åt endast i fall. Om du behöver det tidigare beteendet, användBaseUserCreationForm
istället.Den minsta versionen av
mysqlclient
som stöds har ökats från 1.4.0 till 1.4.3.Den minsta versionen av
argon2-cffi
som stöds har ökats från 19.1.0 till 19.2.0.Den lägsta versionen av
Pillow
som stöds har ökats från 6.2.0 till 6.2.1.Den lägsta versionen av
jinja2
som stöds har ökats från 2.9.2 till 2.11.0.Den minsta versionen som stöds av redis-py har ökats från 3.0.0 till 3.4.0.
Manuellt instantierade
WSGIRequest
-objekt måste förses med ett filliknande objekt förwsgi.input
. Tidigare var Django mer slapphänt än det förväntade beteendet som anges i WSGI-specifikationen.Stöd för
PROJ
< 5 har tagits bort.EmailBackend
verifierar nu enhostname
ochcertificates
. Om du behöver det tidigare beteendet som är mindre restriktivt och inte rekommenderas, underklassaEmailBackend
och åsidosätt egenskapenssl_context
.
Funktioner som inte längre är aktuella i 4.2¶
alternativet index_together
är föråldrat till förmån för indexes
¶
Alternativet Meta.index_together
är föråldrat till förmån för alternativet indexes
.
Migrering av befintliga index_together
bör hanteras som en migrering. Till exempel:
class Author(models.Model):
rank = models.IntegerField()
name = models.CharField(max_length=30)
class Meta:
index_together = [["rank", "name"]]
Bör bli:
class Author(models.Model):
rank = models.IntegerField()
name = models.CharField(max_length=30)
class Meta:
indexes = [models.Index(fields=["rank", "name"])]
Om du kör kommandot makemigrations
genereras en migrering som innehåller en RenameIndex
-operation som byter namn på det befintliga indexet. Därefter kan du överväga att krossa migreringar för att ta bort index_together
från historiska migreringar.
Migreringsoperationen AlterIndexTogether
stöds nu officiellt endast för migreringsfiler från före Django 4.2. Av bakåtkompatibilitetsskäl är det fortfarande en del av det offentliga API:et, och det finns ingen plan att avskriva eller ta bort det, men det bör inte användas för nya migreringar. Använd istället AddIndex
och RemoveIndex
.
Att skicka kodade JSON-stränglitteraler till JSONField
är föråldrat¶
JSONField
och dess associerade uppslagningar och aggregat brukade tillåta överföring av JSON-kodade stränglitteraler vilket orsakade tvetydighet om huruvida stränglitteraler redan var kodade från databasens backend-perspektiv.
Under utfasningsperioden kommer stränglitteraler att försöka JSON-avkodas och en varning kommer att skickas ut vid framgång som pekar på att icke-kodade former ska skickas istället.
Kod som används för att skicka JSON-kodade stränglitteraler:
Document.objects.bulk_create(
Document(data=Value("null")),
Document(data=Value("[]")),
Document(data=Value('"foo-bar"')),
)
Document.objects.annotate(
JSONBAgg("field", default=Value("[]")),
)
Bör bli:
Document.objects.bulk_create(
Document(data=Value(None, JSONField())),
Document(data=[]),
Document(data="foo-bar"),
)
Document.objects.annotate(
JSONBAgg("field", default=[]),
)
Från Django 5.1+ kommer stränglitteraler att tolkas implicit som JSON-stränglitteraler.
Diverse¶
Metoden
BaseUserManager.make_random_password()
är föråldrad. Se recept och bästa praxis för att använda Pythons modulsecrets
för att generera lösenord.Mallfiltret
length_is
är föråldrat till förmån förlength
och operatorn==
inom en{% if %}
-tagg. Till exempel{% if value|length == 4 %}…{% endif %} {% if value|length == 4 %}True{% else %}False{% endif %}
istället för:
{% if value|length_is:4 %}…{% endif %} {{ value|length_is:4 }}
django.contrib.auth.hashers.SHA1PasswordHasher
,django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher
ochdjango.contrib.auth.hashers.UnsaltedMD5PasswordHasher
är föråldrade.django.contrib.postgres.fields.CICharField
är föråldrad till förmån förCharField(db_collation="...")
med en skiftlägesokänslig icke-deterministisk kollation.django.contrib.postgres.fields.CIEmailField
är föråldrad till förmån förEmailField(db_collation="...")
med en skiftlägeskänslig icke-deterministisk kollation.django.contrib.postgres.fields.CITextField
är föråldrad till förmån förTextField(db_collation="...")
med en skiftlägeskänslig icke-deterministisk kollation.django.contrib.postgres.fields.CIText
mixin är föråldrad.Attributen
map_height
ochmap_width
förBaseGeometryWidget
är föråldrade, använd CSS för att dimensionera kartwidgets istället.SimpleTestCase.assertFormsetError()
är föråldrad till förmån förassertFormSetError()
.TransactionTestCase.assertQuerysetEqual()
är föråldrad till förmån förassertQuerySetEqual()
.Att skicka positionella argument till
Signer
ochTimestampSigner
är föråldrat till förmån för argument som endast innehåller nyckelord.Inställningen
DEFAULT_FILE_STORAGE
är föråldrad till förmån förSTORAGES["default"]
.Inställningen
STATICFILES_STORAGE
är föråldrad till förmån förSTORAGES["staticfiles"]
.Funktionen
django.core.files.storage.get_storage_class()
är föråldrad.