проблема для обновления логического значения - PullRequest
0 голосов
/ 05 мая 2019

В моем приложении для колб я создаю две модели, Car и Place. Проблема заключается в том, что модель Place, содержащая логическое значение, не обновляется одновременно с добавлением нового автомобиля.

Я уже создал две модели (Car и Place).

Мои модели (модели автомобилей и автомобилей)

class Car(db.Model):

    id = db.Column(db.Integer, primary_key=True)
    mark = db.Column(db.String(25), unique=False, nullable=False)
    model = db.Column(db.String(25), unique=False, nullable=False)
    color = db.Column(db.String(16), unique=False, nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
class Place(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    numb = db.Column(db.Integer, unique=True, nullable=False)
    is_available = db.Column(db.Boolean())

Места маршрутов

def make_a_place_unavailable(the_place):
    place_concerned = Place.query.filter_by(numb=the_place).first()
    place_concerned.is_available = False

Автомобильные маршруты

from project.cars.forms import AdmitCarForm
from project.models import Car, Place
from project import db
from project.places.routes import make_a_place_unavailable

@cars.route('/c_car', methods=['GET', 'POST'])
@login_required
def c_car():
    form = AdmitCarForm()
    available_places = []
    places = Place.query.filter_by(is_available=True)

    # fill out available places list
    for available_place in places:
        available_places.append(available_place)

    # redirect user to home page if all places are unavailable
    if len(available_places) == 0 :
        flash('All places are unavailable. Remove a car or wait')
        return redirect(url_for('main.home'))
    else:
        # choose a random available place to park car
        choosen_place = randint(1, len(available_places))

        if form.validate_on_submit():
            # add car to database
            car = Car(
                mark = form.mark.data,
                model = form.model.data,
                color = form.color.data,
                user_id = current_user.id
            )
            db.session.add(car)

            # make place unavailable
            make_a_place_unavailable(choosen_place)

            # add car to database
            db.session.commit()

            flash(f'Car on parking!')
            return redirect(url_for('main.home'))

    return render_template('c_car.html', form=form, choosen_place=choosen_place)

В результате в базу данных при добавлении нового автомобиля по форме в шаблон добавляется только автомобиль, а выбранное место не обновляется в базе данных. То, что я хочу, это когда я добавляю новую машину в форму, место, которое указано, будет обновлено.

1 Ответ

0 голосов
/ 06 мая 2019

Я не отвечаю прямо на ваш вопрос, но я хотел бы предложить, чтобы вам не требовалось поле is_available.

Используя свойства relationship() в ваших моделях, вы можете легко определить, доступен ли Place или нет, но также вы можете увидеть, какой Car находится в Place, и легко найти, какой Place a Car находится в.

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)


class Car(db.Model):

    id = db.Column(db.Integer, primary_key=True)
    mark = db.Column(db.String(25), unique=False, nullable=False)
    model = db.Column(db.String(25), unique=False, nullable=False)
    color = db.Column(db.String(16), unique=False, nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

    # new relationship fields
    place = db.relationship('Place', back_populates='car')
    user = db.relationship('User')


class Place(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    # As numb is not nullable, and must be unique, you could consider
    # removing the `id` column above and making `numb` primary key.
    numb = db.Column(db.Integer, unique=True, nullable=False)

    # new column
    car_id = db.Column(db.Integer, db.ForeignKey('car.id'))

    # new relationship
    car = db.relationship('Car', back_populates='place', uselist=False)

Я аннотировал модели, в которых я внес изменения, также я удалил Place.is_available.

Здесь я создаю несколько мест и пользователя для тестирования:

# add some places
db.session.add_all([
    Place(id=1, numb=1),
    Place(id=2, numb=2),
    Place(id=3, numb=3)
])
# create a user
me = User()
db.session.add(me)
db.session.commit()

Теперь создайте автомобиль и поместите его в Место:

#  instead of query by `is_available`, query for spaces without cars
places = Place.query.filter_by(car=None).all()
print(places)  # [<Place 1>, <Place 2>, <Place 3>]

# create a Car
car = Car(mark='mark', model='model', color='green', user=me)

# put car in a random place, random.choice will select a space
# from the list for you
car.place = random.choice(places)
db.session.commit()

# then we can easily find out if a place is available:
for place in places:
    print(f'{place} is available?', not place.car)
# <Place 1> is available? False
# <Place 2> is available? True
# <Place 3> is available? True

# given a Place, we can easily see the exact car parked there:
for place in places:
    print(f'{place.car} in {place}')
# <Car 1> in <Place 1>
# None in <Place 2>
# None in <Place 3>

# and given a car we can see exactly where it's parked
print(car.place)
# <Place 1>
...