Django 1.4 release notes

23 mars 2012

Välkommen till Django 1.4!

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.3 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.

Översikt

Den största nyheten i Django 1.4 är stöd för tidszoner vid hantering av datum/tider. När detta är aktiverat kommer Django att lagra datum/tider i UTC, använda tidszonsmedvetna objekt internt och översätta dem till användarnas lokala tidszoner för visning.

Om du uppgraderar ett befintligt projekt till Django 1.4 kan det krävas lite försiktighet att byta till det tidszonsmedvetna läget: det nya läget tillåter inte något ganska slarvigt beteende som tidigare accepterades. Vi uppmuntrar alla som uppgraderar att kolla in timezone migration guide och timezone FAQ för användbara tips.

Andra anmärkningsvärda nya funktioner i Django 1.4 inkluderar:

När det är möjligt försöker vi introducera nya funktioner på ett bakåtkompatibelt sätt enligt vår API-stabilitetspolicy policy. Men som med tidigare utgåvor levereras Django 1.4 med några mindre bakåtkompatibla ändringar; personer som uppgraderar från tidigare versioner av Django bör läsa listan noggrant.

Kompatibilitet med Python

Django 1.4 har tappat stödet för Python 2.4. Python 2.5 är nu den Python-version som minst krävs. Django testas och stöds på Python 2.5, 2.6 och 2.7.

Denna förändring bör endast påverka ett litet antal Django-användare, eftersom de flesta leverantörer av operativsystem idag levererar Python 2.5 eller nyare som standardversion. Om du fortfarande använder Python 2.4 måste du dock hålla dig till Django 1.3 tills du kan uppgradera. Enligt vår supportpolicy kommer Django 1.3 att fortsätta att få säkerhetsstöd fram till lanseringen av Django 1.5.

Django stöder inte Python 3.x för närvarande. Vid någon tidpunkt före lanseringen av Django 1.4 planerar vi att publicera ett dokument som beskriver vår fullständiga tidslinje för att avskriva Python 2.x och flytta till Python 3.x.

Vad är nytt i Django 1.4

Stöd för tidszoner

I tidigare versioner använde Django ”naiva” datum/tider (det vill säga datum/tider utan tillhörande tidszon), vilket gjorde att det var upp till varje utvecklare att tolka vad ett visst datum/tid ”egentligen betyder”. Detta kan orsaka alla möjliga subtila tidszonsrelaterade buggar.

I Django 1.4 kan du nu växla Django till ett mer korrekt, tidszonsmedvetet läge. I det här läget lagrar Django datum- och tidsinformation i UTC i databasen, använder tidszonmedvetna datetime-objekt internt och översätter dem till slutanvändarens tidszon i mallar och formulär. Anledningar till att använda denna funktion inkluderar:

  • Anpassa visning av datum och tid för användare runt om i världen.

  • Lagring av datatider i UTC för databasportabilitet och interoperabilitet. (Detta argument gäller inte PostgreSQL, eftersom det redan lagrar tidsstämplar med tidszoninformation i Django 1.3)

  • Undvika problem med datakorruption vid övergång till sommartid.

Stöd för tidszoner är aktiverat som standard i nya projekt som skapas med startproject. Om du vill använda den här funktionen i ett befintligt projekt kan du läsa migration guide. Om du stöter på problem finns det en användbar FAQ.

Stöd för ramverk för testning i webbläsaren

Django 1.4 stöder integration med testramverk i webbläsaren som Selenium. Med den nya basklassen django.test.LiveServerTestCase kan du testa interaktionerna mellan webbplatsens front- och backend på ett mer omfattande sätt. Se documentation för mer information och konkreta exempel.

Uppdaterad standardprojektlayout och manage.py

Django 1.4 levereras med en uppdaterad standardprojektlayout och manage.py-fil för hanteringskommandot startproject. Dessa åtgärdar vissa problem med den tidigare manage.py-hanteringen av Python-importvägar som orsakade dubbelimport, problem med att flytta från utveckling till distribution och andra problem med sökvägar som är svåra att debugga.

Den tidigare manage.py anropade funktioner som nu är föråldrade, och därför bör projekt som uppgraderar till Django 1.4 uppdatera sin manage.py. (Den gamla stilen manage.py kommer att fortsätta att fungera som tidigare fram till Django 1.6. I 1.5 kommer den att ge upphov till DeprecationWarning).

Den nya rekommenderade filen manage.py bör se ut så här:

#!/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)

{{projektnamn }} ska ersättas med Python-paketnamnet för det aktuella projektet.

Om inställningar, URLconfs och appar inom projektet importeras eller refereras till med hjälp av projektnamnets prefix (t.ex. myproject.settings, ROOT_URLCONF = "myproject.urls", etc.), måste den nya manage.py flyttas en katalog uppåt, så att den ligger utanför projektpaketet i stället för bredvid settings.py och urls.py.

Till exempel med följande layout:

manage.py
mysite/
    __init__.py
    settings.py
    urls.py
    myapp/
        __init__.py
        models.py

