Django 1.2 release notes

17 maj 2010.

Välkommen till Django 1.2!

Django 1.2 har nästan ett år på nacken och innehåller en imponerande lista med nya funktioner och massor av buggfixar. Dessa release notes täcker de nya funktionerna, liksom viktiga förändringar som du vill vara medveten om när du uppgraderar från Django 1.1 eller äldre versioner.

Översikt

Django 1.2 introducerar flera stora och viktiga nya funktioner, bland annat:

Det här är bara höjdpunkterna; fullständig information och en komplett lista över funktioner finns under.

Se även

Django Advent täckte lanseringen av Django 1.2 med en serie artiklar och handledningar som behandlar några av de nya funktionerna på djupet.

Där det är möjligt har dessa funktioner införts på ett bakåtkompatibelt sätt enligt vår API-stabilitetspolicy policy.

En handfull funktioner har dock ändrats på sätt som för vissa användare kommer att vara bakåtkompatibla. De stora förändringarna är:

  • Stöd för Python 2.3 har tagits bort. Se de fullständiga anteckningarna nedan.

  • Det nya ramverket för CSRF-skydd är inte bakåtkompatibelt med det gamla systemet. Användare av det gamla systemet kommer inte att påverkas förrän det gamla systemet tas bort i Django 1.4.

    Uppgradering till det nya ramverket för CSRF-skydd kräver dock några viktiga bakåtkompatibla ändringar, som beskrivs i CSRF-skydd nedan.

  • Författare av anpassade Field-underklasser bör vara medvetna om att ett antal metoder har fått en ändring i prototypen, som beskrivs under get_db_prep_*() methods on Field, nedan.

  • De interna egenskaperna hos malltaggar har ändrats något; författare av anpassade malltaggar som behöver lagra tillstånd (t.ex. anpassade kontrollflödes-taggar) bör se till att deras kod följer de nya reglerna för `stateful template tags`__

  • Dekoratorerna user_passes_test(), login_required(), och permission_required(), från django.contrib.auth gäller endast för funktioner och fungerar inte längre på metoder. Det finns en enkel fix på en rad detalj nedan.

Återigen, det här är bara de stora funktionerna som kommer att påverka de flesta användare. Användare som uppgraderar från tidigare versioner av Django uppmanas starkt att läsa den fullständiga listan över backwards-incompatible changes och listan över deprecated features.

Kompatibilitet med Python

Även om det inte är en ny funktion är det viktigt att notera att Django 1.2 introducerar den första förändringen i vår Python-kompatibilitetspolicy sedan Djangos första offentliga debut. Tidigare Django-utgåvor testades och stöddes på 2.x Python-versioner från 2.3 och uppåt; Django 1.2 släpper dock officiellt stöd för Python 2.3. Som sådan är den minsta Python-versionen som krävs för Django nu 2.4, och Django testas och stöds på Python 2.4, 2.5 och 2.6, och kommer att stödjas på den ännu inte släppta Python 2.7.

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

En färdplan för Djangos övergripande 2.x Python-stöd, och eventuell övergång till Python 3.x, utvecklas för närvarande och kommer att meddelas före lanseringen av Django 1.3.

Vad är nytt i Django 1.2

Stöd för flera databaser

Django 1.2 lägger till möjligheten att använda mer än en databas i ditt Django-projekt. Frågor kan ställas till en specifik databas med metoden using() på objekt av typen QuerySet. Enskilda objekt kan sparas till en specifik databas genom att tillhandahålla ett using argument när du anropar save().

Validering av modell

Modellinstanser har nu stöd för validering av sina egna data, och både modell- och formulärfält accepterar nu konfigurerbara listor med validatorer som anger återanvändbart, inkapslat valideringsbeteende. Observera dock att validering fortfarande måste utföras explicit. Att helt enkelt anropa en modellinstans save()-metod kommer inte att utföra någon validering av instansens data.

Förbättrat CSRF-skydd

Django har nu ett mycket förbättrat skydd mot Cross-Site Request Forgery (CSRF)-attacker. Denna typ av attack inträffar när en skadlig webbplats innehåller en länk, en formulärknapp eller något JavaScript som är avsett att utföra någon åtgärd på din webbplats med hjälp av inloggningsuppgifterna för en inloggad användare som besöker den skadliga webbplatsen i sin webbläsare. En relaterad typ av attack, ”login CSRF”, där en angripande webbplats lurar en användares webbläsare att logga in på en webbplats med någon annans inloggningsuppgifter, omfattas också.

Ramverk för meddelanden

Django innehåller nu ett robust och konfigurerbart messages framework med inbyggt stöd för cookie- och sessionsbaserad meddelandehantering, för både anonyma och autentiserade klienter. Meddelanderamen ersätter det föråldrade API:et för användarmeddelanden och gör att du tillfälligt kan lagra meddelanden i en begäran och hämta dem för visning i en efterföljande begäran (vanligtvis nästa).

Behörigheter på objektnivå

En grund för att specificera behörigheter på objektnivå har lagts till. Även om det inte finns någon implementering av detta i kärnan, kan en anpassad autentiseringsbackend tillhandahålla denna implementering och den kommer att användas av django.contrib.auth.models.User. Se authentication docs för mer information.

Behörigheter för anonyma användare

Om du tillhandahåller en anpassad autentiseringsbackend med supports_anonymous_user inställd på True, kommer AnonymousUser att kontrollera backend för behörigheter, precis som User redan gjorde. Detta är användbart för att centralisera behörighetshanteringen - appar kan alltid delegera frågan om något är tillåtet eller inte till auktoriserings-/autentiseringsbackend. Se authentication docs för mer information.

Lättare krav för användarnamn

Den inbyggda User-modellens username-fält tillåter nu ett större antal tecken, inklusive @, +, . och --tecken.

Backend för e-post

Du kan nu konfigurera hur Django skickar e-post. Istället för att använda SMTP för att skicka all e-post kan du nu välja en konfigurerbar e-postbackend för att skicka meddelanden. Om ditt webbhotell använder en sandlåda eller någon annan icke-SMTP-teknik för att skicka e-post, kan du nu konstruera en e-postbackend som gör det möjligt för Djangos standard metoder för e-postsändning att använda dessa faciliteter.

Detta gör det också lättare att felsöka e-postmeddelanden. Django levereras med backend-implementationer som gör att du kan skicka e-post till en fil, till konsolen eller till minnet. Du kan även konfigurera att all e-post ska kastas bort.

”Smart” if tag

Taggen if har uppgraderats till att bli mycket kraftfullare. Först har vi lagt till stöd för jämförelseoperatorer. Du behöver inte längre skriva:

{% ifnotequal a b %}
 ...
{% endifnotequal %}

Du kan nu göra detta:

{% if a != b %}
 ...
{% endif %}

Det finns egentligen ingen anledning att använda {% ifequal %} eller {% ifnotequal %} längre, såvida du inte är nostalgisk.

De operatorer som stöds är ==, !=, <, >, <=, >=, in och not in, som alla fungerar som Python-operatorer, utöver and, or och not, som redan stöddes.

Dessutom kan filter nu användas i if-uttrycket. Till exempel:

<div
  {% if user.email|lower == message.recipient|lower %}
    class="highlight"
  {% endif %}
>{{ message }}</div>

Cachelagring av mallar

I tidigare versioner av Django laddades en mall på nytt från disken varje gång du renderade den. I Django 1.2 kan du använda en cachad malladdare för att ladda mallar en gång och sedan cacha resultatet för varje efterföljande rendering. Detta kan leda till en betydande prestandaförbättring om dina mallar är uppdelade i många mindre undermallar (med hjälp av taggarna {% extends %} eller {% include %}).

Som en bieffekt är det nu mycket lättare att stödja mallspråk som inte är Django.

Klassbaserade mallladdare

Som en del av de ändringar som gjorts för att införa Template caching och som följer en allmän trend i Django, har API:et för mallladdare modifierats för att använda mallladdningsmekanismer som är inkapslade i Python-klasser i motsats till funktioner, den enda tillgängliga metoden fram till Django 1.1.

Alla mallladdare levereras med Django har portats till det nya API men de implementerar fortfarande det funktionsbaserade API och mallkärnmaskineriet accepterar fortfarande funktionsbaserade laddare (inbyggda eller tredje part) så det finns inget omedelbart behov av att ändra din TEMPLATE_LOADERS-inställning i befintliga projekt, saker och ting kommer att fortsätta fungera om du lämnar det orört fram till och med Django 1.3-versionen.

Om du har utvecklat dina egna anpassade template-laddare föreslår vi att du överväger att porta dem till en klassbaserad implementering eftersom koden för bakåtkompatibilitet med funktionsbaserade laddare börjar sin deprecieringsprocess i Django 1.2 och kommer att tas bort i Django 1.4. Det finns en beskrivning av API:et som dessa klasser av laddare måste implementera i mallens API-referens och du kan också undersöka källkoden för de laddare som levereras med Django.

Naturliga nycklar i fixturer

Fixturer kan nu referera till fjärrobjekt med hjälp av Naturliga nycklar. Detta uppslagsschema är ett alternativ till de normala primärnyckelbaserade objektreferenserna i en fixtur, vilket förbättrar läsbarheten och löser problem med att referera till objekt vars primärnyckelvärde kanske inte är förutsägbart eller känt.

Snabbt fel vid tester

Både underkommandot test i django-admin.py och skriptet runtests.py som används för att köra Djangos egen testsvit har nu stöd för alternativet --failfast. När detta alternativ anges får det testköraren att avsluta efter att ha stött på ett fel istället för att fortsätta med testkörningen. Dessutom har hanteringen av Ctrl-C under en testkörning förbättrats för att utlösa en elegant avslutning från testkörningen som rapporterar detaljer om de tester som kördes före avbrottet.

BigIntegerField

Modeller kan nu använda en 64-bitars BigIntegerField-typ.

Förbättrad lokalisering

