Porta dina appar från Django 0.96 till 1.0¶
Django 1.0 bryter kompatibiliteten med 0.96 i vissa områden.
Den här guiden hjälper dig att porta 0.96-projekt och appar till 1.0. Den första delen av detta dokument innehåller de vanliga ändringar som behövs för att köra med 1.0. Om din kod fortfarande inte fungerar efter att du har gått igenom den första delen kan du läsa avsnittet Mindre vanliga ändringar för en lista över ett antal mindre vanliga kompatibilitetsproblem.
Se även
Den 1.0 versionsinformation. Det dokumentet förklarar de nya funktionerna i 1.0 mer ingående; portningsguiden är mer inriktad på att hjälpa dig att snabbt uppdatera din kod.
Vanliga förändringar¶
I detta avsnitt beskrivs de ändringar mellan 0.96 och 1.0 som de flesta användare kommer att behöva göra.
Använd Unicode¶
Ändra stränglitteraler ('foo') till Unicode-litteraler (u'foo'). Django använder nu Unicode-strängar genomgående. På de flesta ställen kommer råa strängar att fortsätta att fungera, men uppdatering till att använda Unicode-litteraler kommer att förhindra vissa obskyra problem.
Se Unicode-data för fullständig information.
Modeller¶
Vanliga ändringar i din models-fil:
Byt namn på maxlength till max_length¶
Byt namn på argumentet maxlength till max_length (detta ändrades för att vara konsekvent med formulärfält):
Ersätt __str__ med __unicode__¶
Ersätt din modells funktion __str__ med en metod __unicode__ och se till att du använder Unicode (u'foo') i den metoden.
Ta bort prepopulated_from¶
Ta bort prepopulated_from-argumentet på modellfält. Det är inte längre giltigt och har flyttats till klassen ModelAdmin i admin.py. Se admin nedan för mer information om ändringar i admin.
Ta bort kärna¶
Ta bort core-argumentet från dina modellfält. Det är inte längre nödvändigt, eftersom motsvarande funktionalitet (en del av inline editing) hanteras annorlunda av admin-gränssnittet nu. Du behöver inte oroa dig för inline-redigering förrän du kommer till avsnittet Admin nedan. För tillfället, ta bort alla referenser till core.
Ersätt class Admin: med admin.py¶
Ta bort alla dina inre class Admin-deklarationer från dina modeller. De kommer inte att förstöra något om du låter dem vara kvar, men de kommer inte heller att göra något. För att registrera appar med administratören kommer du att flytta dessa deklarationer till en admin.py-fil; se the admin nedan för mer information.
Se även
En bidragsgivare till djangosnippets har skrivit ett skript som söker igenom din models.py och genererar en motsvarande admin.py.
Exempel¶
Nedan följer ett exempel på filen models.py med alla de ändringar du behöver göra:
Gammal (0.96) models.py:
class Author(models.Model):
    first_name = models.CharField(maxlength=30)
    last_name = models.CharField(maxlength=30)
    slug = models.CharField(maxlength=60, prepopulate_from=("first_name", "last_name"))
    class Admin:
        list_display = ["first_name", "last_name"]
    def __str__(self):
        return "%s %s" % (self.first_name, self.last_name)
Ny (1.0) models.py:
class Author(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    slug = models.CharField(max_length=60)
    def __unicode__(self):
        return "%s %s" % (self.first_name, self.last_name)
Ny (1.0) admin.py:
from django.contrib import admin
from models import Author
class AuthorAdmin(admin.ModelAdmin):
    list_display = ["first_name", "last_name"]
    prepopulated_fields = {"slug": ("first_name", "last_name")}
admin.site.register(Author, AuthorAdmin)
Administratören¶
En av de största förändringarna i 1.0 är den nya administratören. Djangos administrativa gränssnitt (django.contrib.admin) har helt omarbetats; admin-definitioner är nu helt frikopplade från modelldefinitioner, ramverket har skrivits om för att använda Djangos nya formulärhanteringsbibliotek och omdesignats med tanke på utdragbarhet och anpassning.
I praktiken innebär det att du måste skriva om alla dina class Admin-deklarationer. Du har redan sett i models ovan hur du kan ersätta din class Admin med ett admin.site.register()-anrop i en admin.py-fil. Nedan följer lite mer information om hur man skriver om Admin deklarationen till den nya syntaxen.
Använd ny inline-syntax¶
De nya edit_inline-alternativen har alla flyttats till admin.py. Här är ett exempel:
Gammal (0,96):
class Parent(models.Model): ...
class Child(models.Model):
    parent = models.ForeignKey(Parent, edit_inline=models.STACKED, num_in_admin=3)
Ny (1.0):
class ChildInline(admin.StackedInline):
    model = Child
    extra = 3
class ParentAdmin(admin.ModelAdmin):
    model = Parent
    inlines = [ChildInline]
admin.site.register(Parent, ParentAdmin)
Se objekt av typen ``InlineModelAdmin för mer information.
Förenkla fields, eller använd fieldsets¶
Den gamla syntaxen fields var ganska förvirrande och har förenklats. Den gamla syntaxen fungerar fortfarande, men du måste använda fieldsets istället.
Gammal (0,96):
class ModelOne(models.Model):
    ...
    class Admin:
        fields = ((None, {"fields": ("foo", "bar")}),)
class ModelTwo(models.Model):
    ...
    class Admin:
        fields = (
            ("group1", {"fields": ("foo", "bar"), "classes": "collapse"}),
            ("group2", {"fields": ("spam", "eggs"), "classes": "collapse wide"}),
        )
Ny (1.0):
class ModelOneAdmin(admin.ModelAdmin):
    fields = ("foo", "bar")
class ModelTwoAdmin(admin.ModelAdmin):
    fieldsets = (
        ("group1", {"fields": ("foo", "bar"), "classes": "collapse"}),
        ("group2", {"fields": ("spam", "eggs"), "classes": "collapse wide"}),
    )
Se även
- Mer detaljerad information om ändringarna och orsakerna bakom dem finns på wikisidan NewformsAdminBranch 
- Den nya admin kommer med massor av nya funktioner; du kan läsa om dem i admin dokumentation. 
URL:er¶
Uppdatera din root urls.py¶
Om du använder administratörssidan måste du uppdatera din root urls.py.
Gammal (0.96) urls.py:
from django.conf.urls.defaults import *
urlpatterns = patterns(
    "",
    (r"^admin/", include("django.contrib.admin.urls")),
    # ... the rest of your URLs here ...
)
Ny (1.0) urls.py:
from django.conf.urls.defaults import *
# The next two lines enable the admin and load each admin.py file:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns(
    "",
    (r"^admin/(.*)", admin.site.root),
    # ... the rest of your URLs here ...
)
Vyer¶
Använd django.forms istället för newforms¶
Ersätt django.newforms med django.forms – Django 1.0 bytte namn på modulen newforms (introducerad i 0.96) till gamla vanliga forms. Modulen oldforms togs också bort.
Om du redan använder biblioteket newforms och du använde vår rekommenderade syntax för import-satser behöver du bara ändra dina importsatser.
Gammal:
from django import newforms as forms
Ny:
from django import forms
Om du använder det gamla formulärsystemet (tidigare känt som django.forms och django.oldforms) måste du skriva om dina formulär. Ett bra ställe att börja på är formulärdokumentation
Hantera uppladdade filer med hjälp av det nya API:et¶
Ersätt användningen av uppladdade filer - det vill säga poster i request.FILES - som enkla ordböcker med den nya UploadedFile. Den gamla syntaxen för ordböcker fungerar inte längre.
Alltså, i en vy som:
def my_view(request):
    f = request.FILES["file_field_name"]
    ...
…måste du göra följande ändringar:
| Gammal (0,96) | Ny (1.0) | 
|---|---|
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
Arbeta med filfält med hjälp av det nya API:et¶
Den interna implementeringen av django.db.models.FileField har ändrats. Ett synligt resultat av detta är att sättet du kommer åt specialattribut (URL, filnamn, bildstorlek etc.) för dessa modellfält har ändrats. Du kommer att behöva göra följande ändringar, förutsatt att din modells FileField heter myfile:
| Gammal (0,96) | Ny (1.0) | 
|---|---|
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
Observera att attributen width och height endast är meningsfulla för ImageField-fält. Mer information finns i dokumentationen model API.
Använd Paginator istället för ObjectPaginator¶
ObjectPaginator i 0.96 har tagits bort och ersatts med en förbättrad version, django.core.paginator.Paginator.
Mallar¶
Lär dig att älska autoescaping¶
Som standard HTML-eskapsätter mallsystemet nu automatiskt utdata från varje variabel. För mer information, se Automatisk HTML-escaping.
Om du vill inaktivera automatisk eskapning för en enskild variabel använder du filtret safe:
This will be escaped: {{ data }}
This will not be escaped: {{ data|safe }}
Om du vill inaktivera auto-escaping för en hel mall, linda in mallen (eller bara en viss del av mallen) i taggen autoescape:
{% autoescape off %}
   ... unescaped template content here ...
{% endautoescape %}
Mindre vanliga förändringar¶
Följande ändringar är mindre, mer lokala ändringar. De bör endast påverka mer avancerade användare, men det är förmodligen värt att läsa igenom listan och kontrollera din kod för dessa saker.
Signaler¶
- Lägg till - **kwargstill alla registrerade signalhanterare.
- Anslut, koppla från och skicka signaler via metoder på objektet - Signalistället för via modulmetoder i- django.dispatch.dispatcher.
- Ta bort all användning av avsändaralternativen - Anonymousoch- Any; de finns inte längre. Du kan fortfarande ta emot signaler som skickas av vilken avsändare som helst genom att använda- sender=None
- Gör alla anpassade signaler som du har deklarerat till instanser av - django.dispatch.Signalistället för anonyma objekt.
Här är en snabb sammanfattning av de kodändringar du behöver göra:
| Gammal (0,96) | Ny (1.0) | 
|---|---|
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
Kommentarer¶
Om du använde Django 0.96:s app django.contrib.comments måste du uppgradera till den nya kommentarsappen som introducerades i 1.0. Se uppgraderingsguiden för mer information.
Lokala smaker¶
Lokal smak från USA¶
django.contrib.localflavor.usa har bytt namn till django.contrib.localflavor.us. Denna förändring gjordes för att matcha namngivningsschemat för andra lokala smaker. För att migrera din kod är allt du behöver göra att ändra importen.
Sessioner¶
Få en ny sessionsnyckel¶
SessionBase.get_new_session_key() har bytt namn till _get_new_session_key(). get_new_session_object() finns inte längre.
Fixturer¶
Laddning av en rad kräver inte längre save()¶
Tidigare körde laddning av en rad automatiskt modellens save()-metod. Detta är inte längre fallet, så alla fält (till exempel: tidsstämplar) som automatiskt fylldes i av en save() behöver nu uttryckliga värden i alla fixturer.
Inställningar¶
Bättre undantag¶
Det gamla EnvironmentError har delats upp i ett ImportError när Django misslyckas med att hitta inställningsmodulen och ett RuntimeError när du försöker konfigurera om inställningar efter att du redan har använt dem.
LOGIN_URL har flyttats¶
Konstanten LOGIN_URL flyttades från django.contrib.auth till modulen settings. Istället för att använda from django.contrib.auth import LOGIN_URL hänvisa till settings.LOGIN_URL.
APPEND_SLASH-beteendet har uppdaterats¶
I 0.96, om en URL inte slutade med ett snedstreck eller hade en punkt i den sista komponenten i sökvägen, och APPEND_SLASH var True, skulle Django omdirigera till samma URL, men med ett snedstreck i slutet. Nu kontrollerar Django för att se om mönstret utan det efterföljande snedstrecket skulle matchas av något i dina URL-mönster. Om så är fallet sker ingen omdirigering, eftersom det antas att du avsiktligt ville fånga det mönstret.
För de flesta människor kommer detta inte att kräva några ändringar. Vissa människor har dock URL-mönster som ser ut så här:
r"/some_prefix/(.*)$"
Tidigare skulle dessa mönster ha omdirigerats till att ha ett efterföljande snedstreck. Om du alltid vill ha ett snedstreck på sådana webbadresser skriver du om mönstret till:
r"/some_prefix/(.*/)$"
Mindre modellförändringar¶
Olika undantag från get()¶
Hanterare returnerar nu ett MultipleObjectsReturned undantag istället för AssertionError:
Gammal (0,96):
try:
    Model.objects.get(...)