Du kan importera mysite.settings, mysite.urls och mysite.myapp, men inte `settings, urls eller myapp som toppnivåmoduler.

Allt som importeras som en modul på högsta nivån kan placeras bredvid den nya manage.py. Till exempel, för att frikoppla myapp från projektmodulen och importera den som bara myapp, placera den utanför katalogen mysite/:

manage.py
myapp/
    __init__.py
    models.py
mysite/
    __init__.py
    settings.py
    urls.py

Om samma kod importeras på ett inkonsekvent sätt (på vissa ställen med projektprefixet, på andra ställen utan) måste importen rensas upp när man byter till den nya manage.py.

Anpassade projekt- och appmallar

Hanteringskommandona startapp och startproject har nu ett alternativ --template för att ange en sökväg eller URL till en anpassad app- eller projektmall.

Till exempel kommer Django att använda katalogen /path/to/my_project_template när du kör följande kommando:

django-admin.py startproject --template=/path/to/my_project_template myproject

Du kan nu också ange en destinationskatalog som det andra argumentet till både startapp och startproject:

django-admin.py startapp myapp /path/to/new/app
django-admin.py startproject myproject /path/to/new/project

Mer information finns i dokumentationen för startapp och startproject.

Förbättrat stöd för WSGI

Hanteringskommandot startproject lägger nu till en modul wsgi.py i den inledande projektlayouten, som innehåller en enkel WSGI-applikation som kan användas för deployering med WSGI-appservrar.

Servern built-in development server stöder nu användning av en externt definierad WSGI-kallelse, vilket gör det möjligt att köra runserver med samma WSGI-konfiguration som används för distributionen. Med den nya inställningen WSGI_APPLICATION kan du konfigurera vilken WSGI-kallelse som runserver använder.

(Hanteringskommandot runfcgi omsluter också internt den WSGI-kallelse som konfigureras via WSGI_APPLICATION)

VAL FÖR UPPDATERING stöd

Django 1.4 innehåller en QuerySet.select_for_update()-metod, som genererar en SQL-fråga SELECT ... FOR UPDATE. Detta låser raderna till slutet av transaktionen, vilket innebär att andra transaktioner inte kan ändra eller ta bort rader som matchas av en FOR UPDATE-fråga.

För mer information, se dokumentationen för select_for_update().

Model.objects.bulk_create i ORM

Med den här metoden kan du skapa flera objekt på ett mer effektivt sätt. Det kan resultera i betydande prestandaförbättringar om du har många objekt.

Django använder sig av detta internt, vilket innebär att vissa operationer (t.ex. databasuppsättning för testsviter) har sett en prestandafördel som ett resultat.

Se bulk_create()-dokumenten för mer information.

Förbättrad hashing av lösenord

Djangos auth-system (django.contrib.auth) lagrar lösenord med hjälp av en envägsalgoritm. Django 1.3 använder SHA1-algoritmen, men ökande processorhastigheter och teoretiska attacker har visat att SHA1 inte är så säker som vi skulle önska. Därför introducerar Django 1.4 ett nytt system för lagring av lösenord: som standard använder Django nu PBKDF2-algoritmen (som rekommenderas av NIST). Du kan också enkelt välja en annan algoritm (inklusive den populära bcrypt-algoritmen). För mer information, se Hur Django lagrar lösenord.

HTML5 doktyp

Vi har bytt admin och andra medföljande mallar till att använda HTML5-doktypen. Även om Django kommer att vara noga med att upprätthålla kompatibilitet med äldre webbläsare, innebär denna förändring att du kan använda alla HTML5-funktioner du behöver på adminsidor utan att behöva förlora HTML-validitet eller åsidosätta de medföljande mallarna för att ändra doktypen.

Lista filter i administratörsgränssnittet

Före Django 1.4 lät admin-appen dig ange filter för ändringslistor genom att ange en fältuppslagning, men det tillät dig inte att skapa anpassade filter. Detta har korrigerats med ett enkelt API (tidigare använt internt och känt som ”FilterSpec”). För mer information, se dokumentationen för list_filter.

Flera sorteringar i admin-gränssnittet

Administratörens ändringslista stöder nu sortering på flera kolumner. Det respekterar alla element i attributet ordering, och sortering på flera kolumner genom att klicka på rubriker är utformad för att efterlikna beteendet hos skrivbords-GUI. Vi har också lagt till en get_ordering()-metod för att ange sorteringen dynamiskt (dvs. beroende på begäran).

Nya metoder för ModelAdmin

Vi har lagt till en save_related()-metod till ModelAdmin för att underlätta anpassningen av hur relaterade objekt sparas i admin.

Två andra nya ModelAdmin-metoder, get_list_display() och get_list_display_links() möjliggör dynamisk anpassning av fält och länkar som visas på adminändringslistan.

Admin inlines respekterar användarnas behörigheter

Admin inlines tillåter nu endast de åtgärder som användaren har behörighet till. För ManyToMany-relationer med en automatiskt skapad mellanliggande modell (som inte har sina egna behörigheter) avgör ändringsbehörigheten för den relaterade modellen om användaren har behörighet att lägga till, ändra eller ta bort relationer.

Verktyg för kryptografisk signering

Django 1.4 lägger till både ett API på låg nivå för att signera värden och ett API på hög nivå för att ställa in och läsa signerade cookies, en av de vanligaste användningarna av signering i webbapplikationer.

Mer information finns i dokumenten cryptographic signing.

Ny formulärguide

Den tidigare FormWizard från django.contrib.formtools har ersatts med en ny implementation baserad på de klassbaserade vyerna som introducerades i Django 1.3. Den har ett pluggbart lagrings-API och kräver inte att guiden skickar runt dolda fält för varje tidigare steg.

Django 1.4 levereras med en sessionsbaserad lagringsbackend och en cookiebaserad lagringsbackend. Den senare använder verktygen för cryptographic signing som också introducerades i Django 1.4 för att lagra guidens tillstånd i användarens cookies.

omvända_lazy

En latent utvärderad version av reverse() lades till för att göra det möjligt att använda URL-omvändningar innan projektets URLconf laddas.

Översättning av URL-mönster

Django kan nu leta efter ett språkprefix i URL-mönstret när man använder den nya i18n_patterns() hjälpfunktionen. Det är nu också möjligt att definiera översättningsbara URL-mönster med hjälp av django.utils.translation.ugettext_lazy(). Se url-internationalisering för mer information om språkprefixet och hur man internationaliserar URL-mönster.

Stöd för kontextuell översättning för {% trans %} och {% blocktrans %}

Stödet :ref:kontextuell översättning<contextual-markers> som infördes i Django 1.3 via funktionen pgettext har utökats till malltaggarna trans och blocktrans med hjälp av det nya nyckelordet context.

Anpassningsbar SingleObjectMixin URLConf kwargs

Två nya attribut, pk_url_kwarg och slug_url_kwarg, har lagts till i SingleObjectMixin för att möjliggöra anpassning av URLconf-nyckelordsargument som används för generiska vyer för enstaka objekt.

Taggar för uppdragsmall

En ny hjälpfunktion, assignment_tag, har lagts till i template.Library för att underlätta skapandet av malltaggar som lagrar data i en angiven kontextvariabel.

stöd för *args och **kwargs för hjälpfunktioner för malltaggar

Hjälpfunktionerna simple_tag, inclusion_tag och den nyligen introducerade assignment_tag kan nu acceptera ett valfritt antal positionella eller nyckelordsargument. Till exempel:

@register.simple_tag
def my_tag(a, b, *args, **kwargs):
    warning = kwargs["warning"]
    profile = kwargs["profile"]
    ...
    return ...

I mallen kan sedan valfritt antal argument skickas till malltaggen. Till exempel:

{% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}

Ingen omslutning av undantag i TEMPLATE_DEBUG-läge

I tidigare versioner av Django, när inställningen TEMPLATE_DEBUG var True, lindades alla undantag som uppstod under mallrendering (även undantag som inte var relaterade till mallsyntax) i TemplateSyntaxError och uppstod igen. Detta gjordes för att kunna tillhandahålla detaljerad information om mallens källplacering på debug 500-sidan.

I Django 1.4 är undantag inte längre inplastade. Istället annoteras det ursprungliga undantaget med källinformationen. Detta innebär att det nu är konsekvent att fånga undantag från mallrendering oavsett värdet på TEMPLATE_DEBUG, och det finns inget behov av att fånga och packa upp TemplateSyntaxError för att fånga andra fel.

trunkatechars mallfilter

Detta nya filter trunkerar en sträng så att den inte är längre än det angivna antalet tecken. Trunkerade strängar avslutas med en översättningsbar ellipssekvens (”…”). Se dokumentationen för truncatechars för mer information.

statisk mall tagg

Contrib-appen staticfiles har en ny malltagg static för att referera till filer som sparats med lagringsbackend STATICFILES_STORAGE. Den använder lagringsbackendets url-metod och stöder därför avancerade funktioner som :ref:``serving files from a cloud service<staticfiles-from-cdn>`.

CachedStaticFilesStorage lagringsbackend

Contrib-appen staticfiles har nu en django.contrib.staticfiles.storage.CachedStaticFilesStorage-backend som cachelagrar filerna den sparar (när du kör hanteringskommandot collectstatic) genom att lägga till MD5-hashen för filens innehåll till filnamnet. Till exempel skulle filen css/styles.css också sparas som css/styles.55e7cbb9ba48.css

Enkelt skydd mot clickjacking

Vi har lagt till en mellanvara för att ge enkelt skydd mot clickjacking med hjälp av X-Frame-Options-headern. Det är inte aktiverat som standard av bakåtkompatibilitetsskäl, men du kommer nästan säkert att vilja aktivera det för att hjälpa till att täppa till det säkerhetshålet för webbläsare som stöder rubriken.

CSRF-förbättringar

Vi har gjort olika förbättringar av våra CSRF-funktioner, inklusive ensure_csrf_cookie()-dekoratorn, som kan hjälpa till med AJAX-tunga webbplatser; skydd för PUT- och DELETE-förfrågningar; och inställningarna CSRF_COOKIE_SECURE och CSRF_COOKIE_PATH, som kan förbättra säkerheten och användbarheten av CSRF-skydd. Se CSRF docs för mer information.

Filtrering av felrapporter

Vi har lagt till två funktionsdekoratorer, sensitive_variables() och sensitive_post_parameters(), för att göra det möjligt att ange de lokala variabler och POST-parametrar som kan innehålla känslig information och som bör filtreras bort från felrapporter.

Alla POST-parametrar filtreras nu systematiskt bort från felrapporter för vissa vyer (login, password_reset_confirm, password_change och add_view i django.contrib.auth.views, samt user_change_password i admin-appen) för att förhindra läckage av känslig information som användarlösenord.

Du kan åsidosätta eller anpassa standardfiltreringen genom att skriva ett custom filter. Mer information finns i dokumentationen om Filtrering av felrapporter.

Utökat IPv6-stöd

Django 1.4 kan nu bättre hantera IPv6-adresser med det nya modellfältet GenericIPAddressField, formulärfältet GenericIPAddressField och validerarna validate_ipv46_address och validate_ipv6_address.

HTML-jämförelser i tester

