Поля 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
, headline_image
, nav_override
, а также published
Все отлично работает с использованием SQLite, но когда я использую MySQL и пытаюсь добавить страницу с помощью администратора (или используя 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()
?
3 ответа
Проблема заключалась в том, что поля были добавлены динамически дважды (я думаю, из-за способа settings.py
импортируется дважды.
В итоге я исправил это, используя обычную версию django-mptt, и добавил это к своему __init__.py
:
from cbc.kaleo.models import Page
import mptt
try:
mptt.register(Page)
except mptt.AlreadyRegistered:
pass
Не самая красивая вещь в мире, но она работает!
Я заметил, что вы наследуете от нескольких базовых классов, class Page(mptt.Model, BaseModel):
, Обнаружены ли дублирующиеся поля на обеих этих моделях?
Поскольку вы используете ветку 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
? Он выглядит нормально, используя branched_mptt, когда я запускаю его с sqlite3 или mysql:
$ ./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? Вы делаете что-нибудь модное там? Если да, то пробовали ли вы с простым ванильным администратором модели для Пейджа?
# admin.py
from django.contrib import admin
from kaleo.models import Page
admin.site.register(Page)