Search code examples
djangodjango-mpttmpttdjango-flatpages

Extending Django FlatPages to use MPTT


Preface: I was writing my own Page app that used MPTT and a custom page model. This was working for me, but FlatPages is more refined than my custom Page Model and so I'm leaning toward just extending it.

from django.db import models
from django.contrib.flatpages.models import FlatPage
from mptt.models import MPTTModel

class ExtendedFlatPage(FlatPage, MPTTModel):

    parent = models.ForeignKey('ExtendedFlatPage', null=True, blank=True, default=None, related_name="children", help_text="Hierarchical parent page (if any)")

    class Meta:
        ordering = ['flatpages__url']
        order_with_respect_to = 'parent'
        verbose_name = 'page'
        verbose_name_plural = 'pages'

    class MPTTMeta:
        left_attr = 'mptt_left'
        right_attr = 'mptt_right'
        level_attr = 'mptt_level'
        order_insertion_by = ['title']

    def __unicode__(self):
        return self.url

This almost works, except throws an error when I go to run python manage.py syncdb

Error:

iMac:cms colab$ python manage.py syncdb
Creating tables ...
Creating table my_flatpages_extendedflatpage
Traceback (most recent call last):
  File "manage.py", line 14, in <module>
    execute_manager(settings)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/__init__.py", line 438, in execute_manager
    utility.execute()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/__init__.py", line 379, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/base.py", line 191, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/base.py", line 220, in execute
    output = self.handle(*args, **options)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/base.py", line 351, in handle
    return self.handle_noargs(**options)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/core/management/commands/syncdb.py", line 101, in handle_noargs
    cursor.execute(statement)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/db/backends/util.py", line 34, in execute
    return self.cursor.execute(sql, params)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django-1.3-py2.7.egg/django/db/backends/mysql/base.py", line 86, in execute
    return self.cursor.execute(query, args)
  File "build/bdist.macosx-10.6-intel/egg/MySQLdb/cursors.py", line 174, in execute
  File "build/bdist.macosx-10.6-intel/egg/MySQLdb/connections.py", line 36, in defaulterrorhandler
django.db.utils.DatabaseError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 2")

If anyone could point me in the right direction, I would greatly appreciate it. Thanks!


Solution

  • replace

    class ExtendedFlatPage(FlatPage, MPTTModel):

    with

    class ExtendedFlatPage(MPTTModel, FlatPage):

    This will allow MPTTModel class to override FlatPage attributes and methods.

    @comment

    It appears that something (an attribute, method) in FlatPage model overrides something in MPTTModel cousing this error.

    order of classes you import from is important. here's an example:

    class A:
       attribute = 1
    class B:
       attribute = 2
    class C(A,B):
       pass
    

    class C attribute value will be 1.