Как сохранить идентификатор выбранного выпадающего значения в SQLAlchemy

0

У меня есть две модели классов, которые переводят на две таблицы базы данных MySQL. Один из них - employees а другой - projects. У них есть отношения "один ко многим", т.е. Один проект может иметь несколько сотрудников. В моей веб-форме при регистрации сотрудника у меня есть выпадающий список, содержащий проекты. Таблица employees, имеют ключевой иностранный REFERENCING projects стола и, таким образом, employees таблица имеет Integer столбец (emp_project_id) в качестве внешнего ключа из projects таблицы. Как сохранить идентификатор, когда проект выбран из выпадающего списка?

class Employee(UserMixin, db.Model):
    """
    Create Employee table
    """

   # Ensures table will be named in plural and not in singular 
   # as in the name of the model
   __tablename__ = 'employees'

   id = db.Column(db.Integer, primary_key=True)
   emp_number = db.Column(db.String(10), index=True, unique=True, nullable=False)
   username = db.Column(db.String(60), index=True, unique=True)
   email = db.Column(db.String(60), index=True, unique=True, nullable=False)
   emp_name = db.Column(db.String(100), index=True)
   password_hash = db.Column(db.String(128))
   emp_project_id = db.Column(db.Integer, db.ForeignKey('projects.id'), nullable=False)

И вот таблица projects

class Project(db.Model):
    """
    Create a Project table
    """

    __tablename__ = 'projects'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(60), unique=True, nullable=False)
    description = db.Column(db.String(200), nullable=False)

    pro_subprojects = db.relationship('Subproject', backref='sp_project', 
                                lazy='dynamic')
    pro_employees = db.relationship('Employee', backref='emp_project', 
                                lazy='dynamic')

Пожалуйста, отсылайте меня к ресурсу, который я могу пройти, если это возможно, так как я не нашел решение в своей документации.

Вот класс из forms.py который создает форму

class RegistrationForm(FlaskForm):
    """
    Form for users to create new account
    """
    project = QuerySelectField(query_factory=lambda: Project.query.all(), 
                                                    get_label="name")
    subproject = QuerySelectField(query_factory=lambda: Subproject.query.all(), 
                                                    get_label="name")
    emp_number = StringField('Employee Number', validators=[DataRequired()])
    email = StringField('Email', validators=[DataRequired(), Email()])
    username = StringField('Username', validators=[DataRequired()])
    emp_name = StringField('Full Name', validators=[DataRequired()])
    password = PasswordField('Password', validators=[
                                            DataRequired(), 
                                            EqualTo('confirm_password')
                                        ])
    confirm_password = PasswordField('Confirm Password')
    submit = SubmitField('Register')

Вот что я добавил на мои views.py:

@auth.route('/register', methods=['GET', 'POST'])
def register():
    """
    Handle requests to the /register route
    Add an employee to the database through the registration form
    """
    form = RegistrationForm()
    if form.validate_on_submit():
        employee = Employee(project=form.project.data,
                            subproject=form.subproject.data,
                            emp_number=form.emp_number.data,
                            email=form.email.data,
                            username=form.username.data,
                            emp_name=form.emp_name.data,
                            password=form.password.data)

        # add employee to the database
        db.session.add(employee)
        db.session.commit()
        flash('You have registered successfully. You can now log in.')

Однако, когда я пытаюсь зарегистрировать сотрудника, я получаю сообщение об ошибке типа TypeError: 'project' is an invalid keyword argument for Employee. Просьба помочь

Теги:
flask
flask-sqlalchemy

1 ответ

0

вот что сказано в документации для QuerySelectedField:

Свойство данных фактически будет хранить/хранить экземпляр модели ORM, а не идентификатор.

Теперь я понимаю, что ваша проблема изменила ваше мнение следующим образом:

@auth.route('/register', methods=['GET', 'POST'])
def register():
    """
    Handle requests to the /register route
    Add an employee to the database through the registration form
    """
    form = RegistrationForm()
    if form.validate_on_submit():
        employee = Employee(
                            emp_number=form.emp_number.data,
                            email=form.email.data,
                            username=form.username.data,
                            emp_name=form.emp_name.data,
                            password=form.password.data)
        project=form.project.data  #an instance of Project Class
        subproject=form.subproject.data #an instance of SubProject Class
        project.pro_subproject.append(subproject) 
        project.pro_employee.append(employee)
        # add employee to the database
        db.session.add(employee)
        db.session.add(subproject)
        db.session.add(project)
        db.session.commit()
        flash('You have registered successfully. You can now log in.')

Вот объяснение этого:

От одного до многих отношений помещает внешний ключ в дочернюю таблицу, ссылаясь на родителя. Затем отношение отношения() указывается в родительском объекте, как ссылка на набор элементов, представленных дочерним элементом:

Это означает, что в вашей таблице проектов поле pro_employees и pro_subproject - это списки сотрудников (n) и sub_project (n).

  • 0
    Я думаю, что мы почти на месте, @EspoirMurhabazi. Теперь я получаю сообщение об ошибке, что emp_project_id не может быть null . Когда данные отправляются в базу данных, поле emp_project_id остается пустым, но это внешний ключ, поэтому not null
  • 0
    Попробуйте напечатать проект, чтобы проверить, не является ли он пустым, и сначала сохраните проект, поэтому поместите db.session.add (project) перед сотрудниками.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню