I'm encountering an error when trying to create a User object from the Admin page using Flask-Admin with SQLAlchemy. The error occurs in link http://127.0.0.1:5000/admin/user/new/?url=/admin/user/ is:
AttributeError: 'tuple' object has no attribute 'items'
The issue arises when I attempt to access the page for adding a new user in the admin panel. I believe this is related to the way I'm passing enum values to the form, as I am using an Enum class for the role and gender fields in the User model. in models.py:
class Gender(Enum):
MALE = 'male'
FEMALE = 'female'
class UserRole(Enum):
ADMIN = 'admin'
PATIENT = 'patient'
class User(db.Model, UserMixin):
id = Column(Integer, autoincrement=True, primary_key=True)
username = Column(String(50), unique=True, nullable=False)
password = Column(String(100), nullable=False)
role = Column(EnumType(UserRole), nullable=False)
name = Column(String(100))
birth = Column(Date, default=datetime.date.today)
phone = Column(String(14), default="2134215567")
email = Column(String(100), unique=True)
gender = Column(EnumType(Gender))
address = Column(String(100), default="address")
avatar = Column(String(100),
default="https://res.cloudinary.com/dwvkjyixu/image/upload/v1715592288/avatars/pzh51raolcegilwmhm4g.jpg")
def __str__(self):
return self.username
class Admin(db.Model):
id = Column(Integer, ForeignKey(User.id), primary_key=True)
def __str__(self):
return User.query.get(self.id).name
class Patient(db.Model):
id = Column(Integer, ForeignKey(User.id), primary_key=True)
def __str__(self):
return User.query.get(self.id).name
class Product(db.Model):
id = Column(Integer, autoincrement=True, primary_key=True)
name = Column(String(50), nullable=True )
price = Column(Integer, nullable=True)
if __name__ == '__main__':
with app.app_context():
db.create_all()
in admin.py
from clinic import app, db
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
from clinic.models import User, UserRole, Product, Gender
from flask_login import current_user
admin = Admin(app=app, name="Private Clinic", template_mode = 'bootstrap4')
class AuthenticatedView(ModelView):
def is_accessible(self):
return current_user.is_authenticated and current_user.role == UserRole.ADMIN
class MyUserView(ModelView):
column_list = ['id', 'name', 'phone', 'username', 'email', 'address', 'role']
column_searchable_list = ['username', 'name', 'phone']
column_editable_list = ['name', 'role', 'gender']
can_export = True
column_filters = ['role']
column_labels = {
'id': 'ID',
'name': 'fullname',
'phone': 'SĐT',
'username': 'user name',
'email': 'Email',
'address': 'address',
'role': 'role',
}
admin.add_view(MyUserView(User, db.session))
admin.add_view(ModelView(Product, db.session))
in init.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import cloudinary
from flask_login import LoginManager
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = 'mysql+pymysql://root:12345@localhost/myclinic?charset=utf8mb4'
app.secret_key = '^%^&%^(*^^&&*^$%((^^&$$&^'
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
app.config["PAGE_SIZE"] = 4
cloudinary.config(
cloud_name = 'mycloud',
api_key = 'api_key',
api_secret = 'api_secret'
)
db = SQLAlchemy(app)
login = LoginManager(app)
I suspect that this issue is related to the Enum fields in my User model. Before this, I tested a Product class without using Enum, and it worked fine without any errors.
Could someone please help me understand why I'm getting this error with Enum fields in Flask Admin, while the code works fine without them?
Thanks in advance!