You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

首次尝试Django 2.0模型执行migrations时触发AttributeError

解决Django 2.0模型迁移与Admin注册的AttributeError问题

问题根源

你的错误完全来自admin.py里错误的模型注册方式!admin.site.register()的正确用法是一次注册一个模型,第二个参数是可选的自定义ModelAdmin类(用来定制后台展示),而你把两个模型放在同一个register调用里:

admin.site.register(Author, Book)

这相当于告诉Django:用Book这个模型类作为Author的后台管理类,但Book并不是ModelAdmin的子类,Django尝试访问它的model属性时自然会抛出AttributeError: 'Book' object has no attribute 'model'。

修正Admin注册代码

把每个模型单独注册,修改后的admin.py应该是这样:

from django.contrib import admin
from .models import (Author, Book, Narrator, Audiobook)

# 每个模型单独调用register方法
admin.site.register(Author)
admin.site.register(Book)
admin.site.register(Narrator)
admin.site.register(Audiobook)

如果之后需要给某个模型定制后台展示(比如显示特定字段),再添加自定义ModelAdmin类,比如给Book加后台展示:

class BookAdmin(admin.ModelAdmin):
    # 后台列表显示的字段
    list_display = ('title', 'list_authors', 'finished')

# 注册时传入自定义的ModelAdmin
admin.site.register(Book, BookAdmin)

解决后续迁移/URL错误

你提到注释注册代码后迁移成功但后续报'urls'属性错误,这是因为之前错误的注册导致Django的Admin站点初始化异常,残留了错误状态。现在按以下步骤操作:

  1. 检查你的migrations目录,删除任何因错误操作生成的多余迁移文件(保留最初的正确迁移,比如0001_initial.py)
  2. 重新执行迁移命令:
    python manage.py makemigrations
    python manage.py migrate
    
  3. 启动服务后访问Admin后台,应该就能正常运行了。

额外建议:模型继承的注意点

你的Audiobook继承自Book,Django默认是多表继承(即Audiobook会生成一张单独的表,同时关联Book表)。如果你的业务需求是让Audiobook作为Book的子类,共用同一张表(单表继承),需要给Book添加abstract = True的Meta类:

class Book(models.Model):
    title = models.CharField(max_length=150)
    description = models.TextField(blank=True, null=True)
    series = models.CharField(max_length=150, blank=True, null=True)
    authors = models.ManyToManyField(Author, blank=True)
    finished = models.BooleanField(default=False, verbose_name="Finished")

    class Meta:
        abstract = True  # 标记为抽象模型,不会生成单独的表

根据你的实际业务场景选择即可。

内容的提问来源于stack exchange,提问作者Derrick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:35:22