Запись в три базы данных с одной отправки с колбой - PullRequest
0 голосов
/ 25 июня 2018


Я начал играть с флягой неделю назад и уже столкнулся с небольшой проблемой, и я не знаю, может ли фляга воспринимать это как основу или мне нужно решить ее «старым» способом.
Вот ситуация.

У меня есть три дБ Платтен , Метка и Исполнитель .Для заполнения таблиц у меня есть одна форма, в которую я могу ввести информацию для LP (Artist, Label, Date Release и т. Д.).
Отправляя форму, я хочу проверить db Artist, если Artist уже существуетили нет.Если хотите, возьмите идентификатор и сохраните его для LP.Если артиста нет в БД, напишите его и сохраните новый идентификатор.
То же самое для метки.

Это мой файл models.py: из импорта приложения db из werkzeug.security import generate_password_hash, check_password_hash from flask_login import UserMixin из приложения import login_manager

class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), index=True, unique=True)
    email = db.Column(db.String(120), index=True, unique=True)
    password_hash = db.Column(db.String(128))

    def __repr__(self):
        return '<User {}>'.format(self.username)

    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.password_hash, password)


class Label(db.Model):
    __tablename__ = 'labels'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)

    def __repr__(self):
        return '<Label {}>'.format(self.name)


class Artist(db.Model):
    __tablename__ = 'artists'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)

    def __repr__(self):
        return '<Artist {}>'.format(self.name)


class Platte(db.Model):
    __tablename__ = 'platten'

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(64), index=True)
    label_id = db.Column(db.Integer, db.ForeignKey('labels.id'))
    label = db.relationship('Label', backref=db.backref('platten'), lazy=True)
    release_date = db.Column(db.Date())
    artist_id = db.Column(db.Integer, db.ForeignKey('artists.id'))
    artist = db.relationship('Artist', backref=db.backref('platten'), lazy=True)

    def __repr__(self):
        return '<Platte {}>'.format(self.title)

Это мой файл rout.py:

from flask import render_template, flash, redirect, url_for, request
from app import app, db
from app.forms import LoginForm, RegistrationForm, PlattenForm
from flask_login import current_user, login_user, logout_user, login_required
from app.models import User, Platte, Artist, Label
from werkzeug.urls import url_parse

@app.route('/')
@app.route('/index')
@login_required
def index():
    platten = Platte.query.all()

    return render_template('index.html', title='Home', platten=platten)

@app.route('/add', methods=['GET', 'POST'])
@login_required
def platten_add():
    form = PlattenForm()
    if form.validate_on_submit():
        artist = Artist(name=form.artist.data)
        label = Label(name=form.label.data)

        # artist_check = Artist.query.filter_by(name=artist).first()
        # if artist_check is None:
        #     db.session.add(artist)
        #     db.session.commit()
        #     artist_id = Artist.query.filter_by(name=artist).first()
        #     artist_id = artist_id.id
        # else:
        #     artist_id = artist_check.id
        platte = Platte(title=form.title.data, label_id=label.id, label=label, artist_id=artist.id, artist=artist, release_date=form.release_date.data)
        db.session.add(platte)
        db.session.commit()
        flash('Platte ' + platte.title + ', hinzugefügt!')
        return redirect(url_for('platten_add'))
    return render_template('platten_add.html', title='Add', form=form)

Закомментированная часть в файле rout.py будет «старомодным» способом, как я буду делать вставку в БД.

Есть ли способ сделать это в колбе или я должен сделать это вручную, как в разделе с комментариями кода?Спасибо за помощь.

1 Ответ

0 голосов
/ 25 июня 2018

Нет, это невозможно сделать в flask_sqlalchemy.Чтобы получить доступ к идентификатору объекта, например artist.id, он должен быть уже сохранен.

Кроме того, для того, чтобы это было один ко многим, это предпочтительный способ сделать это:

class Label(db.Model):
    __tablename__ = 'labels'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    platten = db.relationship('Platte', backref='labels')

    def __repr__(self):
        return '<Label {}>'.format(self.name)


class Artist(db.Model):
    __tablename__ = 'artists'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    platten = db.relationship('Platte', backref='artists')

    def __repr__(self):
        return '<Artist {}>'.format(self.name)


class Platte(db.Model):
    __tablename__ = 'platten'

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(64), index=True)
    label_id = db.Column(db.Integer, db.ForeignKey('labels.id'))
    release_date = db.Column(db.Date())
    artist_id = db.Column(db.Integer, db.ForeignKey('artists.id'))

    def __repr__(self):
        return '<Platte {}>'.format(self.title)

Что, в свою очередь, означает, что вы теперь можете делать:

@app.route('/add', methods=['GET', 'POST'])
@login_required
def platten_add():
    form = PlattenForm()
    if form.validate_on_submit():

        artist = Artist.query.filter_by(name=form.artist.data).first()
        if not artist:
            artist = Artist(name=form.artist.data)
            db.session.add(artist)
        label = Label.query.filter_by(name=form.label.data).first()
        if not label:
            label = Label(name=form.label.data)
            db.session.add(label)

        platte = Platte(title=form.title.data, release_date=form.release_date.data)

        label.platten.append(platte)
        artist.platten.append(platte)

        db.session.commit()
        flash('Platte ' + platte.title + ', hinzugefügt!')
        return redirect(url_for('platten_add'))
    return render_template('platten_add.html', title='Add', form=form)
...