一对多关系建立

在数据模型中建立一对多的关系的数据库 如文章分类Category(__tablename__='category')(一)和发布的文章Post(__table__='post')(多),一个分类下可以发布多篇文章。可以如下建立模型:

from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash

class Admin(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20))
    password_hash = db.Column(db.String(128))
    blog_title = db.Column(db.String(60))
    blog_sub_title = db.Column(db.String(100))
    name = db.Column(db.String(30))
    about = db.Column(db.Text)
    # @property (装饰器让方法属性话)  admin=Admin() admin.password()等于 admin.password 就可以取到密码当然这里为了密码安全是不可以取到密码
    @property
    def password(self):
        raise AttributeError('password is not a readable attribute')
        
    # 这个让设置密码可以直接赋值 admin.password = 'pwd'等同于不用装饰器时候admin.password('pwd')
    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)  #用户输入的密码进行加密存储到数据库中字段password_hash

    def verify_password(self, password):
        return check_password_hash(self.password_hash, password) # 判断用户输入的密码(原文)和数据库中存储的hash加密值解密后是否一致

class Category(db.Model):   # 分类代表(一)
    __tablename__='category'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30), unique=True)
    
    
class Post(db.Model):  # 文章代表(多)
    __tablename__='post'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(60))
    body = db.Column(db.Text)
    timestamp = db.Column(db.DateTime, default=datetime.utcnow, index=True)
    can_comment = db.Column(db.Boolean, default=True)
    
    category_id = db.Column(db.Integer, db.ForeignKey('category.id'))   # 建立外键  总是在多这一侧建立
    category = = db.relationship('Category', backref=db.backref('posts'))  # 建立关系属性反方向引用相当于快捷查询不会写入数据库

2.一对多基于对象的插入

一、一般插入新增操作(一对多插入数据)

c=Category(name="python")

obj = db.session.query(Category).filter_by(name=="python).first()

p = Post(title="python flask",body="content",category_id=obj.id)

b.session.add_all([c,p])

db.session.commit()

二、插入数据(增加了backref方向引用后在插入多的对象(文章)时可以把一的对象(分类)的相关属性也添加进去,同时在多的表中会生成相关外键关联category_id

#category=Category(name="python") 前提是要在post表中加入db.relationship关联。

p=Post(title="flask orm",body="内容",category=Category(name="python")

#上述等同于

#p=Post(title="flask orm",body="内容")

#p.category=Category(name="python")

db.session.add(p)

db.session.commit()

三、通过反向操作从某一分类直接插入该分类的相应多篇文章

c=Category(name="scratch")

c.categorys=[Post(title="scratch 入门",body="内容"),Post(title="scratch 进阶",body="内容")]

db.session.add(c)

db.session.commit()

3.查询:基于对象跨表查询(子查询,查询了2次)

p=db.session.query(Post).filter_by(title="flask orm").first()

p.category.name #查出flask orm这篇文章所属的分类

c=db.session.query(Category).filter_by(name="python")

c.posts

4.查询:基于连表的跨表查询(查一次)

post_list=db.session.query(Post,Category,).join(Category,isouter=True).all() # 默认以外键连表

for row in post_list;

print(row[0].name,row[1].title)     #  查询文章标题 和分类Category.name Post.title



0 评论 最近

没有评论!