except AssertionError:
    handle_the_error()
Ny (1.0):
try:
    Model.objects.get(...)
except Model.MultipleObjectsReturned:
    handle_the_error()
LazyDate har avfyrats¶
Hjälpklassen LazyDate finns inte längre.
Standardfältvärden och frågeargument kan båda vara anropsbara objekt, så instanser av LazyDate kan ersättas med en referens till datetime.datetime.now:
Gammal (0,96):
class Article(models.Model):
    title = models.CharField(maxlength=100)
    published = models.DateField(default=LazyDate())
Ny (1.0):
import datetime
class Article(models.Model):
    title = models.CharField(max_length=100)
    published = models.DateField(default=datetime.datetime.now)
DecimalField är ny, och FloatField är nu en riktig float¶
Gammal (0,96):
class MyModel(models.Model):
    field_name = models.FloatField(max_digits=10, decimal_places=3)
    ...
Ny (1.0):
class MyModel(models.Model):
    field_name = models.DecimalField(max_digits=10, decimal_places=3)
    ...
Om du glömmer att göra denna ändring kommer du att se fel om att FloatField inte tar ett max_digits-attribut i __init__, eftersom den nya FloatField inte tar några precisionsrelaterade argument.
Om du använder MySQL eller PostgreSQL behövs inga ytterligare ändringar. Databasens kolumntyper för DecimalField är desamma som för den gamla FloatField.
Om du använder SQLite måste du tvinga databasen att visa de aktuella kolumnerna som decimaltyper i stället för flyttal. För att göra detta måste du ladda om dina data. Gör detta efter att du har gjort ändringen till att använda DecimalField i din kod och uppdaterat Django-koden.
Varning
Säkerhetskopiera din databas först!
För SQLite innebär detta att du gör en kopia av den enda fil som lagrar databasen (namnet på den filen är DATABASE_NAME i filen settings.py).
För att uppgradera varje applikation till att använda en DecimalField kan du göra följande och ersätta <app> i koden nedan med varje apps namn:
$ ./manage.py dumpdata --format=xml <app> > data-dump.xml
$ ./manage.py reset <app>
$ ./manage.py loaddata data-dump.xml
Anteckningar:
- Det är viktigt att du kommer ihåg att använda XML-format i det första steget av den här processen. Vi utnyttjar en funktion i XML-datadumparna som gör det möjligt att porta floats till decimaler med SQLite. 
- I det andra steget kommer du att bli ombedd att bekräfta att du är beredd att förlora data för applikationen/applikationerna i fråga. Säg ja, så återställer vi dessa data i det tredje steget. 
- DecimalFieldanvänds inte i någon av de appar som levererades med Django innan denna ändring gjordes, så du behöver inte oroa dig för att utföra denna procedur för någon av Djangos standardmodeller.
Om något går fel under processen ovan är det bara att kopiera den säkerhetskopierade databasfilen över originalfilen och börja om.
Internationalisering¶
django.views.i18n.set_language() kräver nu en POST-begäran¶
Tidigare användes en GET-begäran. Det gamla beteendet innebar att state (den locale som används för att visa webbplatsen) kunde ändras genom en GET-begäran, vilket strider mot HTTP-specifikationens rekommendationer. Kod som anropar denna vy måste se till att en POST-begäran nu görs, istället för en GET. Det innebär att du inte längre kan använda en länk för att komma åt vyn, utan du måste använda någon form av formulär (t.ex. en knapp).
_() finns inte längre i inbyggda program¶
_() (det anropsbara objektet vars namn är ett enda understreck) är inte längre monkeypatchat i builtins - det vill säga, det finns inte längre magiskt tillgängligt i varje modul.
Om du tidigare förlitade dig på att _() alltid skulle finnas, bör du nu uttryckligen importera ugettext eller ugettext_lazy, om det är lämpligt, och alias det till _ själv:
from django.utils.translation import ugettext as _
Objekt för HTTP-begäran/-svar¶
Dictionary-åtkomst till HttpRequest¶
objekten HttpRequest stöder inte längre direkt åtkomst i ordboksstil; tidigare var både GET och POST data direkt tillgängliga på objektet HttpRequest (t.ex. kunde du söka efter en bit formulärdata genom att använda if 'some_form_key' in request eller genom att läsa request['some_form_key']. Detta stöds inte längre; om du behöver tillgång till kombinerade GET och POST data, använd request.REQUEST istället.
Det rekommenderas dock starkt att du alltid uttryckligen letar i lämplig ordbok efter den typ av begäran du förväntar dig att få (request.GET eller request.POST); att förlita sig på den kombinerade ordboken request.REQUEST kan maskera ursprunget till inkommande data.
Tillgång till HTTPResponse-rubriker¶
django.http.HttpResponse.headers har bytt namn till _headers och HttpResponse stöder nu containment checking direkt. Så använd if header in response: istället för if header in response.headers:.
Generiska relationer¶
Generiska relationer har flyttats ut ur kärnan¶
De generiska relationsklasserna - GenericForeignKey och GenericRelation - har flyttats till modulen django.contrib.contenttypes.
Testar¶
django.test.Client.login() har ändrats¶
Gammal (0,96):
from django.test import Client
c = Client()
c.login("/path/to/login", "myuser", "mypassword")
Ny (1.0):
# ... same as above, but then:
c.login(username="myuser", password="mypassword")
Ledningskommandon¶
Kör kommandon för hantering från din kod¶
django.core.management har genomgått en omfattande omarbetning.
Anrop till hanteringstjänster i din kod måste nu använda call_command. Om du till exempel har en testkod som anropar flush och load_data:
from django.core import management
management.flush(verbosity=0, interactive=False)
management.load_data(["test_data"], verbosity=0)
…måste du ändra den här koden så att den lyder:
from django.core import management
management.call_command("flush", verbosity=0, interactive=False)
management.call_command("loaddata", "test_data", verbosity=0)
Underkommandon måste nu föregå alternativ¶
django-admin.py och manage.py kräver nu att underkommandon föregår alternativen. Så här är det:
$ django-admin.py --settings=foo.bar runserver
…fungerar inte längre och bör ändras till:
$ django-admin.py runserver --settings=foo.bar
Datastrukturer¶
SortedDictFromList är borta¶
django.newforms.forms.SortedDictFromList togs bort. django.utils.datastructures.SortedDict kan nu instansieras med en sekvens av tupler.
För att uppdatera din kod:
- Använd - django.utils.datastructures.SortedDictdär du tidigare använde- django.newforms.forms.SortedDictFromList.
- Eftersom - django.utils.datastructures.SortedDict.copyinte returnerar en deepcopy som- SortedDictFromList.copy()gjorde, måste du uppdatera din kod om du förlitade dig på en deepcopy. Gör detta genom att använda- copy.deepcopydirekt.
Funktioner för databasens backend¶
Databasens backend-funktioner har bytt namn¶
Nästan alla funktioner på databasens backend-nivå har bytt namn och/eller flyttats. Ingen av dessa har dokumenterats, men du måste ändra din kod om du använder någon av dessa funktioner, som alla finns i django.db:
| Gammal (0,96) | Ny (1.0) | 
|---|---|
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
 
          