Basklasserna i django.test har nu några hjälpmedel för att jämföra HTML utan att snubbla över irrelevanta skillnader i blanksteg, argumentcitering/ordning och stängning av självstängande taggar. Du kan antingen jämföra HTML direkt med de nya assertHTMLEqual() och assertHTMLNotEqual() påståendena, eller använda html=True flaggan med assertContains() och assertNotContains() för att testa om klientens svar innehåller ett visst HTML-fragment. Se :ref:``assertions documentation <assertions>` för mer information.

Två nya datumformatsträngar

Två nya date-format har lagts till för användning i mallfilter, malltaggar och Lokalisering av format:

  • e – namnet på tidszonen för det angivna datetime-objektet

  • o – ISO 8601-årsnumret

Se till att uppdatera dina :ref:custom format files <custom-format-files> om de innehåller antingen e eller o i en formatsträng. Till exempel har ett spanskt lokaliseringsformat tidigare bara undkommit formattecknet d:

DATE_FORMAT = r"j \de F \de Y"

Men nu måste den också kunna undkomma e och o:

DATE_FORMAT = r"j \d\e F \d\e Y"

Mer information finns i date-dokumentationen.

Mindre funktioner

Django 1.4 innehåller också flera mindre förbättringar som är värda att notera:

  • En mer användbar stacktrace på den tekniska 500-sidan. Ramar i stackspåret som refererar till Djangos ramverkskod är nedtonade, medan ramar i applikationskod är något framhävda. Denna förändring gör det lättare att skanna en stacktrace efter problem i applikationskoden.

  • Tablespace-stöd i PostgreSQL.

  • Anpassningsbara namn för simple_tag().

  • I dokumentationen finns en användbar säkerhetsöversikt-sida.

  • Funktionen django.contrib.auth.models.check_password har flyttats till modulen django.contrib.auth.hashers. Att importera den från den gamla platsen kommer fortfarande att fungera, men du bör uppdatera dina importer.

  • Hanteringskommandot collectstatic har nu ett --clear-alternativ för att radera alla filer på destinationen innan de statiska filerna kopieras eller länkas.

  • Det är nu möjligt att ladda fixturer som innehåller framåtriktade referenser när MySQL används med InnoDB-databasmotorn.

  • En ny 403-svarshanterare har lagts till som 'django.views.defaults.permission_denied'. Du kan ställa in din egen hanterare genom att ställa in värdet på django.conf.urls.handler403. Se dokumentationen om vyn 403 (HTTP Forbidden) för mer information.

  • Kommandot makemessages använder en ny och mer exakt lexer, JsLex, för att extrahera översättningsbara strängar från JavaScript-filer.

  • Malltaggen trans tar nu ett valfritt as-argument för att kunna hämta en översättningssträng utan att visa den, utan istället ange en mallkontextvariabel.

  • Malltaggen if har nu stöd för {% elif %}-klausuler.

  • Om din Django-app befinner sig bakom en proxy kanske du tycker att den nya SECURE_PROXY_SSL_HEADER-inställningen är användbar. Den löser problemet med att din proxy ”äter” det faktum att en begäran kom in via HTTPS. Men använd bara den här inställningen om du vet vad du gör.

  • En ny version i klartext av den interna felsidan med statuskod HTTP 500 som visas när DEBUG är True skickas nu till klienten när Django upptäcker att begäran har sitt ursprung i JavaScript-kod. (is_ajax() används för detta.)

    Precis som sin HTML-motsvarighet innehåller den en samling av olika informationsbitar om applikationens tillstånd.

    Detta bör göra det lättare att läsa vid felsökning av interaktion med JavaScript på klientsidan.

  • Lagt till alternativet makemessages --no-location.

  • Ändrade cache-backend locmem till att använda pickle.HIGHEST_PROTOCOL för bättre kompatibilitet med de andra cache-backend.

  • Lagt till stöd i ORM för att generera SELECT-frågor som innehåller DISTINCT ON.

    Metoden distinct() QuerySet accepterar nu en valfri lista med namn på modellfält. Om det anges är DISTINCT -uttalandet begränsat till dessa fält. Detta stöds endast i PostgreSQL.

    För mer information, se dokumentationen för distinct().

  • Den administrativa inloggningssidan kommer att lägga till en länk för återställning av lösenord om du inkluderar en URL med namnet 'admin_password_reset' i din urls.py, så det är nu mycket enklare att koppla in den inbyggda mekanismen för återställning av lösenord och göra den tillgänglig. För detaljer, se Lägga till en funktion för återställning av lösenord.

  • MySQL-databasens backend kan nu använda den savepoint-funktion som implementerats av MySQL version 5.0.3 eller nyare med InnoDB-lagringsmotorn.

  • Det är nu möjligt att skicka initiala värden till modellformulär som ingår i både modellformulär och inline-modellformulär som returneras från fabriksfunktionerna modelformset_factory respektive inlineformset_factory precis som med vanliga formulär. Initiala värden gäller dock endast för extra formulär, dvs. de som inte är bundna till en befintlig modellinstans.

  • Sitemaps-ramverket kan nu hantera HTTPS-länkar med hjälp av det nya klassattributet Sitemap.protocol.

  • En ny django.test.SimpleTestCase underklass av unittest.TestCase som är lättare än django.test.TestCase och company. Den kan vara användbar i tester som inte behöver träffa en databas. Se Hierarki av klasser för enhetstestning av Django.

Bakåtkompatibla ändringar i 1.4

SECRET_KEY-inställning krävs

Att köra Django med en tom eller känd SECRET_KEY inaktiverar många av Djangos säkerhetsskydd och kan leda till sårbarheter för kodutförande på distans. Ingen Django-webbplats bör någonsin köras utan en SECRET_KEY.

I Django 1.4 kommer start av Django med en tom SECRET_KEY att ge upphov till en DeprecationWarning. I Django 1.5 kommer det att ge upphov till ett undantag och Django kommer att vägra att starta. Detta är något snabbare än den vanliga utfasningsvägen på grund av allvaret i konsekvenserna av att köra Django utan SECRET_KEY.

django.contrib.admin

Den medföljande administrationsappen django.contrib.admin har under en lång tid levererats med en standarduppsättning av statiska filer som JavaScript, bilder och stilmallar. Django 1.3 lade till en ny contrib-app django.contrib.staticfiles för att hantera sådana filer på ett generiskt sätt och definierade konventioner för statiska filer som ingår i appar.

Från och med Django 1.4 följer även admins statiska filer denna konvention, för att göra filerna enklare att distribuera. I tidigare versioner av Django var det också vanligt att definiera en ADMIN_MEDIA_PREFIX-inställning för att peka på URL:en där administratörens statiska filer finns på en webbserver. Denna inställning har nu utgått och ersatts av den mer allmänna inställningen STATIC_URL. Django kommer nu att förvänta sig att hitta administratörens statiska filer under webbadressen <STATIC_URL>/admin/.

Om du tidigare har använt en URL-sökväg för ADMIN_MEDIA_PREFIX (t.ex. /media/), se bara till att STATIC_URL och STATIC_ROOT är konfigurerade och att din webbserver serverar dessa filer korrekt. Utvecklingsservern fortsätter att servera adminfilerna precis som tidigare. Läs static files howto för mer information.

Om din ADMIN_MEDIA_PREFIX är inställd på en specifik domän (t.ex. http://media.example.com/admin/), se till att du också ställer in din STATIC_URL-inställning på rätt URL - till exempel http://media.example.com/.

Varning

Om du implicit förlitar dig på sökvägen för de statiska admin-filerna i Djangos källkod måste du uppdatera den sökvägen. Filerna flyttades från django/contrib/admin/media/ till django/contrib/admin/static/admin/.

Webbläsare som stöds för administratören

Django har inte haft en tydlig policy för vilka webbläsare som stöds av admin-appen. Vår nya policy formaliserar befintlig praxis: YUI:s A-grade-webbläsare bör ge en fullt fungerande administratörsupplevelse, med det anmärkningsvärda undantaget Internet Explorer 6, som inte längre stöds.

IE6 släpptes för över 10 år sedan och innebär många begränsningar för modern webbutveckling. De praktiska konsekvenserna av denna policy är att bidragsgivare är fria att förbättra administratören utan hänsyn till dessa begränsningar.

Denna nya policy har ingen inverkan på webbplatser som du utvecklar med Django. Den gäller endast för Django-administratören. Känn dig fri att utveckla appar som är kompatibla med alla typer av webbläsare.

Borttagna administratörsikoner

Som en del av ett försök att förbättra prestandan och användbarheten för admins ändringslistasorteringsgränssnitt och horizontal och vertical ”filter”-widgets, togs vissa ikonfiler bort och grupperades i två sprite-filer.

Specifikt: selector-add.gif, selector-addall.gif, selector-remove.gif, selector-removeall.gif, selector_stacked-add.gif och selector_stacked-remove.gif kombinerades till selector-icons.gif; och arrow-up.gif och arrow-down.gif kombinerades till orting-icons.gif.

Om du använde dessa ikoner för att anpassa administratören måste du ersätta dem med dina egna ikoner eller hämta filerna från en tidigare version.

CSS-klassnamn i adminformulär

För att undvika konflikter med andra vanliga CSS-klassnamn (t.ex. ”knapp”) har vi lagt till ett prefix (”field-”) till alla CSS-klassnamn som automatiskt genereras från formulärfältens namn i huvudadministratörens formulär, staplade inline-formulär och tabulära inline-celler. Du måste ta hänsyn till det prefixet i dina anpassade stilmallar eller JavaScript-filer om du tidigare har använt vanliga fältnamn som väljare för anpassade stilar eller JavaScript-transformationer.

Kompatibilitet med gamla signerade data

Django 1.3 ändrade de kryptografiska signeringsmekanismerna som används på ett antal ställen i Django. Medan Django 1.3 behöll fallbackar som skulle acceptera hashar som producerats med de tidigare metoderna, tas dessa fallbackar bort i Django 1.4.

Så om du uppgraderar till Django 1.4 direkt från 1.2 eller tidigare, kan du förlora / ogiltigförklara vissa delar av data som har kryptografiskt signerats med en gammal metod. För att undvika detta, använd Django 1.3 först under en tidsperiod för att låta de signerade uppgifterna löpa ut naturligt. De berörda delarna beskrivs nedan, med 1) konsekvenserna av att ignorera detta råd och 2) den tid du behöver köra Django 1.3 för att data ska löpa ut eller bli irrelevanta.

  • contrib.sessions kontroll av dataintegritet

    • Konsekvenser: Användaren loggas ut och sessionsdata går förlorade.

    • Tidsperiod: Definieras av SESSION_COOKIE_AGE.

  • contrib.auth hash för återställning av lösenord

    • Konsekvenser: Länkar för återställning av lösenord från före uppgraderingen kommer inte att fungera.

    • Tidsperiod: Definieras av PASSWORD_RESET_TIMEOUT_DAYS.

Formulärrelaterade hashar: dessa har en mycket kortare livslängd och är endast relevanta för det korta fönster där en användare kan fylla i ett formulär som genererats av Django-instansen före uppgraderingen och försöka skicka in det till den uppgraderade Django-instansen:

  • contrib.comments formulär säkerhet hash

    • Konsekvenser: Användaren kommer att se valideringsfelet ”Security hash failed.”

    • Tidsperiod: Den tid du förväntar dig att användarna ska använda för att fylla i kommentarformulär.

  • FormWizard säkerhetshash

    • Konsekvenser: Användaren kommer att se ett felmeddelande om att formuläret har löpt ut och skickas tillbaka till första sidan i guiden och förlorar de uppgifter som hittills har angetts.

    • Tidsperiod: Den tid du förväntar dig att det tar för användarna att fylla i de berörda formulären.

  • CSRF-kontroll

    • Obs: Detta är faktiskt en Django 1.1 fallback, inte Django 1.2, och det gäller endast om du uppgraderar från 1.1.

    • Konsekvenser: Användaren kommer att se ett 403-fel med alla CSRF-skyddade POST-formulär.

    • Tidsperiod: Den tid du förväntar dig att det tar för användaren att fylla i sådana formulär.

  • contrib.auth användare lösenord hash-upgrade sekvens

    • Konsekvenser: Varje användares lösenord kommer att uppdateras till en starkare lösenordshash när det skrivs till databasen i 1.4. Detta innebär att om du uppgraderar till 1.4 och sedan behöver nedgradera till 1.3, kommer version 1.3 inte att kunna läsa de uppdaterade lösenorden.

    • Åtgärd: Ställ in PASSWORD_HASHERS för att använda din ursprungliga lösenordshashning när du initialt uppgraderar till 1.4. När du har bekräftat att din app fungerar bra med Django 1.4 och att du inte behöver återgå till 1.3, aktivera de nya lösenordshasharna.

django.contrib.flatpages

Från och med 1.4 lägger FlatpageFallbackMiddleware bara till ett efterföljande snedstreck och omdirigerar om den resulterande URL:en hänvisar till en befintlig flatpage. Till exempel skulle en begäran om /notaflatpageoravalidurl i en tidigare version omdirigera till /notaflatpageoravalidurl/, vilket skulle ge en 404. Om du begär /notaflatpageoravalidurl nu kommer du omedelbart att få en 404.

Dessutom är omdirigeringar som returneras av flatpages nu permanenta (med 301 statuskod), för att matcha beteendet hos CommonMiddleware.

Serialisering av datetime och time

Som en följd av stödet för tidszoner, och i enlighet med ECMA-262-specifikationen, har vi gjort ändringar i JSON-serialisatorn:

  • Det inkluderar tidszonen för medvetna datetime-objekt. Det ger upphov till ett undantag för medvetna tidsobjekt.

  • Det inkluderar millisekunder för datetime- och tidsobjekt. Det finns fortfarande en viss precisionsförlust, eftersom Python lagrar mikrosekunder (6 siffror) och JSON endast stöder millisekunder (3 siffror). Det är dock bättre än att helt slopa mikrosekunder.

Vi har ändrat XML-serialisatorn så att den använder ISO8601-formatet för datumtider. Bokstaven T används för att separera datumdelen från tidsdelen, istället för ett mellanslag. Information om tidszon ingår i formatet [+-]HH:MM.

Även om serialiserarna nu använder dessa nya format när de skapar fixturer, kan de fortfarande ladda fixturer som använder det gamla formatet.

`supports_timezone ändras till False för SQLite

