django-mptt 字段出现两次,破坏了 SQL
我正在使用 django-mptt 来管理一个简单的 CMS,其模型名为 Page
,如下所示(大多数可能是不相关的字段被删除):
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< /code>、
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()
中出现两次?
I'm using django-mptt to manage a simple CMS, with a model called Page
, which looks like this (most presumably irrelevant fields removed):
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.')
removed fields are called attachments
, headline_image
, nav_override
, and published
All works fine using SQLite, but when I use MySQL and try and add a Page using the admin (or using ModelForms and the save()
method), I get this:
ProgrammingError at /admin/mycms/page/add/
(1110, "Column 'level' specified twice")
where the SQL generated is:
'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)'
for some reason I'm getting the django-mptt fields (lft
, rght
, tree_id
and level
) twice. It works in SQLite presumably because SQLite is more forgiving about what it accepts than MySQL.
get_all_field_names()
also shows them twice:
>>> Page._meta.get_all_field_names()
['attachments', 'children', 'contents', 'headline_image', 'id', 'level', 'lft',
'nav_override', 'parent', 'published', 'rght', 'slug', 'title', 'tree_id']
Which is presumably why the SQL is bad. What could I have done that would result in those fields appearing twice in get_all_field_names()
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我注意到您继承了多个基类,
class Page(mptt.Model, BaseModel):
。在这两个模型上都找到了重复的字段吗?I noticed that you're inheriting from multiple base classes,
class Page(mptt.Model, BaseModel):
. Are the fields that are being duplicated found on both of those models?由于您使用的是允许继承的 mptt 分支,我们假设继承 mptt.Model与使用 mptt.register() 相同。
运行
manage.py sqlall
时是否看到重复字段?当我使用sqlite3或mysql运行它时,使用branched_mptt看起来不错:如果该输出看起来不错,那么您的PageAdmin呢?你在那里做了什么奇特的事情吗?如果是这样,您是否尝试过使用普通的页面管理员模型?
Since you are using a branch of mptt that allows for inheritance, lets assume that inheriting mptt.Model is the same as using mptt.register().
Do you see duplicate fields when you run
manage.py sqlall
? It looks OK using the branched_mptt when I run it with sqlite3 or mysql:If that output looks OK, what about your PageAdmin? Are you doing anything fancy there? If so, have you tried with a plain vanilla model admin for Page?
问题似乎是这些字段被动态添加了两次(我认为是因为
settings.py
被导入了两次。我最终通过使用常规方法修复了它django-mptt 版本,并将其添加到我的
__init__.py
中:不是世界上最漂亮的东西,但它有效!
The problem appeared to be that the fields were being dynamically added twice (I think because of the way
settings.py
is imported twice.I ended up fixing it by using the regular version of django-mptt, and adding this to my
__init__.py
:Not the prettiest thing in the world, but it works!