Menghubungkan aplikasi anda dari Django 0.96 ke 1.0Link to this heading
Django 1.0 memutus kesesuaian dengan 0.96 di beberapa kawasan.
This guide will help you port 0.96 projects and apps to 1.0. The first part of this document includes the common changes needed to run with 1.0. If after going through the first part your code still breaks, check the section Less-common Changes for a list of a bunch of less-common compatibility issues.
Perubahan umumLink to this heading
Bagian ini menggambarkan perubahan diantara 0.96 dan 1.0 yang paling pengguna butuhkan untuk dibuat.
Gunakan UnicodeLink to this heading
Change string literals ('foo') into Unicode literals (u'foo'). Django
now uses Unicode strings throughout. In most places, raw strings will continue
to work, but updating to use Unicode literals will prevent some obscure
problems.
Lihat Unicode data untuk rincian penuh.
ModelLink to this heading
Perubahan umum ke berkas model anda:
Namai kembali maxlength ke max_lengthLink to this heading
Rename your maxlength argument to max_length (this was changed to be
consistent with form fields):
Ganti __str__ dengan __unicode__Link to this heading
Replace your model's __str__ function with a __unicode__ method, and
make sure you use Unicode (u'foo') in that method.
Pindahkan prepopulated_fromLink to this heading
Remove the prepopulated_from argument on model fields. It's no longer valid
and has been moved to the ModelAdmin class in admin.py. See the
admin, below, for more details about changes to the admin.
Pindahkan coreLink to this heading
Remove the core argument from your model fields. It is no longer
necessary, since the equivalent functionality (part of inline editing) is handled differently by the admin interface now. You don't
have to worry about inline editing until you get to the admin section,
below. For now, remove all references to core.
Ganti class Admin: dengan admin.pyLink to this heading
Remove all your inner class Admin declarations from your models. They won't
break anything if you leave them, but they also won't do anything. To register
apps with the admin you'll move those declarations to an admin.py file;
see the admin below for more details.
ContohLink to this heading
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)
AdminLink to this heading
One of the biggest changes in 1.0 is the new admin. The Django administrative
interface (django.contrib.admin) has been completely refactored; admin
definitions are now completely decoupled from model definitions, the framework
has been rewritten to use Django's new form-handling library and redesigned with
extensibility and customization in mind.
Practically, this means you'll need to rewrite all of your class Admin
declarations. You've already seen in models above how to replace your class
Admin with a admin.site.register() call in an admin.py file. Below are
some more details on how to rewrite that Admin declaration into the new
syntax.
Gunakan sintaks seiring yang baruLink to this heading
The new edit_inline options have all been moved to admin.py. Here's an
example:
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 fieldsetsLink to this heading
The old fields syntax was quite confusing, and has been simplified. The old
syntax still works, but you'll need to use fieldsets instead.
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'}),
)
URLLink to this heading
Perbaharui akar urls.py anda.Link to this heading
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 ...
)
ViewLink to this heading
Gunakan django.forms sebagai gantinya newformsLink to this heading
Replace django.newforms with django.forms -- Django 1.0 renamed the
newforms module (introduced in 0.96) to plain old forms. The
oldforms module was also removed.
If you're already using the newforms library, and you used our recommended
import statement syntax, all you have to do is change your import
statements.
Lama:
from django import newforms as forms
Baru:
from django import forms
If you're using the old forms system (formerly known as django.forms and
django.oldforms), you'll have to rewrite your forms. A good place to start
is the forms documentation
Menangani berkas terunggah menggunakan API baruLink to this heading
Replace use of uploaded files -- that is, entries in request.FILES -- as
simple dictionaries with the new
UploadedFile. The old dictionary
syntax no longer works.
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) |
|---|---|
|
|
|
|
|
|
Bekerja dengan bidang berkas menggunakan API baruLink to this heading
The internal implementation of django.db.models.FileField have changed.
A visible result of this is that the way you access special attributes (URL,
filename, image size, etc.) of these model fields has changed. You will need to
make the following changes, assuming your model's
FileField is called myfile:
Lama (0.96) |
Baru (1.0) |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Note that the width and height attributes only make sense for
ImageField fields. More details can be found in the
model API documentation.
Gunakan Paginator daripada ObjectPaginatorLink to this heading
The ObjectPaginator in 0.96 has been removed and replaced with an improved
version, django.core.paginator.Paginator.
TemplatLink to this heading
Learn to love autoescapingLink to this heading
By default, the template system now automatically HTML-escapes the output of every variable. To learn more, see Automatic HTML escaping.
To disable auto-escaping for an individual variable, use the safe
filter:
This will be escaped: {{ data }}
This will not be escaped: {{ data|safe }}
To disable auto-escaping for an entire template, wrap the template (or just a
particular section of the template) in the autoescape tag:
{% autoescape off %}
... unescaped template content here ...
{% endautoescape %}
Less-common changesLink to this heading
The following changes are smaller, more localized changes. They should only affect more advanced users, but it's probably worth reading through the list and checking your code for these things.
SinyalLink to this heading
Add
**kwargsto any registered signal handlers.Connect, disconnect, and send signals via methods on the
Signalobject instead of through module methods indjango.dispatch.dispatcher.Remove any use of the
AnonymousandAnysender options; they no longer exist. You can still receive signals sent by any sender by usingsender=NoneMake any custom signals you've declared into instances of
django.dispatch.Signalinstead of anonymous objects.
Berikut rekap dari perubahan kode yang perlu anda lakukan:
Lama (0.96) |
Baru (1.0) |
|---|---|
|
|
|
|
|
|
|
|
|
|
Rasa lokalLink to this heading
Rasa lokal U.SLink to this heading
django.contrib.localflavor.usa has been renamed to
django.contrib.localflavor.us. This change was made to match the naming
scheme of other local flavors. To migrate your code, all you need to do is
change the imports.
SesiLink to this heading
Mendapatkan kunci sesi baruLink to this heading
SessionBase.get_new_session_key() telah dinamai kembali menjadi _get_new_session_key(). get_new_session_object() tidak lagi ada.
PerlengkapanLink to this heading
Memuat sebuah baris yang tidak memanggil save()Link to this heading
Previously, loading a row automatically ran the model's save() method. This
is no longer the case, so any fields (for example: timestamps) that were
auto-populated by a save() now need explicit values in any fixture.
PengaturanLink to this heading
Pengecualian terbaikLink to this heading
The old EnvironmentError has split into an
ImportError when Django fails to find the settings module
and a RuntimeError when you try to reconfigure settings
after having already used them.
LOGIN_URL telah dipindahkanLink to this heading
The LOGIN_URL constant moved from django.contrib.auth into the
settings module. Instead of using from django.contrib.auth import
LOGIN_URL refer to settings.LOGIN_URL.
Kebiasaan APPEND_SLASH telah diperbaharuiLink to this heading
In 0.96, if a URL didn't end in a slash or have a period in the final
component of its path, and APPEND_SLASH was True, Django would
redirect to the same URL, but with a slash appended to the end. Now, Django
checks to see whether the pattern without the trailing slash would be matched
by something in your URL patterns. If so, no redirection takes place, because
it is assumed you deliberately wanted to catch that pattern.
For most people, this won't require any changes. Some people, though, have URL patterns that look like this:
r'/some_prefix/(.*)$'
Previously, those patterns would have been redirected to have a trailing slash. If you always want a slash on such URLs, rewrite the pattern as:
r'/some_prefix/(.*/)$'
Perubahan model kecilLink to this heading
Pengecualian berbeda dari get()Link to this heading
Managers now return a MultipleObjectsReturned
exception instead of 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 has been firedLink to this heading
The LazyDate helper class no longer exists.
Default field values and query arguments can both be callable objects, so
instances of LazyDate can be replaced with a reference to 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 is new, and FloatField is now a proper floatLink to this heading
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)
...
If you forget to make this change, you will see errors about FloatField
not taking a max_digits attribute in __init__, because the new
FloatField takes no precision-related arguments.
If you're using MySQL or PostgreSQL, no further changes are needed. The
database column types for DecimalField are the same as for the old
FloatField.
If you're using SQLite, you need to force the database to view the
appropriate columns as decimal types, rather than floats. To do this, you'll
need to reload your data. Do this after you have made the change to using
DecimalField in your code and updated the Django code.
To upgrade each application to use a DecimalField, you can do the
following, replacing <app> in the code below with each app's name:
$ ./manage.py dumpdata --format=xml <app> > data-dump.xml
$ ./manage.py reset <app>
$ ./manage.py loaddata data-dump.xml
Catatan:
It's important that you remember to use XML format in the first step of this process. We are exploiting a feature of the XML data dumps that makes porting floats to decimals with SQLite possible.
In the second step you will be asked to confirm that you are prepared to lose the data for the application(s) in question. Say yes; we'll restore this data in the third step, of course.
DecimalFieldis not used in any of the apps shipped with Django prior to this change being made, so you do not need to worry about performing this procedure for any of the standard Django models.
If something goes wrong in the above process, just copy your backed up database file over the original file and start again.
InternasionalisasiLink to this heading
django.views.i18n.set_language() sekarang membutuhkan permintaan POSTLink to this heading
Previously, a GET request was used. The old behavior meant that state (the locale used to display the site) could be changed by a GET request, which is against the HTTP specification's recommendations. Code calling this view must ensure that a POST request is now made, instead of a GET. This means you can no longer use a link to access the view, but must use a form submission of some kind (e.g. a button).
_() is no longer in builtinsLink to this heading
_() (the callable object whose name is a single underscore) is no longer
monkeypatched into builtins -- that is, it's no longer available magically in
every module.
If you were previously relying on _() always being present, you should now
explicitly import ugettext or ugettext_lazy, if appropriate, and alias
it to _ yourself:
from django.utils.translation import ugettext as _
Obyek HTTP request/responseLink to this heading
Akses kamus ke HttpRequestLink to this heading
HttpRequest objects no longer directly support dictionary-style
access; previously, both GET and POST data were directly
available on the HttpRequest object (e.g., you could check for a
piece of form data by using if 'some_form_key' in request or by
reading request['some_form_key']. This is no longer supported; if
you need access to the combined GET and POST data, use
request.REQUEST instead.
It is strongly suggested, however, that you always explicitly look in
the appropriate dictionary for the type of request you expect to
receive (request.GET or request.POST); relying on the combined
request.REQUEST dictionary can mask the origin of incoming data.
Mengakses kepala HTTPResponseLink to this heading
django.http.HttpResponse.headers has been renamed to _headers and
HttpResponse now supports containment checking directly.
So use if header in response: instead of if header in response.headers:.
Hubungan umumLink to this heading
Generic relations have been moved out of coreLink to this heading
The generic relation classes -- GenericForeignKey and GenericRelation
-- have moved into the django.contrib.contenttypes module.
PengujianLink to this heading
meth:django.test.Client.login telah berubahLink to this heading
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 perintahLink to this heading
Menjalankan pengelolaan perintah dari kode andaLink to this heading
django.core.management has been greatly refactored.
Calls to management services in your code now need to use
call_command. For example, if you have some test code that calls flush and
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)
Subcommands must now precede optionsLink to this heading
django-admin.py and manage.py now require subcommands to precede
options. So:
$ django-admin.py --settings=foo.bar runserver
...tidak lagi bekerja dan harus dirubah menjadi:
$ django-admin.py runserver --settings=foo.bar
Struktur dataLink to this heading
SortedDictFromList` telah pergiLink to this heading
django.newforms.forms.SortedDictFromList was removed.
django.utils.datastructures.SortedDict can now be instantiated with
a sequence of tuples.
Untuk memperbaharui kode anda:
Use
django.utils.datastructures.SortedDictwherever you were usingdjango.newforms.forms.SortedDictFromList.Because
django.utils.datastructures.SortedDict.copydoesn't return a deepcopy asSortedDictFromList.copy()did, you will need to update your code if you were relying on a deepcopy. Do this by usingcopy.deepcopydirectly.
Fungsi basisdata backendLink to this heading
Fungsi basisdata backend telah diubah namanyaLink to this heading
Almost all of the database backend-level functions have been renamed and/or
relocated. None of these were documented, but you'll need to change your code
if you're using any of these functions, all of which are in django.db:
Lama (0.96) |
Baru (1.0) |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
connection.ops.fulltext_search_sql` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
KomentarLink to this heading#
If you were using Django 0.96's
django.contrib.commentsapp, you'll need to upgrade to the new comments app introduced in 1.0. See the upgrade guide for details.