Menghubungkan aplikasi anda dari Django 0.96 ke 1.0

Django 1.0 memutus kesesuaian dengan 0.96 di beberapa kawasan.

Panduan ini akan membantu anda menghubungkan proyek 0.96 dan apliaksi ke 1.0. Bagian pertama dari dokumen ini termasuk perubahan umum dibutuhkan untuk berjalan dengan 1.0. Jika setelah melalui bagian pertama kode anda masih rusak, periksa bagian Less-common Changes untuk daftar ikatan masalah kesesuaian yang kurang umum.

lihat juga

1.0 release notes. Dokumen itu menjelaskan fitur-fitur baru di 1.0 lebih dalam; panduan menghubungkan lebih diperhatikan dengan bantuan anda dengan cepat memperbaharui kode anda.

Perubahan umum

Bagian ini menggambarkan perubahan diantara 0.96 dan 1.0 yang paling pengguna butuhkan untuk dibuat.

Gunakan Unicode

Merubah harfiah deretan karakter ('foo') menjadi harfiah Unicode (u'foo'). Django sekarang menggunakan deretan karakter Unicode seluruhnya. Di kebanyakan tempat, deretan karakter mentah akan lanjut bekerja, tetapi memperbaharui untuk menggunakan harfiah Unicode akan mencegah pengaburan beberapa masalah.

Lihat Data Unicode untuk rincian penuh.

Model

Perubahan umum ke berkas model anda:

Namai kembali maxlength ke max_length

Namai kembali argumen maxlength anda ke max_length (ini dirubah agar selaras dengan bidang-bidang formulir):

Ganti __str__ dengan __unicode__

Ganti fungsi __str__ model anda dengan metode __unicode__, dan pastikan anda use Unicode (u'foo') di metode itu.

Pindahkan prepopulated_from

Pindahkan argumen prepopulated_from pada bidang model. Itu tidak lagi sah dan telah dipindahkan ke kelas ModelAdmin di admin.py. Lihat the admin, dibawah ini, untuk rincian lebih tentang dirubah ke admin.

Pindahkan core

Pindahkan argumen core dari bidang model anda. itu tidak lagi dibutuhkan, sejak kegunaan yang setara (bagian dari inline editing) ditangani dengan berbeda oleh antarmuka admin sekarang. Anda tidak harus khawatir tentang penyuntingan berderet sampai anda menuju bagian the admin, dibawah. Untuk sekarang, pindahkan semua acuan ke core.

Ganti class Admin: dengan admin.py

Pindahkan semua pernyataan class Admin sebelah dalam dari model anda. Mereka tidak merusak apapun jika anda meninggalkan mereka, tetapi mereka juga tidak akan melakukan apapun. Untuk mendaftarkan aplikasi dengan admin anda akan pindahkan pernyataan itu ke berkas admin.py; lihat the admin dibawah untuk lebih rinci.

lihat juga

Seorang penyumbang pada djangosnippets telah menuli skembali sebuah tulisan yang akan scan your models.py and generate a corresponding admin.py.

Contoh

DIbawah ini adalah sebuah contoh berkas models.py dengan semua perubahan anda ingin buat:

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

Baru (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 u'%s %s' % (self.first_name, self.last_name)

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

Admin

Satu dari perubahan terbesar di 1.0 adalah admin baru. Antarmuak administratif Django (django.contrib.admin) telah sepenuhnya di refaktor; pengertian admin sekarang sepenuhnya dipisahkan dari pengertian model, kerangka kerja telah ditulis kembali untuk menggunakan pustaka penanganan formulir baru Django dan dirancang kembali dengan perpanjangan dan penyesuaian dalam pikiran.

Sebenarnya, ini berarti anda akan butuh menulis kembali semua pernyataan class Admin anda. Anda telah melihat di models diatas bagaimana mengganti class Admin anda dengan sebuah panggilan admin.site.register() dalam sebuah berkas admin.py. Dibawah ini adalah beberapa lebih rinci pada bagimana menulis kembali pernyataan Admin itu kedalam sintaksis baru.

Gunakan sintaksis berderet yang baru

Pilihan edit_inline baru semua telah dipindahkan ke admin.py. Ini adalah contoh:

Lama (0.96):

class Parent(models.Model):
    ...

class Child(models.Model):
    parent = models.ForeignKey(Parent, edit_inline=models.STACKED, num_in_admin=3)

Baru (1.0):

class ChildInline(admin.StackedInline):
    model = Child
    extra = 3

class ParentAdmin(admin.ModelAdmin):
    model = Parent
    inlines = [ChildInline]

admin.site.register(Parent, ParentAdmin)

Lihat Obyek InlineModelAdmin untuk rinci.

Sederhanakan fields, atau gunakan fieldsets

Sintaksis fields lama sangat membingungkan, dan telah disederhanakan. Sintaksis lama masih bekerja, tetapi anda akan butuh menggunakan fieldsets sebagai gantinya.

Lama (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'}),
        )

Baru (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'}),
    )

lihat juga

URL

Perbaharui akar urls.py anda.

Jika anda menggunakan situs admin, anda butuh memperbaharui akar urls.py anda.

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

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

View

Gunakan django.forms sebagai gantinya newforms

Ganti django.newforms dengan django.forms -- Django 1.0 dinamai kembali modul newforms (diperkenalkan di 0.96) untuk forms lama kosong. Modul oldforms juga dipindahkan.

Jika anda sudah menggunakan pustaka newforms, dan anda menggunakan anjuran kami sintaksis pernyataan import, semua anda harus lakukan adalah merubah pernyataan impor anda.

Lama:

from django import newforms as forms

Baru:

from django import forms

Jika anda sedang menggunakan sistem formulir lama (dahulu dikenal sebagai django.forms dan django.oldforms), anda akan harus menuli skembali formulir anda. Tempat bagus untuk memulai adalah forms documentation

Menangani berkas terunggah menggunakan API baru

Rubah penggunaan berkas-berkas terunggah -- yaitu, masukan di request.FILES -- sebagai kamus sederhana dengan UploadedFile baru. Sintaksis kamus lama tidak lagi bekerja.

Jadi, dalam tampilan seperti:

def my_view(request):
    f = request.FILES['file_field_name']
    ...

...anda butuh membuat perubahan berikut:

Lama (0.96) Baru (1.0)
f['content'] f.read()
f['filename'] f.name
f['content-type'] f.content_type

Bekerja dengan bidang berkas menggunakan API baru

Penerapan internal dari django.db.models.FileField telah berubah. Hasil nampak dari ini adalah bahwa cara anda mengakses atribut khusus (URL, berkas nama, ukuran gambar, dll.) dari bidang model ini telah berubah. Anda akan butuh membuat perubahan berikut, menganggap FileField model anda dipanggil myfile:

Lama (0.96) Baru (1.0)
myfile.get_content_filename() myfile.content.path
myfile.get_content_url() myfile.content.url
myfile.get_content_size() myfile.content.size
myfile.save_content_file() myfile.content.save()
myfile.get_content_width() myfile.content.width
myfile.get_content_height() myfile.content.height

Catat bahwa atribut width dan height hanya masuk akal untuk bidang ImageField. Rincian lebih dapat ditemukan di dokumentasi model API.

Gunakan Paginator daripada ObjectPaginator

ObjectPaginator di 0.96 telah dipindahkan dan diganti dengan versi diperbaiki, django.core.paginator.Paginator.

Templat

Belajar mencintai pelolosan otomatis

Secara awal, sistem cetakan sekarang otomatis meloloskan HTML keluaran setiap variabel. Untuk mempelajari lebih, lihat Automatic HTML escaping.

Untuk meniadakan pelolosan otomatis untuk variabel tersendiri, gunakan safe filter:

This will be escaped: {{ data }}
This will not be escaped: {{ data|safe }}

Untuk meniadakan pelolosan otomatis untuk keseluruhan cetakan, bungkus cetakan (atau cukup bagian tertentu dari cetakan) di etiket autoescape:

{% autoescape off %}
   ... unescaped template content here ...
{% endautoescape %}

Perubahan kurang umum

Perubahan berikut lebih kecil, lebih perubahan lokal. Mereka hanya berpengaruh lebih pengguna lanjutan, tetapi itu mungkin bernilai baik membaca melalui daftar dan memeriksa kode anda untuk hal-hal ini.

Sinyal

  • Tambah **kwargs pada setiap penangan sinyal terdaftar.
  • Hubungkan, putuskan, dan kirim sinyal melalui metode pada obyek Signal daripada melalui modul metode di django.dispatch.dispatcher.
  • Pindahkan tiap penggunaan pilihan pengirim Anonymous dan Any; mereka tidak lagi ada. Anda masih dapat menerima sinyal dikirim oleh pengirim dengan menggunakan sender=None
  • Buat sinyal penyesuaian apa saja anda telah nyatakan kedalam instance dari django.dispatch.Signal sebagai ganti dari obyek anonim.

Berikut rekap dari perubahan kode yang perlu anda lakukan:

Lama (0.96) Baru (1.0)
def callback(sender) def callback(sender, **kwargs)
sig = object() sig = django.dispatch.Signal()
dispatcher.connect(callback, sig) sig.connect(callback)
dispatcher.send(sig, sender) sig.send(sender)
dispatcher.connect(callback, sig, sender=Any) sig.connect(callback, sender=None)

Komentar

Jika anda menggunakan aplikasi django.contrib.comments Django 0.96, anda akan btuuh meningkatkan ke aplikasi komentar baru diperkenalkan di 1.0. Lihat panduan peningkatan untuk rincian.

Tag templat

Etiket spaceless

Etiket cetakan tidak berruang sekarang memindahkan semua ruang diantara etiket HTML, sebagai gantinya dari menyediakan ruang tunggal.

Rasa lokal

Rasa lokal U.S

django.contrib.localflavor.usa telah dinamai kembali ke django.contrib.localflavor.us. Perubahan ini dibuat untuk mencocokan penamaan skema dari rasa lokal lainnya. Untuk memindahkan kode anda, anda yang butuh lakukan adalah merubah impor.

Sesi

Mendapatkan kunci sesi baru

SessionBase.get_new_session_key() telah dinamai kembali menjadi _get_new_session_key(). get_new_session_object() tidak lagi ada.

Perlengkapan

Memuat sebuah baris yang tidak memanggil save()

Sebelumnya, memuat sebuah baris secara otomatis menjalankan metode save() model. Ini bukan lagi kasus, jadi tiap bidang (sebagai contoh: timestamp) yang dikumpulkan otomatis oleh save() sekarang butuh nilai eksplisit di tiap perlengkapan tetap.

Pengaturan

Pengecualian terbaik

EnvironmentError lama telah dipisah menjadi ImportError ketika Django gagal menemukan modul pengaturan dan RuntimeError ketika anda mencoba mengkonfigurasi kembali pengaturan setelah selesai menggunakan mereka.

LOGIN_URL telah dipindahkan

Ketetapan LOGIN_URL dipindah dari django.contrib.auth kedalam modul settings. Daripada menggunakan from django.contrib.auth import LOGIN_URL mengacu pada settings.LOGIN_URL.

Perilaku APPEND_SLASH telah diperbaharui

Di 0.96, jika sebuah URL tidak berakhir di garis miring atau mempunyai titik di akhir komponen dari jalurnya, dan APPEND_SLASH adalah True, Django akan mengalihkan ke URL sama, tetapi dengan tanda miring ditambahkan pada akhir. Sekarang, Django memeriksa apakah pola tanpa ekor garis miring akan cocok oleh sesuatu di pola URL anda. Jika demikian, tidak ada pengalihan, karena itu dianggap anda sengaja ingin menangkap pola itu.

Untuk kebanyakan orang, ini tidak akan membutuhkan perubahan. Beberapa orang, meskipun, mempunyai pola URL yang terlihat seperti ini:

r'/some_prefix/(.*)$'

Sebelumnya, pola itu akan dialihkan untuk mempunyai sebuah ekor garis miring. Jika anda selalu ingin garis miring pada URL itu, tulis kembali pola sebagai:

r'/some_prefix/(.*/)$'

Perubahan model kecil

Pengecualian berbeda dari get()

Pengelola sekarang mengembalikan pengecualian MultipleObjectsReturned daripada AssertionError:

Lama (0.96):

try:
    Model.objects.get(...)
except AssertionError:
    handle_the_error()

Baru (1.0):

try:
    Model.objects.get(...)
except Model.MultipleObjectsReturned:
    handle_the_error()

LazyDate telah dinyalakan

Kelas pembantu LazyDate tidak lagi ada.

Nilai bidang awalan dan permintaan argumen keduanya obyek callable, jadi instance dari LazyDate dapat diganti dengan acuan pada datetime.datetime.now:

Lama (0.96):

class Article(models.Model):
    title = models.CharField(maxlength=100)
    published = models.DateField(default=LazyDate())

Baru (1.0):

import datetime

class Article(models.Model):
    title = models.CharField(max_length=100)
    published = models.DateField(default=datetime.datetime.now)

DecimalField adalah baru, dan FloatField sekarang float tepat.

Lama (0.96):

class MyModel(models.Model):
    field_name = models.FloatField(max_digits=10, decimal_places=3)
    ...

Baru (1.0):

class MyModel(models.Model):
    field_name = models.DecimalField(max_digits=10, decimal_places=3)
    ...

Jika anda lupa membuat perubahan ini, anda akan melihat kesalahan tentang FloatField bukan mengambil atribut max_digits di __init__, karena FloatField baru mengambil argumen terkait tidak teliti.

Jika anda sedang menggunakan MySQL atau PostgreSQL, tidak dibtuuhkan perubahan lebih lanjut. Jenis kolom basisdata untuk DecimalField adalah sama untuk FloatField lama.

Jika anda menggunakan SQLite, anda butuh memaksa basisdata melihat kolom yang sesuai sebagai jenis desimal, daripada float. untuk melakukan ini, anda akan butuh memuat kembali data anda. Lakukam ini setelah anda membuat perubahan untuk menggunakan DecimalField di kode anda dan kode Django diperbaharui.

Peringatan

Sokong basisdata anda dahulu!

Untuk SQLite, ini berarti membuat sebuah salinan dari berkas tunggal yang menyimpan basisdata (nama dari berkas itu adalah DATABASE_NAME di berkas settings.py anda).

Untuk meningkatkan setiap aplikasi untuk menggunakan sebuah DecimalField, anda dapat melakukan berikut, mengganti <app> di kode dibawah ini dengan setiap nama aplikasi:

$ ./manage.py dumpdata --format=xml <app> > data-dump.xml
$ ./manage.py reset <app>
$ ./manage.py loaddata data-dump.xml

Catatan:

  1. Itu sangat penting bahwa anda mengingat untuk menggunakan bentuk XML dalam langkah pertama dari pengolahan ini. Kami sedang menggunakan fitur dari data buangan XML yang membuat belokan float ke desimal dengan SQLite memungkinkan.
  2. Di langkah kedua anda akan diminta menegaskan bahwa anda siap kehilangan data untuk aplikasi di pertanyaan. Katakan ya; kami akan menyimpan kembali data ini di langkah ketiga, tentu saja.
  3. DecimalField tidak digunakan di tiap aplikasi yang dibekali dengan Django sebelum perubahan ini dibuat, jadi anda tidak butuh khawatir tentang melakukan prosedur ini untuk tiap model Django standar.

Jika sesuatu berjalan salah di pengolahan diatas, cukup salin berkas basisdata sokongan anda terhadap berkas asli dan mulai kembali.

Internasionalisasi

django.views.i18n.set_language() sekarang membutuhkan permintaan POST

Sebelumnya, permintaan GET telah digunakan. Perilaku lama berarti bahwa keadaan (lokal digunakan untuk menampilkan situs) dapat berubah dengan permintaan GET, yaitu terhadap anjuran spesifikasi HTTP. Kode memanggil tampilan ini harus memastikan bahwa permintaan POST sekaragn dibuat, sebagai gantinya GET. Ini berarti anda tidak dapat lagi menggunakan tautan mengakses tampilan, tetapi harus menggunakan pengajuan formulir dari sejenis (sebagai contoh tombol).

_() tidak lagi siap pakai

_() (obyek callable yang namanya adalah garis bawah tunggal) tidak lagi monkeypatch kedalam siap pakai -- yaitu, itu tidak lagi tersedia secara ajaib di setiap modul.

Jika anda sebelumnya bergantung pada _() selalu menjadi hadir, anda harus sekarang secara eksplisit mengimpor ugettext atau ugettext_lazy, jika sesuai, dan namai itu menjadi _ anda sendiri:

from django.utils.translation import ugettext as _

Obyek HTTP request/response

Akses kamus ke HttpRequest

Obyek HttpRequest tidak lagi langsung mendukung akses gaya kamus; sebelumnya, kedua data GET dan POST langsung tersedia pada obyek HttpRequest (sebagai contoh, anda dapat memeriksa untuk potongan dari formulir data dengan menggunakan if 'some_form_key' in request atau dengan membaca request['some_form_key']. Ini tidak lagi didukung; jika anda butuh akses untuk mengkombinasikan data GET dan POST, gunakan request.REQUEST sebagai gantinya.

Itu sangat disarankan, bagaimanapun, bahwa anda selalu secara eksplisit mencari di kamus yang sesuai untuk jenis dari permintaan anda harapkan untuk menerima (request.GET or request.POST); bergantung pada gabungan kamus request.REQUEST dapat menutup data datang asli.

Mengakses kepala HTTPResponse

django.http.HttpResponse.headers telah dinamai kembali ke _headers dan HttpResponse sekarang mendukung penahanan pemeriksaan secara langsung. Jadi gunakan if header in response: daripada if header in response.headers:.

Hubungan umum

Hubungan umum telah dipindahkan keluar dari inti

Kelas-kelas hubungan umum -- GenericForeignKey dan GenericRelation -- telah dipindahkan kedalam modul django.contrib.contenttypes.

Pengujian

meth:django.test.Client.login telah berubah

Lama (0.96):

from django.test import Client
c = Client()
c.login('/path/to/login','myuser','mypassword')

Baru (1.0):

# ... same as above, but then:
c.login(username='myuser', password='mypassword')

Pengelolaan perintah

Menjalankan pengelolaan perintah dari kode anda

django.core.management telah direfaktor.

Panggilan pada pengelolaan pelayanan di kode anda sekarang butuh untuk menggunakan call_command. Sebagai contoh, jika anda mempunyai beberapa percobaan yang memanggil flush dan load_data:

from django.core import management
management.flush(verbosity=0, interactive=False)
management.load_data(['test_data'], verbosity=0)

...anda akan butuh merubah kdoe ini untuk dibaca:

from django.core import management
management.call_command('flush', verbosity=0, interactive=False)
management.call_command('loaddata', 'test_data', verbosity=0)

Sub perintah sekarang harus mendahulukan pilihan

django-admin.py dan manage.py sekarang membutuhkan sub perintah untuk mendahulukan pilihan. Jadi:

$ django-admin.py --settings=foo.bar runserver

...tidak lagi bekerja dan harus dirubah menjadi:

$ django-admin.py runserver --settings=foo.bar

Kongsi

Feed.__init__ telah berubah

metode __init__() dari kongsi kelas Feed kerangka kerja sekarang mengambil sebuah obyek HttpRequest sebagai parameter keduanya, daripada URL umpan. Ini mengizinkan kongsi kerangka kerja untuk bekerja tanpa membutuhkan kerangka kerja situs. Ini hanya mempengaruhi kode yang subkelas Feed dan menimpa metode __init__(), dan kode yang memanggil Feed.__init__() secara langsung.

Struktur data

SortedDictFromList` telah pergi

django.newforms.forms.SortedDictFromList telah dipindahkan. django.utils.datastructures.SortedDict sekarang dapat membuat obyek dengan urutan dari tuple-tuple.

Untuk memperbaharui kode anda:

  1. Gunakan django.utils.datastructures.SortedDict dimanapun anda menggunakan django.newforms.forms.SortedDictFromList.
  2. Karena django.utils.datastructures.SortedDict.copy tidak mengemblikan salinan dalam sebagai SortedDictFromList.copy() lakukan, anda akan butuh memperbaharui kode anda jika anda bergantung pada saliann dalam. Lakukan ini dengan menggunakan copy.deepcopy secara langsung.

Fungsi basisdata backend

Fungsi basisdata backend telah diubah namanya

Hampir semua dari fungsi tingkatan backend basisdata telah dinamai kembali dan/atau ditempatkan kembali. Tidak ada dari ini didokumentasikan, tetapi anda akan butuh merubah kode anda jika anda sedang menggunakan tiap fungsi ini, semua dari yang berada di django.db:

Lama (0.96) Baru (1.0)
backend.get_autoinc_sql connection.ops.autoinc_sql
backend.get_date_extract_sql connection.ops.date_extract_sql
backend.get_date_trunc_sql connection.ops.date_trunc_sql
backend.get_datetime_cast_sql connection.ops.datetime_cast_sql
backend.get_deferrable_sql connection.ops.deferrable_sql
backend.get_drop_foreignkey_sql connection.ops.drop_foreignkey_sql
backend.get_fulltext_search_sql connection.ops.fulltext_search_sql`
backend.get_last_insert_id connection.ops.last_insert_id
backend.get_limit_offset_sql connection.ops.limit_offset_sql
backend.get_max_name_length connection.ops.max_name_length
backend.get_pk_default_value connection.ops.pk_default_value
backend.get_random_function_sql connection.ops.random_function_sql
backend.get_sql_flush connection.ops.sql_flush
backend.get_sql_sequence_reset connection.ops.sequence_reset_sql
backend.get_start_transaction_sql connection.ops.start_transaction_sql
backend.get_tablespace_sql connection.ops.tablespace_sql
backend.quote_name connection.ops.quote_name
backend.get_query_set_class connection.ops.query_set_class
backend.get_field_cast_sql connection.ops.field_cast_sql
backend.get_drop_sequence connection.ops.drop_sequence_sql
backend.OPERATOR_MAPPING connection.operators
backend.allows_group_by_ordinal connection.features.allows_group_by_ordinal
backend.allows_unique_and_pk connection.features.allows_unique_and_pk
backend.autoindexes_primary_keys connection.features.autoindexes_primary_keys
backend.needs_datetime_string_cast connection.features.needs_datetime_string_cast
backend.needs_upper_for_iops connection.features.needs_upper_for_iops
backend.supports_constraints connection.features.supports_constraints
backend.supports_tablespaces connection.features.supports_tablespaces
backend.uses_case_insensitive_names connection.features.uses_case_insensitive_names
backend.uses_custom_queryset connection.features.uses_custom_queryset
Back to Top