适当减少手机使用,有助于视力保护... 新的一年祝您:身体健康,阖家欢乐!~~

Flask-SQLAlchemy model 类的继承

浏览量:1562 作者:admin 类别:: 学习笔记 更新时间:2023-05-25 12:32:41

在模型类的继承中发现,直接继承,然后在子类中重新定义 表名,并不能实现自己所想

比如:

class User(db.Model):
    __tablename__='users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)

class SecondUser(User):
    __tablename__='second_users'
    pass


实现应用中,并没有生成这个second_users表,而是直接使用了users表。说明并不能通过这种方法来重写


根据chatgpt的提示,我定义了一下基类。

class BaseUser(db.Model):
    __abstract__ = True

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)


class User(BaseUser):
    __tablename__='users'
    pass

class SecondUser(BaseUser):
    __tablename__='second_users'
    pass


这样就成功实现了。


但在后期的使用中,想方法模型类中的其它方法时,出现了问题。


在子类中想使用父级基类中的方法时,无法直接对子类进行实例化,也无法访问到其父级基类的方法。


那应该怎么办呢?

一、重新定义,相对比较麻烦。

二、直接修改基类,定义方法为类方法。则可以直接使用,User.func() 


以下是chatgpt给到的答案和方法:

如果一个模型类是从另一个抽象基类中继承而来的,那么它不能直接被实例化。由于它是抽象类,存在意义就是为了被其他类继承使用,而不是直接实例化使用。

如果在子类中想使用基类中的方法,通常有两种方法:

1.在子类中重新定义该方法,并根据需要对其进行修改。

例如,我们有以下的抽象基类:

```python
class BaseUser(db.Model):
    __abstract__ = True

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)

    def serialize(self):
        return {
            'id': self.id,
            'name': self.name,
            'email': self.email
        }
```

如果我们想在子类`User`中使用`serialize()`方法,可以这样做:

```python
class User(BaseUser):
    ...

    def serialize(self):
        data = super().serialize()
        data['extra_field'] = 'example'
        return data
```

在这个例子中,`User`类重新定义了`serialize()`方法,并在基类的方法调用上使用了`super()`函数来调用基类的`serialize()`方法。然后,它在基类方法返回的字典中添加了一个额外的字段,并返回修改后的字典。

2.在子类中通过实例化基类来调用其方法。

另一种方法是在子类中通过实例化基类来调用其方法。

例如,在基类中添加一个额外的方法:

```python
class BaseUser(db.Model):
    __abstract__ = True

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)

    def serialize(self):
        return {
            'id': self.id,
            'name': self.name,
            'email': self.email
        }

    @classmethod
    def get_users(cls):
        return cls.query.all()
```

如果我们想在子类`User`中使用`get_users()`方法,我们可以这样做:

```python
class User(BaseUser):
    ...

    @classmethod
    def get_all_users(cls):
        return BaseUser.get_users()
```

在这个例子中,`User`类重新定义了`get_all_users()`方法,并在其中使用`BaseUser.get_users()`方法来获取所有用户,而不是使用`cls.query.all()`来获取用户。


关于博主
北京南城网络及弱电【张工】为您提供:
校园网、楼宇、村镇、园区,光纤网络覆盖,无线覆盖 华为|H3c|锐捷|爱快|panabit等品牌,路由、交换机、AC、AP 无源光网络(PON)设备,布署、调试、维运,等服务...
应急/临时光纤熔接...[藤仓22S]
博文为学习python所写:内容摘自网络、学习笔记、记事备忘。
QQ:872876353,欢迎交流学习、加Q注明来意。

诗文鉴赏

《满江红》· 岳飞
落星侵晓没,
残月半山低。
怒发冲冠,
凭栏处、潇潇雨歇。
抬望眼、仰天长啸,壮怀激烈。
三十功名尘与土,八千里路云和月。
莫等闲、白了少年头,
空悲切。
源于生活-记录日常
The site based on python 3 with flask...