Databasfunktionen supports_timezone brukade vara True för SQLite. Om du sparade ett medvetet datetime-objekt lagrade SQLite faktiskt en sträng som inkluderade en UTC-offset. Denna förskjutning ignorerades dock när värdet laddades tillbaka från databasen, vilket kunde korrumpera data.

I samband med tidszonsstöd ändrades denna flagga till False, och datatider lagras nu utan tidszonsinformation i SQLite. När USE_TZ är False, om du försöker spara ett medvetet datetime-objekt, ger Django upphov till ett undantag.

MySQLdb-specifika undantag

MySQL-backend har historiskt gett upphov till MySQLdb.OperationalError när en fråga utlöste ett undantag. Vi har fixat den här buggen, och vi höjer nu django.db.DatabaseError istället. Om du testade för MySQLdb.OperationalError måste du uppdatera dina except-klausuler.

Databasanslutningens trådlocalitet

DatabaseWrapper-objekt (dvs. anslutningsobjekten som refereras till av django.db.connection och django.db.connections["some_alias"]) brukade vara trådlokala. De är nu globala objekt för att potentiellt kunna delas mellan flera trådar. Medan de enskilda anslutningsobjekten nu är globala är django.db.connections-ordlistan som hänvisar till dessa objekt fortfarande trådlokal. Om du bara använder ORM eller DatabaseWrapper.cursor() är beteendet därför fortfarande detsamma som tidigare. Observera dock att django.db.connection inte längre refererar direkt till standardobjektet DatabaseWrapper utan nu är en proxy för att komma åt objektets attribut. Om du behöver komma åt det faktiska DatabaseWrapper-objektet, använd django.db.connections[DEFAULT_DB_ALIAS] istället.

Som en del av denna förändring är alla underliggande SQLite-anslutningar nu aktiverade för potentiell tråddelning (genom att skicka attributet check_same_thread=False till pysqlite). DatabaseWrapper behåller dock det tidigare beteendet genom att inaktivera tråddelning som standard, så detta påverkar inte någon befintlig kod som enbart förlitar sig på ORM eller på DatabaseWrapper.cursor().

Slutligen, även om det nu är möjligt att skicka anslutningar mellan trådar, gör Django inte något försök att synkronisera åtkomst till den underliggande backend. Samtidighetsbeteendet definieras av den underliggande backend-implementeringen. Kontrollera deras dokumentation för detaljer.

COMMENTS_BANNED_USERS_GROUP inställning

Djangos kommentarer har historiskt sett haft stöd för att utesluta kommentarer från en speciell användargrupp, men vi har aldrig dokumenterat funktionen ordentligt och inte genomdrivit uteslutningen i andra delar av appen, till exempel malltaggarna. För att åtgärda detta problem tog vi bort koden från feed-klassen.

Om du förlitar dig på funktionen och vill återställa det gamla beteendet använder du en anpassad kommentarmodellhanterare för att utesluta användargruppen, så här:

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

Spara denna modellhanterare i din anpassade kommentarapp (t.ex. i my_comments_app/managers.py) och lägg till den i din anpassade kommentarappsmodell:

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()

inställningar för IGNORABLE_404_STARTS och IGNORABLE_404_ENDS

Fram till Django 1.3 var det möjligt att utesluta vissa webbadresser från Djangos 404 error reporting genom att lägga till prefix till IGNORABLE_404_STARTS och suffix till IGNORABLE_404_ENDS.

I Django 1.4 ersätts dessa två inställningar av IGNORABLE_404_URLS, som är en lista med kompilerade reguljära uttryck. Django kommer inte att skicka ett e-postmeddelande för 404-fel på webbadresser som matchar någon av dem.

Dessutom hade de tidigare inställningarna några ganska godtyckliga standardvärden:

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

Det är inte Djangos roll att avgöra om din webbplats har en äldre /cgi-bin/-sektion eller en favicon.ico. Som en följd av detta är standardvärdena för IGNORABLE_404_URLS, IGNORABLE_404_STARTS och IGNORABLE_404_ENDS nu alla tomma.

Om du har anpassat IGNORABLE_404_STARTS eller IGNORABLE_404_ENDS, eller om du vill behålla det gamla standardvärdet, bör du lägga till följande rader i din inställningsfil:

import re

IGNORABLE_404_URLS = (
    # for each <prefix> in IGNORABLE_404_STARTS
    re.compile(r"^<prefix>"),
    # for each <suffix> in IGNORABLE_404_ENDS
    re.compile(r"<suffix>$"),
)

Glöm inte att undkomma tecken som har en speciell betydelse i ett reguljärt uttryck, t.ex. punkter.

CSRF-skydd utökat till PUT och DELETE

Tidigare gav Djangos CSRF-skydd endast skydd mot POST-förfrågningar. Eftersom användningen av PUT- och DELETE-metoder i AJAX-applikationer blir allt vanligare, skyddar vi nu alla metoder som inte definieras som säkra av RFC 2616 - dvs. vi undantar GET, HEAD, OPTIONS och TRACE, och vi tillämpar skydd på allt annat.

Om du använder PUT- eller DELETE-metoder i AJAX-applikationer, se :ref:instruktioner om att använda AJAX och CSRF <csrf-ajax>.

Lösenordsåterställningsvyn accepterar nu subject_template_name

Vyn password_reset i django.contrib.auth accepterar nu en subject_template_name parameter, som skickas till formuläret för att spara lösenord som ett nyckelordsargument. Om du använder den här vyn med ett anpassat formulär för återställning av lösenord måste du se till att formulärets save()-metod accepterar detta nyckelordsargument.

