Question

I'm trying to get my user class to work with both BaseModel and FlaskView. This results in the metaclass conflict error and I can't solve it.

Things I have tried to fix the problem:
This didn't work because of the from noconflict import classmaker. The example is from June 2003. Maybe it is too old? I'm running on python 2.7.3.
http://code.activestate.com/recipes/204197-solving-the-metaclass-conflict/

Also tried this solution, see the code blocks below. I get this error: AttributeError: type object 'BaseModel' has no attribute 'metaclass'
Double inheritance causes metaclass conflict

from base_model import BaseModel
from flask.ext.classy import FlaskView

class CombinedMeta(BaseModel.__metaclass__, FlaskView.__metaclass__):
    pass


from peewee import *
#sqlite is used for easy testing.
mysql_db = SqliteDatabase('test.db')


class BaseModel(Model):

    class Meta:
        database = mysql_db


from combined_meta import CombinedMeta
from base_model import BaseModel
from flask.ext.classy import FlaskView
from flask.ext.classy import route
from peewee import *
from flask import request
from utility import response_json
from utility import send_email
from utility import random_string

class User(BaseModel, FlaskView):
    __metaclass__ = CombinedMeta

    @route('/<username>', methods=['GET'])
    def read_user(self, username):
        #cool method stuff

When I change the BaseModel class to the following code I get a new error.
class BaseModel(Model): TypeError: Error when calling the metaclass bases this constructor takes no arguments

from peewee import *
#sqlite is used for easy testing.
mysql_db = SqliteDatabase('test.db')


class BaseModel(Model):

    class Meta:
        database = mysql_db

    __metaclass__ = Meta

I have no idea how I can fix this, I'm new to Python. My main goal is to get the program working with multiple classes. That is why I'm trying to get flask classy to work.

A way to fix this problem without flask classy is just as welcome as any other fix. If not using flask classy is more easy I'll give that a try.

EDIT
When calling the metaclass bases, object.__init__() takes no parameters

class Meta(type):
    database = mysql_db

When I change the code to this I get the following error:
TypeError: Error when calling the metaclass bases metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

Was it helpful?

Solution

I managed to solve the problem by not using flask-classy. Instead I'm using blueprints, flask documentation. I no longer need both BaseModel and FlakView, only the BaseModel is needed now.

Here is my working code:
I no longer need FlaskView because I don't use flak-classy anymore. No more meteclass error!

_init_.py

from flask import Flask
import user
app = Flask(__name__)
app.register_blueprint(user.bp)

user.py

from base_model import BaseModel
class User(BaseModel):
    username = CharField(primary_key=True)
    password = CharField(null=False)

bp = Blueprint('user', __name__)

@bp.route('/user/method', method=['GET'])
def method()
#method stuff
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top