我正在使用django-mptt来管理一个名为Page
的模型的简单CMS,它看起来像这样(大多数可能是不相关的字段被移除):
class Page(mptt.Model, BaseModel):
title = models.CharField(max_length = 20)
slug = AutoSlugField(populate_from = 'title')
contents = models.TextField()
parent = models.ForeignKey('self', null=True, blank=True,
related_name='children', help_text = u'The page this page lives under.')
删除的字段称为attachments
,headline_image
,nav_override
和published
使用SQLite一切正常,但是当我使用MySQL并尝试使用admin(或使用ModelForms和save()
方法)添加页面时,我得到了这个:
ProgrammingError at /admin/mycms/page/add/
(1110, "Column 'level' specified twice")
生成的SQL是:
'INSERT INTO `kaleo_page` (`title`, `slug`, `contents`, `nav_override`, `parent_id`,
`published`, `headline_image_id`, `lft`, `rght`, `tree_id`, `level`, `lft`, `rght`,
`tree_id`, `level`) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)'
由于某种原因,我得到了django-mptt字段(lft
,rght
,tree_id
和level
)两次。它可以在SQLite中运行,大概是因为SQLite对它接受的东西比MySQL更宽容。
get_all_field_names()
也会向他们展示两次:
>>> Page._meta.get_all_field_names()
['attachments', 'children', 'contents', 'headline_image', 'id', 'level', 'lft',
'nav_override', 'parent', 'published', 'rght', 'slug', 'title', 'tree_id']
这可能是SQL错误的原因。我可以做些什么会导致这些字段在get_all_field_names()
中出现两次?
答案 0 :(得分:1)
我注意到你是从多个基类继承的,class Page(mptt.Model, BaseModel):
。是否在这两个模型上找到了重复的字段?
答案 1 :(得分:1)
由于您使用的是允许继承的branch of mptt,因此我们假设继承mptt.Model与使用mptt.register()相同。
# Page and TrunkPage are basically the same
class Page(branched_mptt.Models, BaseModel):
# ...
class TrunkPage(BaseModel):
# ...
trunk_mptt.register(TrunkPage, order_insertion_by=['title'])
运行manage.py sqlall
时是否看到重复的字段?当我使用sqlite3或mysql运行它时,使用branched_mptt看起来没问题:
$ ./manage.py sqlall kaleo
BEGIN;
CREATE TABLE `kaleo_page` (
[ ... ]
`lft` integer UNSIGNED NOT NULL,
`rght` integer UNSIGNED NOT NULL,
`tree_id` integer UNSIGNED NOT NULL,
`level` integer UNSIGNED NOT NULL
)
[ ... ]
如果输出看起来没问题,那么你的PageAdmin怎么样?你在做什么花哨的吗?如果是这样,您是否尝试过使用普通香草模型管理员进行Page?
# admin.py
from django.contrib import admin
from kaleo.models import Page
admin.site.register(Page)
答案 2 :(得分:1)
问题似乎是字段被动态添加两次(我认为,因为导入settings.py
两次的方式。
我最后使用常规版本的django-mptt修复它,并将其添加到我的__init__.py
:
from cbc.kaleo.models import Page
import mptt
try:
mptt.register(Page)
except mptt.AlreadyRegistered:
pass
这不是世界上最漂亮的东西,但它有效!