TaleLin / lin-cms-flask

🎀A simple and practical CMS implememted by Flask
http://doc.cms.talelin.com/
Other
832 stars 216 forks source link

使用扩展过的 user_model 模型建立多对多关系时报错 #111

Closed yyywang closed 3 years ago

yyywang commented 4 years ago

使用扩展过的 user_model 模型(类名为User)建立多对多关系,程序可以跑起来,但是接收 http 请求时就会报错

  1. 关联表 like_and_quota
    
    # /app/models/association_tables.py

from sqlalchemy import Table, Column, Integer, ForeignKey from lin.interface import InfoCrud as Base

用户点赞的语录

like_and_quota = Table('like_and_quota', Base.metadata, Column('user_id', Integer, ForeignKey('lin_user.id')), Column('quota_id', Integer, ForeignKey('quota.id')))


2. 扩展 `user_model` 的 `User` 模型

/app/models/user.py

from lin import db from lin.core import User as _User from sqlalchemy import Column, String from sqlalchemy.orm import relationship from app.models.association_tables import like_and_quota

class User(_User): wx_openid = Column(String(190)) # 微信 openid liked_quotas = relationship('Quota', secondary=like_and_quota, back_populates='liked_users') # 该用户点赞的语录(与 Quota 模型建立多对多关系)


3. 业务模型 `Quota`

/app/models/quota.py

from lin import db from lin.exception import NotFound from lin.interface import InfoCrud as Base from sqlalchemy import Column, Integer, Text, ForeignKey from sqlalchemy.orm import relationship from app.models.category import Category from app.models.association_tables import like_and_quota

class Quota(Base): id = Column(Integer, primary_key=True, autoincrement=True) content = Column(Text) # html 格式 content_text = Column(Text) # 纯文本格式 category_id = Column(Integer, ForeignKey('category.id')) category = relationship('Category', back_populates='quotas') # 所属分类 liked_users = relationship('User', secondary=like_and_quota ,back_populates='liked_quotas') # 点赞该语录的用户


+ `create_app`

def create_app(register_all=True, environment='production'): app = LinFlask(name, static_folder='./assets') app.config['ENV'] = environment env = app.config.get('ENV') if env == 'production': app.config.from_object('app.config.setting.ProductionConfig') app.config.from_object('app.config.secure.ProductionSecure') elif env == 'development': app.config.from_object('app.config.setting.DevelopmentConfig') app.config.from_object('app.config.secure.DevelopmentSecure') app.config.from_object('app.config.log') if register_all: register_blueprints(app) from app.models.user import User Lin(app, user_model=User) register_before_request(app) register_after_request(app) apply_cors(app)

创建所有表格

    create_tables(app)

return app

+ 报错信息

sqlalchemy.exc.InvalidRequestError: Multiple classes found for path "User" in the registry of this declarative base. Please use a fully module-qualified path.


+ bug 修复
将 `User` 模型换个名称即可,但是官方文档中扩展 `user_model` 模型的示例使用的名称是 `User`,且未说明扩展模型名称不能为 `User`。以下示例中我将 `User` 改为 `CUser`,则不会报错。

**正确代码:**

/app/models/user.py

class CUser(_User):

/app/models/quota.py

liked_users = relationship('CUser', secondary=like_and_quota ,back_populates='liked_quotas') # 点赞该语录的用户

/app/app.py

from app.models.user import CUser Lin(app, user_model=CUser)

colorful3 commented 4 years ago

描述的太仔细了,感谢您的反馈!我们会根据建议修复这个问题。