Написание моего первого веб-приложения с использованием flask / SQLAlchemy. У меня есть много-много отношений между «людьми» и «объектами». Когда я успешно добавляю человека с помощью формы регистрации, в таблицу ассоциаций не добавляется строка. Нужно ли вставлять эту строку вручную?
Вот соответствующая часть модели:
# app/models.py
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
from app import db, login_manager
# [START model]
# Build secondary table for many to many between facilities and persons
workers = db.Table('workers',
db.Column('facility_id', db.Integer, db.ForeignKey('facilities.id')),
db.Column('person_id', db.Integer, db.ForeignKey('persons.id'))
)
class Facility(db.Model):
__tablename__='facilities'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(60))
description = db.Column(db.String(128))
persons = db.relationship('Person', secondary='workers', backref='facilities', lazy = 'dynamic')
def __repr__(self):
return "<Facility name='%s')" % (self.name)
class Person(UserMixin, db.Model):
__tablename__ = 'persons'
id = db.Column(db.Integer, primary_key=True)
last_name = db.Column(db.String(60), index=True)
username = db.Column(db.String(60), index=True, unique=True)
email = db.Column(db.String(80), index=True)
password_hash = db.Column(db.String(128))
first_name = db.Column(db.String(60), index=True)
role = db.Column(db.Integer, db.ForeignKey('roles.id'))
is_person_active = db.Column(db.Boolean, index=True)
is_admin = db.Column(db.Boolean, default=False)
comments = db.Column(db.String(255))
animals = db.relationship('Animal', secondary='permissions', backref='persons', lazy = 'dynamic'))
@property
def password(self):
"""
Prevent password from being accessed
"""
raise AttributeError('password is not a readable attribute.')
@password.setter
def password(self, password):
"""
Set password to a hashed password
"""
self.password_hash = generate_password_hash(password)
def verify_password(self, password):
"""
Check if hashed password matches actual password
"""
return check_password_hash(self.password_hash, password)
def __repr__(self):
return "<Person name='%s', '%s', '%s')" % (self.first_name, self.last_name, self.username)
# Set up user_loader
@login_manager.user_loader
def load_user(user_id):
return Person.query.get(int(user_id))
А вот вид:
# app/auth/views.py
from flask import flash, redirect, render_template, url_for
from flask_login import login_required, login_user, logout_user
from . import auth
from .forms import LoginForm, RegistrationForm
from .. import db
from ..models import Person, Facility
@auth.route('/register', methods=['GET', 'POST'])
def register():
"""
Handle requests to the /register route
Add a person to the database through the registration form
"""
form = RegistrationForm()
form.facility_id.choices = [(f.id, f.name) for f in Facility.query.order_by('name')]
if form.validate_on_submit():
person = Person(facility=form.facility_id.data,
email=form.email.data,
username=form.username.data,
first_name=form.first_name.data,
last_name=form.last_name.data,
password=form.password.data)
# add person to the database
db.session.add(person)
db.session.commit()
flash('You have successfully registered! You may now login.')
# redirect to the login page
return redirect(url_for('auth.login'))
# load registration template
return render_template('auth/register.html', form=form, title='Register')