Djangos internationaliseringsramverk har utökats med lokalmedveten formatering och formulärbehandling. Det innebär att om det är aktiverat kommer datum och siffror på mallar att visas med det format som anges för den aktuella lokalen. Django kommer också att använda lokala format när data analyseras i formulär. Se Lokalisering av format för mer information.

readonly_fields i ModelAdmin

django.contrib.admin.ModelAdmin.readonly_fields har lagts till för att aktivera icke-redigerbara fält på tilläggs-/ändringssidor för modeller och inlines. Fält och beräknade värden kan visas tillsammans med redigerbara fält.

Anpassningsbar syntaxmarkering

Du kan nu använda en DJANGO_COLORS miljövariabel för att ändra eller inaktivera de färger som används av django-admin.py för att tillhandahålla syntaxmarkering.

Syndikering av flöden som visningar

Syndication feeds kan nu användas direkt som vyer i din URLconf. Detta innebär att du kan behålla fullständig kontroll över URL-strukturen i dina feeds. Som alla andra vyer skickas feeds-vyer ett request-objekt, så du kan göra allt du normalt skulle göra med en vy, som användarbaserad åtkomstkontroll eller göra ett flöde till en namngiven URL.

GeoDjango

Den mest betydande nya funktionen för GeoDjango i 1.2 är stöd för flera spatiala databaser. Som ett resultat av detta ingår nu följande spatial database backends:

  • django.contrib.gis.db.backends.postgis

  • django.contrib.gis.db.backends.mysql

  • django.contrib.gis.db.backends.oracle

  • django.contrib.gis.db.backends.spatialite

GeoDjango stöder nu de rika funktioner som lagts till i PostGIS 1.5-versionen. Nya funktioner inkluderar stöd för geografitypen och aktivering av distansfrågor med icke-punktgeometrier på geografiska koordinatsystem.

Stöd för 3D-geometrifält har lagts till och kan aktiveras genom att ställa in nyckelordet dim till 3 i din GeometryField. Aggregatet Extent3D och metoden extent3d() GeoQuerySet lades till som en del av denna funktion.

Metoderna force_rhr(), reverse_geom() och geohash() GeoQuerySet är nya.

GEOS-gränssnittet har uppdaterats för att använda trådsäkra C-biblioteksfunktioner när sådana finns tillgängliga på plattformen.

GDAL-gränssnittet gör det nu möjligt för användaren att ange en spatial_filter på de funktioner som returneras när man itererar över en Layer.

Slutligen, GeoDjangos dokumentation ingår nu i Djangos och är inte längre värd separat på geodjango.org.

Nya tecken för formatangivelse för now malltagg: c och u

Argumentet till now har fått två nya formattecken: c för att ange att ett datetime-värde ska formateras i ISO 8601-format, och u som tillåter utmatning av mikrosekunderna i ett datetime- eller tidsvärde.

Dessa finns också tillgängliga i andra delar som mallfiltren date och time, malltaggbiblioteket humanize och det nya ramverket format localization.

Bakåtkompatibla ändringar i 1.2

Där det är möjligt har de nya funktionerna ovan införts på ett bakåtkompatibelt sätt enligt vår API-stabilitetspolicy policy. Detta innebär att praktiskt taget all befintlig kod som fungerade med Django 1.1 kommer att fortsätta att fungera med Django 1.2; sådan kod kommer dock att börja utfärda varningar (se nedan för detaljer).

En handfull funktioner har dock ändrats på sätt som för vissa användare omedelbart kommer att vara bakåtkompatibla. Dessa ändringar beskrivs närmare nedan.

CSRF-skydd

Vi har gjort stora förändringar i hur CSRF-skydd fungerar, vilket beskrivs i :doc:` CSRF-dokumentationen </ref/csrf>`. Här är de största förändringarna som du bör känna till:

  • CsrfResponseMiddleware och CsrfMiddleware har föråldrats och kommer att tas bort helt i Django 1.4, till förmån för en malltagg som ska infogas i formulär.

  • Alla Contrib-appar använder en csrf_protect-dekorator för att skydda vyn. Detta kräver användning av malltaggen csrf_token i mallen. Om du har använt anpassade mallar för Contrib-vyer MÅSTE du läsa uppgraderingsinstruktionerna för att åtgärda dessa mallar.

    Dokumentation borttagen

    Uppgraderingsanvisningarna har tagits bort i nuvarande Django-dokument. Se dokumenten för Django 1.3 eller äldre för att hitta dessa instruktioner.

  • CsrfViewMiddleware ingår som standard i MIDDLEWARE_CLASSES. Detta aktiverar CSRF-skydd som standard, så vyer som accepterar POST-förfrågningar måste skrivas för att fungera med mellanvaran. Instruktioner om hur man gör detta finns i CSRF-dokumenten.

  • All CSRF har flyttats från contrib till core (med bakåtkompatibel import på de gamla platserna, som är föråldrade och kommer att upphöra att stödjas i Django 1.4).

get_db_prep_*() metoder på Field