django.core.template_loaders

Detta var ett alias till django.template.loader sedan 2005, och vi har tagit bort det utan att skicka ut en varning på grund av längden på utfasningen. Om din kod fortfarande refererar till detta, använd django.template.loader istället.

django.db.models.fields.URLField.verify_exists

Denna funktionalitet har tagits bort på grund av svårlösta prestanda- och säkerhetsproblem. All befintlig användning av verify_exists bör tas bort.

django.core.files.storage.Storage.open

Metoden open i basklassen Storage brukade ta en obskyr parameter mixin som gjorde att du dynamiskt kunde ändra basklasserna för det returnerade filobjektet. Detta har tagits bort. I det sällsynta fall du förlitade dig på parametern mixin kan du enkelt uppnå samma sak genom att åsidosätta metoden open, så här:

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 använder nu yaml.safe_load

yaml.load kan konstruera vilket Python-objekt som helst, vilket kan utlösa godtycklig kodkörning om du bearbetar ett YAML-dokument som kommer från en opålitlig källa. Den här funktionen är inte nödvändig för Djangos YAML-deserializer, vars primära användning är att ladda fixturer som består av enkla objekt. Även om fixturer är betrodda data använder YAML-deserializern nu yaml.safe_load för ytterligare säkerhet.

Session cookies har nu flaggan httponly som standard

Sessionscookies innehåller nu attributet httponly som standard för att minska effekterna av potentiella XSS-attacker. Som en följd av denna ändring är data från sessionscookies, inklusive sessionid, inte längre tillgängliga från JavaScript i många webbläsare. För strikt bakåtkompatibilitet ska du använda SESSION_COOKIE_HTTPONLY = False i din inställningsfil.

Filtret urlize undviker inte längre alla URL:er

När en URL innehåller en %xx-sekvens, där xx är två hexadecimala siffror, antar urlize nu att URL:en redan är escapad och tillämpar inte URL-escaping igen. Detta är fel för webbadresser vars obekräftade form innehåller en %xx-sekvens, men det är mycket osannolikt att sådana webbadresser förekommer i naturen, eftersom de också skulle förvirra webbläsare.

assertTemplateUsed och assertTemplateNotUsed som kontexthanterare

Det är nu möjligt att kontrollera om en mall användes inom ett kodblock med assertTemplateUsed() och assertTemplateNotUsed(). Och de kan användas som en kontexthanterare:

with self.assertTemplateUsed("index.html"):
    render_to_string("index.html")
with self.assertTemplateNotUsed("base.html"):
    render_to_string("index.html")

Se :ref:` assertion documentation<assertions> för mer information.

Databasanslutningar efter körning av testsviten

Standardtestlöparen återställer inte längre databasanslutningarna efter att testerna har körts. Detta förhindrar att produktionsdatabasen exponeras för potentiella trådar som fortfarande skulle vara igång och försöka skapa nya anslutningar.

Om din kod förlitade sig på att anslutningar till produktionsdatabasen skapades efter testkörning, kan du återställa det tidigare beteendet genom att underklassa DjangoTestRunner och åsidosätta dess teardown_databases()-metod.

Utdata från manage.py help

manage.py help grupperar nu tillgängliga kommandon efter applikation. Om du var beroende av utdata från det här kommandot - om du till exempel analyserade det - måste du uppdatera din kod. Om du vill få en lista över alla tillgängliga hanteringskommandon i ett skript använder du manage.py help --commands istället.

förlänger mall tagg

Tidigare använde taggen extends en buggig metod för att parsa argument, vilket kunde leda till att den felaktigt betraktade ett argument som en stränglitual när det inte var det. Den använder nu parser.compile_filter, precis som andra taggar.

Taggens interna funktioner är inte en del av det officiella stabila API:et, men för att vara helt öppen har definitionen av ExtendsNode.__init__ ändrats, vilket kan förstöra alla anpassade taggar som använder den här klassen.

Laddning av vissa ofullständiga fixturer fungerar inte längre

Före 1.4 infogades ett standardvärde för fixturobjekt som saknade ett specifikt datum- eller datetime-värde när auto_now eller auto_now_add ställdes in för fältet. Detta var något som inte borde ha fungerat, och i 1.4 kommer laddning av sådana ofullständiga fixturer att misslyckas. Eftersom fixturer är en råimport bör de uttryckligen ange alla fältvärden, oavsett fältalternativ i modellen.

Utvecklingsserver Multithreading

Utvecklingsservern är nu flertrådig som standard. Använd alternativet runserver --nothreading för att inaktivera användningen av trådar i utvecklingsservern:

django-admin.py runserver --nothreading

Attribut inaktiverade i markdown när säkert läge är inställt

Före Django 1.4 inkluderades attribut i alla markdown-utdata oavsett filtrets inställning för säkert läge. Med version > 2.1 av Python-Markdown-biblioteket lades ett enable_attributes-alternativ till. När safe-argumentet skickas till markdown-filtret, ställs både afe_mode=True och enable_attributes=False in. Om du använder en version av Python-Markdown-biblioteket som är mindre än 2.1, utfärdas en varning om att utdata är osäkra.

FormMixin get_initial returnerar en instansspecifik ordbok

I Django 1.3 returnerade metoden get_initial i klassen django.views.generic.edit.FormMixin` klassens ordbok initial. Detta har åtgärdats så att en kopia av denna ordbok returneras, så att formulärinstanser kan ändra sina initiala data utan att röra vid klassvariabeln.

Funktioner som inte längre är aktuella i 1.4

Gamla sätt att anropa cache_page-dekoratorn

Vissa äldre sätt att anropa cache_page() har föråldrats. Se dokumentationen för det korrekta sättet att använda denna dekorator.

Stöd för PostgreSQL-versioner äldre än 8.2

Django 1.3 tappade stöd för PostgreSQL-versioner äldre än 8.0, och vi föreslog att man skulle använda en nyare version på grund av prestandaförbättringar och, ännu viktigare, slutet på uppströms supportperioder för 8.0 och 8.1 var nära (november 2010).

