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 %}