Före Django 1.2 hade ett anpassat Field möjlighet att definiera flera funktioner för att stödja konvertering av Python-värden till databaskompatibla värden. Ett anpassat fält kan se ut ungefär som:

class CustomModelField(models.Field):
    ...

    def db_type(self): ...

    def get_db_prep_save(self, value): ...

    def get_db_prep_value(self, value): ...

    def get_db_prep_lookup(self, lookup_type, value): ...

I 1.2 har dessa tre metoder genomgått en prototypförändring och två extra metoder har införts:

class CustomModelField(models.Field):
    ...

    def db_type(self, connection): ...

    def get_prep_value(self, value): ...

    def get_prep_lookup(self, lookup_type, value): ...

    def get_db_prep_save(self, value, connection): ...

    def get_db_prep_value(self, value, connection, prepared=False): ...

    def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False): ...

Dessa ändringar krävs för att stödja flera databaser – db_type och get_db_prep_* kan inte längre göra några antaganden om databasen som den förbereder för. Argumentet connection förser nu förberedelsemetoderna med den specifika anslutning som värdet förbereds för.

De två nya metoderna finns för att skilja allmänna krav på dataförberedelse från krav som är databasspecifika. Argumentet prepared används för att ange för databasförberedelsemetoderna om generisk värdeförberedelse har utförts. Om ett oförberett (d.v.s. prepared=False) värde tillhandahålls till get_db_prep_*()-anropen, bör de anropa motsvarande get_prep_*()-anrop för att utföra generisk dataförberedelse.

Vi har tillhandahållit konverteringsfunktioner som på ett transparent sätt konverterar funktioner som följer den gamla prototypen till funktioner som är kompatibla med den nya prototypen. Dessa konverteringsfunktioner kommer dock att tas bort i Django 1.4, så du bör uppgradera dina Field-definitioner så att de använder den nya prototypen så snart som möjligt.

Om dina get_db_prep_*()-metoder inte använde sig av databasanslutningen bör du kunna uppgradera genom att byta namn på get_db_prep_value() till get_prep_value() och get_db_prep_lookup() till get_prep_lookup(). Om du behöver databasspecifika konverteringar måste du tillhandahålla en implementering av get_db_prep_* som använder argumentet connection för att lösa databasspecifika värden.

Statliga malltaggar

Malltaggar som lagrar renderingstillstånd på sin Node-underklass har alltid varit sårbara för trådsäkerhet och andra problem; från och med Django 1.2 kan de dock också orsaka problem när de används med den nya cached template loader.

Alla de inbyggda Django-malltaggarna är säkra att använda med den cachade laddaren, men om du använder anpassade malltaggar som kommer från tredjepartspaket eller från din egen kod, bör du se till att Node-implementeringen för varje tagg är trådsäker. För mer information, se överväganden om trådsäkerhet för malltaggar.

Du kan också behöva uppdatera dina mallar om du förlitade dig på att implementeringen av Djangos malltaggar inte var trådsäkra. Taggen cycle är den som mest sannolikt kommer att påverkas på detta sätt, särskilt när den används tillsammans med taggen include. Tänk på följande mallfragment:

{% for object in object_list %}
    {% include "subtemplate.html" %}
{% endfor %}

med en subtemplate.html som lyder:

{% cycle 'even' 'odd' %}

Om man använder den icke-trådssäkra renderaren från före Django 1.2 skulle detta ge utdata:

even odd even odd ...

Om du använder den trådsäkra renderingstjänsten Django 1.2 får du istället:

even even even even ...

Detta beror på att varje rendering av include-taggen är en oberoende rendering. När taggen cycle inte var trådsäker kunde tillståndet för taggen cycle läcka mellan flera renderingar av samma tagg include. Nu när cycle-taggen är trådsäker sker inte längre detta läckage.

user_passes_test, login_required och permission_required

django.contrib.auth.decorators tillhandahåller dekoratorerna login_required, permission_required och user_passes_test. Tidigare var det möjligt att använda dessa dekoratorer både på funktioner (där det första argumentet är ’request’) och på metoder (där det första argumentet är ’self’ och det andra argumentet är ’request’). Tyvärr upptäcktes brister i koden som stöder detta: det fungerar bara under begränsade omständigheter och producerar fel som är mycket svåra att felsöka när det inte fungerar.

Av denna anledning har ”auto adapt”-beteendet tagits bort, och om du använder dessa dekoratorer på metoder måste du manuellt tillämpa django.utils.decorators.method_decorator() för att konvertera dekoratorn till en som fungerar med metoder. Till exempel skulle du ändra kod från detta:

class MyClass(object):
    @login_required
    def my_view(self, request):
        pass

till detta:

from django.utils.decorators import method_decorator


class MyClass(object):
    @method_decorator(login_required)
    def my_view(self, request):
        pass

eller:

from django.utils.decorators import method_decorator

login_required_m = method_decorator(login_required)


class MyClass(object):
    @login_required_m
    def my_view(self, request):
        pass

För er som har följt utvecklingen i trunken gäller den här ändringen även andra dekoratorer som har införts sedan 1.1, inklusive csrf_protect, cache_control och allt som skapats med decorator_from_middleware.

if tagg ändras

På grund av nya funktioner i if-malltaggen accepterar den inte längre ’and’, ’or’ och ’not’ som giltiga variabel-namn. Tidigare kunde dessa strängar användas som variabelnamn. Nu tillämpas alltid nyckelordets status, och mallkod som {% if not %} eller {% if and %} kommer att ge upphov till ett TemplateSyntaxError. Dessutom är in ett nytt nyckelord och är därför inte ett giltigt variabelnamn i den här taggen.

LazyObject

LazyObject är en odokumenterad men ofta använd verktygsklass som används för att lättsamt förpacka andra objekt av okänd typ.

I Django 1.1 och tidigare hanterade den introspektion på ett icke-standardiserat sätt, beroende på att omslutna objekt implementerade en offentlig metod med namnet get_all_members(). Eftersom detta lätt kan leda till namnkrockar har det ändrats till att använda Pythons standardmetod för introspektion, som involverar __members__ och __dir__().

Om du har använt LazyObject i din egen kod och implementerat metoden get_all_members() för omslutna objekt, måste du göra ett par ändringar:

För det första, om din klass inte har några speciella krav på introspektion (dvs. du har inte implementerat __getattr__() eller andra metoder som möjliggör attribut som inte kan upptäckas genom normala mekanismer), kan du helt enkelt ta bort get_all_members()-metoden. Standardimplementeringen på LazyObject kommer att göra det rätta.

Om du har mer komplexa krav på introspektion, byt först namn på metoden get_all_members() till __dir__(). Detta är standardmetoden för introspektion för Python 2.6 och senare. Om du behöver stöd för Python-versioner tidigare än 2.6, lägg till följande kod i klassen:

__members__ = property(lambda self: self.__dir__())

__dict__ på modellinstanser

Historiskt sett har attributet __dict__ för en modellinstans endast innehållit attribut som motsvarar fälten i en modell.

För att stödja flera databaskonfigurationer har Django 1.2 lagt till ett _state-attribut till objektinstanser. Detta attribut kommer att visas i __dict__ för en modellinstans. Om din kod förlitar sig på att iterera över __dict__ för att få en lista över fält, måste du nu vara beredd att hantera eller filtrera bort attributet _state.

Statuskod för testkörarens utgång

Utgångsstatuskoden för testlöparna (tests/runtests.py och python manage.py test) representerar inte längre antalet misslyckade tester, eftersom ett misslyckande med 256 eller fler tester resulterade i en felaktig utgångsstatuskod. Exit-statuskoden för testköraren är nu 0 för framgång (inga misslyckade tester) och 1 för valfritt antal misslyckade tester. Om det behövs kan antalet misslyckade tester hittas i slutet av testlöparens utdata.

ModelForm.is_valid() och ModelForm.errors

Mycket av valideringsarbetet för ModelForms har flyttats ner till modellnivån. Som ett resultat kommer din modell att rengöras på plats första gången du anropar ModelForm.is_valid(), får tillgång till ModelForm.errors eller på annat sätt utlöser formulärvalidering. Denna konvertering brukade ske när modellen sparades. Om du behöver en omodifierad instans av din modell, bör du skicka en kopia till ModelForm-konstruktören.

BooleanField på MySQL

I tidigare versioner av Django skulle en modells BooleanField under MySQL returnera sitt värde som antingen 1 eller 0, istället för True eller False; för de flesta människor var detta inte ett problem eftersom bool är en underklass av int i Python. I Django 1.2 returnerar dock BooleanField på MySQL korrekt en riktig bool. Den enda gången detta någonsin skulle vara ett problem är om du förväntade dig att repr av en BooleanField skulle skriva ut 1 eller 0.

Ändringar av tolkningen av max_num i FormSets

Som en del av förbättringarna i hanteringen av FormSets har standardvärdet och tolkningen av parametern max_num i funktionerna django.forms.formsets.formset_factory() och django.forms.models.modelformset_factory() ändrats något. Denna ändring påverkar också hur argumentet max_num används för inline admin-objekt.

Tidigare var standardvärdet för max_num 0 (noll). FormSets använde sedan det booleska värdet för max_num för att avgöra om en begränsning skulle införas för antalet genererade formulär. Standardvärdet 0 innebar att det inte fanns någon standardbegränsning för antalet formulär i en FormSet.

Från och med 1.2 har standardvärdet för max_num ändrats till None, och FormSets kommer att skilja mellan ett värde på None och ett värde på 0. Ett värde på None innebär att ingen begränsning av antalet formulär skall införas, medan ett värde på 0 innebär att högst 0 formulär skall införas. Detta betyder inte nödvändigtvis att inga formulär kommer att visas - se :ref:ModelFormSet documentation <model-formsets-max-num> för mer information.

Om du manuellt angav ett värde på ”0” för ”max_num” måste du uppdatera dina FormSet- och/eller admin-definitioner.

Se även

1.2-js-assisterade-linjer

e-post

Ett odokumenterat reguljärt uttryck för validering av e-postadresser har flyttats från django.form.fields till django.core.validators. Du måste uppdatera dina importer om du använder det.

Funktioner som inte längre är aktuella i 1.2

Slutligen, Django 1.2 tar bort vissa funktioner från tidigare utgåvor. Dessa funktioner stöds fortfarande, men kommer gradvis att fasas ut under de kommande utgivningscyklerna.

Kod som utnyttjar någon av funktionerna nedan kommer att ge upphov till en PendingDeprecationWarning i Django 1.2. Denna varning är tyst som standard, men kan aktiveras med Pythons modul warnings eller genom att köra Python med flaggan -Wd eller -Wall.

I Django 1.3 kommer dessa varningar att bli en DeprecationWarning, som inte är tyst. I Django 1.4 kommer stödet för dessa funktioner att tas bort helt och hållet.

Se även

För mer information, se dokumentationen Djangos releaseprocess och vår deprecation tidslinje.`

Specificering av databaser

Före Django 1.2 använde Django ett antal inställningar för att styra åtkomsten till en enda databas. Med Django 1.2 införs stöd för flera databaser och därmed har sättet att definiera databasinställningar ändrats.

Alla befintliga Django-inställningsfiler kommer att fortsätta att fungera som förväntat fram till Django 1.4. Fram till dess kommer gamla databasinställningar automatiskt att översättas till det nya formatet.

I det gamla formatet (före 1.2) hade du ett antal inställningar för DATABASE_ i din inställningsfil. Till exempel:

DATABASE_NAME = "test_db"
DATABASE_ENGINE = "postgresql_psycopg2"
DATABASE_USER = "myusername"
DATABASE_PASSWORD = "s3krit"

Dessa inställningar finns nu i en ordbok med namnet DATABASES. Varje objekt i ordlistan motsvarar en enda databasanslutning, där namnet 'default' beskriver standardanslutningen till databasen. Namnen på inställningarna har också förkortats. De tidigare exempelinställningarna skulle nu se ut så här:

DATABASES = {
    "default": {
        "NAME": "test_db",
        "ENGINE": "django.db.backends.postgresql_psycopg2",
        "USER": "myusername",
        "PASSWORD": "s3krit",
    }
}

Detta påverkar följande inställningar:

Gammal inställning

Ny inställning

DATABAS_MOTOR

:inställning:`ENGINE <DATABASE-ENGINE>`

DATABAS_HOST

:inställning:`HOST`

DATABAS_NAMN

:inställning:`NAME`

DATABAS_ALTERNATIV

:inställning:`OPTIONS`

DATABAS_LÖSENORD

:inställning:`PASSWORD`

DATABAS_PORT

:inställning:`PORT`

DATABAS_ANVÄNDARE

:inställning:`USER`

TEST_DATABASE_CHARSET

:inställning:`TEST_CHARSET`

TEST_DATABAS_COLLATION

:inställning:`TEST_COLLATION`

TEST_DATABAS_NAMN

:inställning:`TEST_NAME`

Dessa ändringar krävs också om du manuellt har skapat en databasanslutning med hjälp av DatabaseWrapper() från din valda databasbackend.

Förutom förändringen i strukturen tar Django 1.2 bort specialhanteringen för de inbyggda databasbackends. Alla databasbackends måste nu specificeras med ett fullständigt kvalificerat modulnamn (dvs. django.db.backends.postgresql_psycopg2, snarare än bara postgresql_psycopg2).

postgresql databas backend

Biblioteket psycopg1 har inte uppdaterats sedan oktober 2005. Som ett resultat av detta har databasbackend postgresql, som använder detta bibliotek, blivit föråldrad.

Om du för närvarande använder postgresql backend, bör du migrera till att använda postgresql_psycopg2 backend. För att uppdatera din kod, installera biblioteket psycopg2 och ändra inställningen ENGINE till att använda django.db.backends.postgresql_psycopg2.

CSRF-svar-omskrivning middleware

CsrfResponseMiddleware, mellanvaran som automatiskt infogade CSRF-tokens i POST formulär på utgående sidor, har utgått till förmån för en template tag metod (se ovan) och kommer att tas bort helt i Django 1.4. CsrfMiddleware, som inkluderar funktionaliteten i CsrfResponseMiddleware och CsrfViewMiddleware, har likaså utgått.

CSRF-modulen har också flyttats från contrib till core, och de gamla importerna är utdaterade, vilket beskrivs i uppgraderingsanvisningarna.

Dokumentation borttagen

Uppgraderingsanvisningarna har tagits bort i nuvarande Django-dokument. Se dokumenten för Django 1.3 eller äldre för att hitta dessa instruktioner.

SMTPC-anslutning

Klassen SMTPConnection har utgått till förmån för ett generiskt API för e-postbackend. Gammal kod som uttryckligen instantierade en instans av en SMTPConnection:

from django.core.mail import SMTPConnection

connection = SMTPConnection()
messages = get_notification_email()
connection.send_messages(messages)

…bör nu anropa get_connection() för att instansiera en generisk e-postanslutning:

from django.core.mail import get_connection

connection = get_connection()
messages = get_notification_email()
connection.send_messages(messages)

Beroende på värdet för inställningen EMAIL_BACKEND är det inte säkert att en SMTP-anslutning returneras. Om du uttryckligen vill ha en SMTP-anslutning för att skicka e-post kan du uttryckligen begära en SMTP-anslutning:

from django.core.mail import get_connection

connection = get_connection("django.core.mail.backends.smtp.EmailBackend")
messages = get_notification_email()
connection.send_messages(messages)

Om ditt anrop för att konstruera en instans av SMTPConnection kräver ytterligare argument, kan dessa argument skickas till get_connection()-anropet:

connection = get_connection(
    "django.core.mail.backends.smtp.EmailBackend", hostname="localhost", port=1234
)

API för användarmeddelanden

API:et för att lagra meddelanden i användarens Message-modell (via user.message_set.create) är nu föråldrat och kommer att tas bort i Django 1.4 enligt standarden release-process.

För att uppgradera din kod måste du ersätta alla instanser av detta:

user.message_set.create("a message")

…med följande:

from django.contrib import messages

messages.add_message(request, messages.INFO, "a message")

Om du använder dig av metoden måste du dessutom byta ut följande:

for message in user.get_and_delete_messages():
    ...

…med:

from django.contrib import messages

for message in messages.get_messages(request):
    ...

För mer information, se hela meddelanden dokumentation. Du bör börja uppdatera din kod för att använda det nya API:et omedelbart.

Hjälpfunktioner för datumformat

django.utils.translation.get_date_formats() och django.utils.translation.get_partial_date_formats() har utgått till förmån för lämpliga anrop till django.utils.formats.get_format(), som är lokalmedveten när USE_L10N är inställd på True, och återgår till standardinställningar om den är inställd på False.

För att få de olika datumformaten, istället för att skriva detta:

from django.utils.translation import get_date_formats

date_format, datetime_format, time_format = get_date_formats()

…använd:

from django.utils import formats

date_format = formats.get_format("DATE_FORMAT")
datetime_format = formats.get_format("DATETIME_FORMAT")
time_format = formats.get_format("TIME_FORMAT")

Eller, vid direktformatering av ett datumvärde:

from django.utils import formats

value_formatted = formats.date_format(value, "DATETIME_FORMAT")

Detsamma gäller för de globaler som finns i django.forms.fields:

  • STANDARD_DATUM_INMATNINGSFORMAT

  • STANDARD_TID_INMATNINGSFORMAT

  • STANDARD_DATATID_INMATNINGSFORMAT

Använd django.utils.formats.get_format() för att få lämpliga format.

Funktionsbaserade testlöpare

Django 1.2 ändrar verktygen för testlöpare till att använda ett klassbaserat tillvägagångssätt. Gamla funktionsbaserade testlöpare kommer fortfarande att fungera, men bör uppdateras för att använda de nya klassbaserade löparna.

Feed i django.contrib.syndication.feeds

Klassen django.contrib.syndication.feeds.Feed har ersatts av klassen django.contrib.syndication.views.Feed`. Den gamla klassen feeds.Feed är föråldrad och kommer att tas bort i Django 1.4.

Den nya klassen har ett nästan identiskt API, men gör det möjligt att använda instanser som vyer. Tänk till exempel på användningen av det gamla ramverket i följande URLconf:

from django.conf.urls.defaults import *
from myproject.feeds import LatestEntries, LatestEntriesByCategory

feeds = {
    "latest": LatestEntries,
    "categories": LatestEntriesByCategory,
}

urlpatterns = patterns(
    "",
    # ...
    (
        r"^feeds/(?P<url>.*)/$",
        "django.contrib.syndication.views.feed",
        {"feed_dict": feeds},
    ),
    # ...
)

Med hjälp av den nya Feed-klassen kan dessa feeds distribueras direkt som vyer:

from django.conf.urls.defaults import *
from myproject.feeds import LatestEntries, LatestEntriesByCategory

urlpatterns = patterns(
    "",
    # ...
    (r"^feeds/latest/$", LatestEntries()),
    (r"^feeds/categories/(?P<category_id>\d+)/$", LatestEntriesByCategory()),
    # ...
)

Om du för närvarande använder vyn feed(), behöver klassen LatestEntries ofta inte ändras förutom att underklassa den nya Feed-klassen. Undantaget är om Django automatiskt räknar ut namnet på den mall som ska användas för att återge flödets beskrivnings- och titelelement (om du inte anger attributen title_template och description_template). Du bör se till att du alltid anger attributen title_template och description_template eller tillhandahåller metoderna item_title() och item_description().

Men LatestEntriesByCategory använder metoden get_object() med argumentet bits för att ange en specifik kategori som ska visas. I den nya Feed-klassen tar get_object()-metoden en request och argument från URL:en, så det skulle se ut så här:

from django.contrib.syndication.views import Feed
from django.shortcuts import get_object_or_404
from myproject.models import Category


class LatestEntriesByCategory(Feed):
    def get_object(self, request, category_id):
        return get_object_or_404(Category, id=category_id)

    # ...

Dessutom tar get_feed()-metoden i Feed-klasserna nu olika argument, vilket kan påverka dig om du använder Feed-klasserna direkt. Istället för att bara ta ett valfritt url-argument tar den nu två argument: det objekt som returneras av dess egen get_object()-metod och det aktuella request-objektet.

För att ta hänsyn till att Feed-klasser inte initialiseras för varje förfrågan, tar __init__()-metoden nu inga argument som standard. Tidigare skulle den ha tagit slug från URL:en och request-objektet.

I enlighet med RSS best practices kommer RSS-flöden nu att innehålla ett atom:link-element. Du kan behöva uppdatera dina tester för att ta hänsyn till detta.

För mer information, se den fullständiga syndication ramdokumentation.

ID:n för tekniska meddelanden

Fram till version 1.1 använde Django tekniska meddelande-ID:n för att ge lokaliserare möjlighet att översätta datum- och tidsformat. De var översättningsbara översättningssträngar som kunde identifieras eftersom de alla var versaler (till exempel DATETIME_FORMAT, DATE_FORMAT, TIME_FORMAT). De har utgått till förmån för den nya Lokalisering av format-infrastrukturen som gör det möjligt för lokaliserare att ange den informationen i en formats.py-fil i motsvarande django/conf/locale/<locale name>/-katalog.

GeoDjango

För att möjliggöra stöd för flera databaser ändrades GeoDjangos databasinterna funktioner avsevärt. Den största bakåtkompatibla förändringen är att modulen django.contrib.gis.db.backend döptes om till django.contrib.gis.db.backends`, där den fullfjädrade spatial database backends nu finns. I följande avsnitt finns information om de mest populära API:erna som påverkades av dessa ändringar.

SpatialBackend

Före skapandet av de separata spatiala backend-objekten tillhandahölls objektet django.contrib.gis.db.backend.SpatialBackend som en abstraktion för att introspektera kapaciteten hos den spatiala databasen. Alla attribut och rutiner som tillhandahålls av SpatialBackend är nu en del av ops-attributet för databasens backend.

Den gamla modulen django.contrib.gis.db.backend tillhandahålls fortfarande för bakåtkompatibilitet med tillgång till ett SpatialBackend-objekt, som bara är ett alias till ops-modulen för standard spatial databasanslutning.

Användare som förlitade sig på odokumenterade moduler och objekt inom django.contrib.gis.db.backend, snarare än de abstraktioner som tillhandahålls av SpatialBackend, måste ändra sin kod. Till exempel, följande import som skulle fungera i 1.1 och nedan:

from django.contrib.gis.db.backend.postgis import PostGISAdaptor

Skulle behöva ändras:

from django.db import connection

PostGISAdaptor = connection.ops.Adapter

modellerna SpatialRefSys och GeometryColumns

I tidigare versioner av GeoDjango hade django.contrib.gis.db.models modellerna SpatialRefSys och GeometryColumns för att fråga OGC:s spatiala metadatatabeller spatial_ref_sys respektive geometry_columns.

Dessa alias tillhandahålls fortfarande, men de gäller endast för standard-databasanslutningen och existerar endast om standardanslutningen använder en spatial databasbackend som stöds.

Observera

Eftersom tabellstrukturen för OGC:s spatiala metadatatabeller skiljer sig åt mellan olika spatiala databaser kan modellerna SpatialRefSys och GeometryColumns inte längre associeras med applikationsnamnet gis. Inga modeller kommer därför att returneras när man använder metoden get_models i följande exempel:

>>> from django.db.models import get_app, get_models
>>> get_models(get_app("gis"))
[]

För att få rätt SpatialRefSys och GeometryColumns för din spatiala databas, använd de metoder som tillhandahålls av den spatiala backend:

>>> from django.db import connections
>>> SpatialRefSys = connections["my_spatialite"].ops.spatial_ref_sys()
>>> GeometryColumns = connections["my_postgis"].ops.geometry_columns()

Observera

När du använder de modeller som returneras från metoderna spatial_ref_sys() och geometry_columns() måste du fortfarande använda rätt databasalias när du ställer frågor på anslutningen som inte är standard. Med andra ord, för att se till att modellerna i exemplet ovan använder rätt databas:

sr_qs = SpatialRefSys.objects.using("my_spatialite").filter(...)
gc_qs = GeometryColumns.objects.using("my_postgis").filter(...)

Språkkod no

Den för närvarande använda språkkoden för norskt bokmål no ersätts av den mer vanliga språkkoden nb.

Funktionsbaserade mallladdare

Django 1.2 ändrar mekanismen för mallinläsning till att använda en klassbaserad metod. Gamla funktionsbaserade mallladdare kommer fortfarande att fungera, men bör uppdateras för att använda de nya klassbaserade mallladdarna.