简体   繁体   中英

How to add data into two tables with one to many relationship using flask-sqlalchemy and flask

guys, im very new using Flask and flask-sqlalchemy. I have two tables one is for store clients data, and the other one is to store quotation values. They have a relationship one to many, One client could have many quotations, but a quotation only belong to one client.

class Clientes(db.Model):
  
    __tablename__ = "clientes"


    id = db.Column(db.Integer, primary_key=True)
    servicios = db.Column(db.String(120), nullable=False)
    nombres = db.Column(db.String(80), nullable=False)
    apellidos = db.Column(db.String(80), nullable=False)
    correo = db.Column(db.String(120), nullable=False)
    empresa = db.Column(db.String(120), nullable=False)
    celular = db.Column(db.String(50), nullable=False)
    mensaje = db.Column(db.String(500), nullable=False)
    checkbox = db.Column(db.Boolean, nullable=False)
    cotizaciones = db.relationship('Cotizacion', cascade='all, delete', backref='clientes_cotizan', lazy=True)

    def __init__(self, servicios, nombres, apellidos, correo, empresa, celular, mensaje, checkbox):
        self.servicios = servicios
        self.nombres = nombres
        self.apellidos = apellidos
        self.correo = correo
        self.empresa = empresa
        self.celular = celular
        self.mensaje = mensaje
        self.checkbox = checkbox
        
    

    def __repr__(self):
        return '<Clientes %r>' % self.id



class Cotizacion(db.Model):
    __tablename__ = "cotizacion"

    id = db.Column(db.Integer, primary_key=True)
    numero_personas = db.Column(db.Integer, nullable=False)
    valor_personas = db.Column(db.Integer, nullable=False)
    numero_horas = db.Column(db.Integer, nullable=False)
    valor_hora = db.Column(db.Integer, nullable=False)
    descuento = db.Column(db.Integer, nullable=False)

    # LLAVE FORANEA
    cliente_id = db.Column(db.Integer, db.ForeignKey("clientes.id"), nullable=False)
   

    def __init__(self, numero_personas, valor_personas, numero_horas, valor_hora, descuento, cliente_id):
        self.numero_personas = numero_personas
        self.valor_personas = valor_personas
        self.numero_horas = numero_horas
        self.valor_hora = valor_hora
        self.descuento = descuento
        self.cliente_id = cliente_id
       

    def __repr__(self):
        return '<Cotizacion %r>' % self.id


This is my view

@app.route('/cotizaciones/crear/<int:id>', methods=("GET", "POST"))
@login_required
def crearcotizacion(id):
    client = (db.session.query(Clientes).filter_by(id=id).one())
    
    form = creacion_Cotizacion(request.form)

    clientes_cotizan = db.session.query(Clientes, Cotizacion.id).join(Cotizacion).filter(Clientes.id).first()

    cotizan = Cotizacion(
         numero_personas=form.numero_personas.data,
         valor_personas=form.valor_personas.data,
         numero_horas=form.numero_horas.data,
         valor_hora=form.valor_hora.data,
         descuento=form.descuento.data,
         cliente_id = clientes_cotizan

     )

    if current_user.role == True:
        
        if request.method == 'POST':
           
            try:
                db.session.add(cotizan)
                db.session.commit()
                flash('La cotización ha sido creado exitosamente', 'success')
                return render_template('crearcotizacion.html', client=client, form=form, id=id)
            except InvalidRequestError:
                db.session.rollback()
                flash(f"Something went wrong!", "danger")

            except IntegrityError:
                db.session.rollback()
                flash(f"La Cotizacion ya existe!.", "warning")
            except DataError:
                db.session.rollback()
                flash(f"Entrada Inválida", "warning")
            except InterfaceError:
                db.session.rollback()
                flash(f"Error al conectarse a la base de datos", "danger")
            except DatabaseError:
                db.session.rollback()
                flash(f"Error de conexión con la base de datos", "danger")
            except BuildError:
                db.session.rollback()
                flash(f"Un error ha ocurrido!", "danger")
            else:
                abort(401)

    return render_template('crearcotizacion.html', nombres=current_user.nombres, correo=current_user.correo, role=current_user.role, id=id, client=client, form=form)

When i enter to /cotizaciones/crear/int:id and select one customer, the second page where i add the quotations value, when create quotation button is clicked an error is raised and i dont know how resolve this: Quotation already exists. Also, I dont know how foreign key is populated. Thanks for all your help.

When you create your Cotizacion object, you are trying to populate the foreignkey column, cliente_id . Instead, you should populate its backref of clientes_cotizan . It should be like this, where clientes_cotizan is populated by a client object you have queried with your selected id.

client = (db.session.query(Clientes).filter_by(id=id).one())

cotizan = Cotizacion(
     numero_personas=form.numero_personas.data,
     ...,
     clientes_cotizan = client

 )

Note you will also need to edit your __init__ function to accept this clientes_cotizan instead of the cliente_id . It should be like this:

def __init__(self, numero_personas, ..., clientes_cotizan):
    self.numero_personas = numero_personas
    ...
    self.clientes_cotizan = clientes_cotizan

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM