Sqlalchemy - 一对多用户定位

Sqlalchemy - One to Many Users to Location

希望一切都好。我很难弄清楚如何使用 Flask 和 SQLALCHEMY 编写此数据库功能。

我希望能够使用数据库中已存在的站点注册用户。

注册它们时,我希望路由能够将该用户分配给数据库中的站点模型。 我想这样做的原因是我以后可以向连接到特定站点的所有用户发送消息,或者向所有站点的所有用户发送消息。

这是我当前的用户和站点模型:

class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
site = db.Column(db.String())
username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(100), unique=True, nullable=False)
password = db.Column(db.String(60), nullable=False)
adminstatus = db.Column(db.Boolean)
user_data = db.relationship('Rma', backref='userdata', lazy=True)
# sites = db.relationship('Sites', secondary=usertosite, backref=db.backref('sites', lazy='dynamic'))

def __repr__(self):
    return f"User('{self.username}, '{self.email}')"

class Sites(db.Model):
id = db.Column(db.Integer, primary_key=True)
sitename = db.Column(db.String(), nullable=False)
contractstart = db.Column(db.String(), nullable=False)
contractend = db.Column(db.String(), nullable = False)
hwkey = db.Column(db.String(), nullable=False)
stations = db.Column(db.String(), nullable=False)
printers = db.Column(db.String(), nullable = False)
remprinters = db.Column(db.String(), nullable = False)
bof = db.Column(db.Boolean())
processor = db.Column(db.String(), nullable = False)
giftopt = db.Column(db.String(), nullable = False)

这是我的注册表

# REGISTER NEW USER
@app.route('/register', methods=['POST', 'GET'])
@login_required
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        hashed_pw = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
        user = User(site = form.site.data, username = form.username.data, email = form.email.data, password = hashed_pw, adminstatus= form.admin_status.data)
        db.create_all()
        db.session.add(user)
        db.session.commit()
        flash(f"{form.username.data} has been added!")
        return redirect(url_for('dash'))

    return render_template('register.html', name = 'login', form=form)

考虑到通常在将表单添加到数据库时我会将所有表单元素添加到特定模型,我不确定如何执行此操作。如果我尝试一对多关系,我将不得不分配 Sites 模型及其所有元素以及特定用户,这不是理想的,因为该站点已经在 db 中创建。我是一个超级菜鸟,我可能遗漏了一些步骤,但请尽可能提供帮助。谢谢大家。

您需要使用外键。

class User(db.Model, UserMixin):
    ...
    site = db.Column(db.Integer, db.ForeignKey('sites.id'))

然后,当您将 User 信息输入数据库时​​,您将提供作为 Sites 存在的站点的主键 ID。您可以在您的路线中执行此操作,也可以提供基于关键字执行此操作的初始化覆盖功能,例如:

class User(..):
    ...
    def __init__(self, **kwargs):
        if 'site' in kwargs:
             site_id = db.session.query(Sites).filter(Sites.sitename == kwargs['site']).one().id
             kwargs['site'] = site_id
        super().__init__(**kwargs)

请注意,我认为 mySQL 或 SQLite 默认情况下不会强制执行外键一致性,我个人觉得这很烦人,这意味着您可能会在 yoru 数据库中得到 NULL 条目,而您可能不希望它们出现,但是 POSTGRES 会执行它,我相信。但是,您可以在 sqlalchemy 中执行一些操作来强制 mySQL 和 SQLlite 中的外键一致性。