Django 1.4 tar den policyn vidare och ställer in 8.2 som den minsta PostgreSQL-versionen som den officiellt stöder.

Undantag från begäran loggas nu alltid

När vi lade till logging support i Django i 1.3, flyttades stödet för admin felmeddelanden till django.utils.log.AdminEmailHandler, kopplad till 'django.request' logger. För att bibehålla det etablerade beteendet för felmeddelanden anropades loggern 'django.request endast när DEBUG var False.

För att öka flexibiliteten i felloggningen för begäranden anropas nu loggern 'django.request' oavsett värdet på DEBUG, och standardinställningsfilen för nya projekt innehåller nu ett separat filter kopplat till django.utils.log.AdminEmailHandler för att förhindra e-postmeddelanden om administratörsfel i DEBUG-läge:

LOGGING = {
    # ...
    "filters": {
        "require_debug_false": {
            "()": "django.utils.log.RequireDebugFalse",
        }
    },
    "handlers": {
        "mail_admins": {
            "level": "ERROR",
            "filters": ["require_debug_false"],
            "class": "django.utils.log.AdminEmailHandler",
        }
    },
}

Om ditt projekt skapades före den här ändringen kommer din LOGGING-inställning inte att innehålla det här nya filtret. För att upprätthålla bakåtkompatibilitet kommer Django att upptäcka att din 'mail_admins hanterarkonfiguration inte innehåller något 'filters avsnitt och kommer automatiskt att lägga till det här filtret åt dig och utfärda en varning om att det är på väg att försvinna. Detta kommer att bli en deprecation-varning i Django 1.5, och i Django 1.6 kommer bakåtkompatibilitets-shim att tas bort helt.

Om det finns någon 'filters'-nyckel under 'mail_admins'-hanteraren inaktiveras denna bakåtkompatibilitetsvarning och deprecation-varning.

django.conf.urls.standardvärden

Fram till Django 1.3 fanns funktionerna include(), patterns() och url(), plus handler404 och handler500 i modulen django.conf.urls.defaults.

I Django 1.4 finns de i django.conf.urls.

django.contrib.databrowse

Databrowse har inte utvecklats aktivt under en längre tid och det finns inga tecken på att detta kommer att förändras. Det har funnits ett förslag om ett GSOC-projekt för att integrera funktionaliteten i databrowse i admin, men inga framsteg gjordes. Databrowse har utgått, men en förbättring av django.contrib.admin som ger en liknande funktionsuppsättning är fortfarande möjlig.

Koden som driver Databrowse är licensierad enligt samma villkor som Django själv, så den är tillgänglig för att antas av en individ eller grupp som ett tredjepartsprojekt.

django.core.management.setup_environ

Denna funktion modifierade temporärt sys.path för att göra den överordnade ”projekt”-katalogen importerbar under den gamla platta startproject-layouten. Den här funktionen är nu utdaterad, eftersom dess sökvägslösningar inte längre behövs med den nya manage.py och standardprojektlayouten.

Denna funktion var aldrig dokumenterad eller en del av det offentliga API:et, men den rekommenderades allmänt för användning för att ställa in en ”Django-miljö” för ett användarskript. Dessa användningar bör ersättas med att ställa in miljövariabeln DJANGO_SETTINGS_MODULE eller använda django.conf.settings.configure().

django.core.management.execute_manager

Denna funktion användes tidigare av manage.py för att utföra ett managementkommando. Den är identisk med django.core.management.execute_from_command_line, förutom att den först anropar setup_environ, som nu är föråldrad. Som sådan är execute_manager också föråldrad; execute_from_command_line kan användas istället. Ingen av dessa funktioner är dokumenterade som en del av det publika API:et, men en utfasningsväg behövs på grund av användning i befintliga manage.py-filer.

attributen is_safe och needs_autoescape för mallfilter

Två flaggor, is_safe och needs_autoescape, definierar hur varje mallfilter interagerar med Djangos auto-escaping-beteende. De brukade vara attribut för filterfunktionen:

@register.filter
def noop(value):
    return value


noop.is_safe = True

Denna teknik orsakade dock vissa problem i kombination med dekoratorer, särskilt @stringfilter. Nu är flaggorna nyckelordsargument för @register.filter:

@register.filter(is_safe=True)
def noop(value):
    return value

Se filter och automatisk särskrivning för mer information.

Jokerteckensexpansion av applikationsnamn i INSTALLED_APPS

Fram till Django 1.3 accepterade INSTALLED_APPS jokertecken i programnamn, som django.contrib.*. Utvidgningen utfördes av en filsystembaserad implementering av from <package> import *. Tyvärr kan detta inte göras på ett tillförlitligt sätt.

Detta beteende har aldrig dokumenterats. Eftersom det är opytoniskt togs det bort i Django 1.4. Om du förlitade dig på det måste du redigera din inställningsfil för att lista alla dina applikationer uttryckligen.

HttpRequest.raw_post_data bytt namn till HttpRequest.body

Detta attribut hade det förvirrande namnet HttpRequest.raw_post_data, men det innehöll faktiskt HTTP-begärans innehåll. Det har bytt namn till HttpRequest.body och HttpRequest.raw_post_data har utgått.

django.contrib.sitemaps buggfix med potentiell påverkan på prestanda

I tidigare versioner cachades Paginator-objekt som användes i sitemap-klasser, vilket kunde resultera i inaktuella webbplatskartor. Vi har tagit bort cachelagringen, så varje begäran till en webbplatskarta skapar nu ett nytt Paginator-objekt och anropar items()-metoden i Sitemap-underklassen. Beroende på vad din items()-metod gör kan detta ha en negativ inverkan på prestandan. För att mildra prestandapåverkan bör du överväga att använda caching framework i din underklass Sitemap.

Versioner av Python-Markdown tidigare än 2.1

Versioner av Python-Markdown tidigare än 2.1 stöder inte alternativet att inaktivera attribut. Som en säkerhetsfråga kommer tidigare versioner av detta bibliotek inte att stödjas av markup contrib-appen i 1.5 under en påskyndad avvecklingstidslinje.