Django 1.0 发布后,其 API 基本上已经稳定下来,但它对以往的 0.9x 版本有不少的不兼容地方。这个教程就是帮助大家将基于 Django 0.96的项目或者 Apps(应用)迁移到 1.0。而且,网上大多数教程都是基于0.96的,了解0.96与1.0的兼容问题,有助于大家更好学习和利用以往的教程。
常见的变迁
这是用户从 Django 0.96迁移到1.0时最常遇到的需要作出的的变迁。
Unicode
Django 1.0已经完全使用 Unicode 字符串(如 u’foo’)。虽然在大多数情况下,使用普通的字符串(raw string)也不会出问题,但更新至 Unicode 字符串可以避免一些莫名其妙的问题。
详情参阅: Unicode data in Django
Models
maxlength 重命名为 max_length
这是为了统一字段格式。
__unicode__ 取代 __str__
将 model 里面的 __str__ 方法替换为 __unicode__ 方法,并且确保在 __unicode__ 方法内使用的字符串全部是 Unicode 字符串(如 u’foo’)。
移除 prepopulate_from 参数
移除 model 字段内的 prepopulate_from 参数,将它移到 admin.py 里的 ModelAdmin 类里面。
移除 core 参数
移除 model 字段内的 core 参数,因为 admin 接口现在已经提供相同的功能。你不必担心到影响 inline editing,可以放心的删除所有对 core 的引用。
admin.py 模块取代 Admin 类
移除所有 models 内的 Admin 内部类,因为它不起任何作用了。现在使用 admin.py 文件来注册 Apps 到 admin。当然,留着它不理也常会影响到应用的正常运行。
示例
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)
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)
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
一个全新、完全重构过的 Admin 后台管理接口,这是 Django 1.0最大的变化之一。Admin 现在并不需要在 modle 里面作定义。Admin 的框架使用 Django 新的 form-handing 库重写过,变得更为具扩展性。
这意味着你必须重写 Admin 类的定义。正如上面的示例,以前 models 内的 Admin 类的定义被 admin.py 文件内的 admin.site.register() 方法替代了。下面将详细讲解如何重写一个 Admin 的定义。
另见: djangosnippets 上的一个贡献者写了一个脚本,可以自动扫描 models.py 并生成相应的 admin.py 文件。
新的 inline 语法
新的 edit_inline 参数选项移至 admin.py。示例:
旧的0.96的 model.py:
class Parent(models.Model):
...
class Child(models.Model):
parent = models.ForeignKey(Parent, edit_inline=models.STACKED, num_in_admin=3)
对应新的1.0的 admin.py:
class ChildInline(admin.StackedInline):
model = Child
extra = 3
class ParentAdmin(admin.ModelAdmin):
model = Parent
inlines = [ChildInline]
admin.site.register(Parent, ParentAdmin)
见: InlineModelAdmin objects 有详细的说明。
简化 fields 语法,或者使用 fieldsets
旧的语法同样可以照常使用,使需要用 fieldsets 代替 fields。
旧的0.96的 model.py:
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'}),
)
新的1.0的 admin.py:
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'}),
)
另见:
- 更详尽的可查看 NewformsAdminBranch wiki page
- 关于 Admin 新的特性,可以查看 admin documentation
URLs
更新根目录下的 urls.py
如果需要使用 admin 来进行后台管理,你必须更新 root 下的 urls.py 文件。
旧的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 ...
)
新的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 ...
)
Views
django.forms 替代 newforms
newforms 将被重命名为 forms,而 oldforms 将会被移除。如果你在应用中使用了 newforms,建议修改 import 语句:
旧的:
from django import newforms as forms
新的:
from django import forms
使用新的 API 处理上传的文件
旧的 API 将不再有效。示例:
像这样的上传的文件:
def my_view(request): f = request.FILES['file_field_name'] ...
你必须作如下的变迁:
| Old (0.96) | New (1.0) |
|---|---|
| f['content'] | f.read() |
| f['filename'] | f.name |
| f['content-type'] | f.content_type |
FileField
django.db.models.FileField 的内部现实已经改变了。假设一个 model 的 FileField 叫做 myfile,你必须作出如下的变迁:
| Old (0.96) | New (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 |
Templates
Autoescapeing(自动转义)
现在,模板系统将对输出变量中的 HTML 标签自动进行转义操作。说情参看 Automatic HTML escaping。
如果要禁用个别变量进行自动转义(auto-escaping),可以使用 safe 过滤器(filter):
默认会进行自动转义: {{ data }}
加上 safe 过滤器后会禁止进行转义: {{ data|safe }}
如果要对模板内的一部分输出内容禁止进行转义,可以使用 autoescape 标签(tag):
{% autoescape off %}
... 这部分内容将不会进行自动转义 ...
{% endautoescape %}