Flask + SqlAlchemy извлекает объект класса из другого атрибута класса - PullRequest
0 голосов
/ 11 ноября 2019

Я создаю приложение flask, используя SqlAlchemy, и я хотел бы получить author из объекта Notification из самого объекта Notification, а не анализировать все User сtemplate для захвата данных author.

Вот мои модели:

В app/models.py

from app import db
from datetime import datetime

#...

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(250), unique=True, index=True)
    password_hash = db.Column(db.Binary(72))
    notifications = db.relationship('Notification', backref='recipient', lazy='dynamic')

#...

class Notification(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    body = db.Column(db.String(140))
    timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    pending = db.Column(db.Boolean, default=True)
    author = ?

На моих маршрутах явсегда анализируйте notifications из current_user в качестве аргумента, поскольку я использую его в моей templates/base.html навигационной панели (и во всех моих представлениях {% extends "base.html %})

Вот один пример маршрута:

In app/routes.py

@app.route('/')
@app.route('/index')
def index():
        notifications = User.query.filter_by(id=current_user.id).first().notifications.all()
    else:
        notifications = []
    return(render_template('index.html', title=_('Home'), notifications=notifications))

Но я не хочу анализировать всех пользователей из базы данных, чтобы получать информацию об авторе из каждого уведомления, вместо этого я хочу получить доступ к объекту User автора вмой шаблон из самого объекта уведомления, например, так:

В app/templates/index.html

{{ notification.author.username }}

И это должно вернуть его имя пользователя.

Чтокакие отношения или хитрость я должен был бы сделать, чтобы добиться этого?

PS: Это было бы каким-либо образом небезопасным, поскольку пользователь (уведомление recipient) мог быкак использовать его для доступа к нежелательным данным из author, например, nothification.author.password_hash? Если да, то как лучше всего реализовать то, что я пытаюсь сделать?

Редактировать

Чтобы прояснить вопрос, как указал @noslenkwah, я хотел бы прояснить это. что author является User, и я надеюсь, что я могу создать Notification объект, назначив вещи следующим образом:

notification = Notification(body='example', user_id=some_recipient_id, author = User.query.filter_by(username=some_author_username).first())

Тогда я смогу db.session.add(notification) инаконец, db.session.commit() it.

some_recipient_id - это id из User, являющегося уникальным идентификатором, а его primary key и some_author_username также являются уникальным идентификатором. Я мог бы также filter_by(id=some_author_id), тогда как some_author_id будет User primary key, а также unique идентификатором.

1 Ответ

0 голосов
/ 14 ноября 2019

Благодаря @noslenkwah, указывающему на этот вопрос, я смог найти способ выполнить то, что пытался.

Вот как:

in models.py

from app import db
from sqlalchemy.orm import backref
from datetime import datetime

#...

class Notification(db.Model):
    __tablename__ = 'notification'

    id = db.Column(db.Integer, primary_key=True)
    body = db.Column(db.String(140))
    timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
    pending = db.Column(db.Boolean, default=True)

    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    author_id = db.Column(db.Integer, db.ForeignKey('user.id'))

    recipient = db.relationship(User, foreign_keys=[user_id],
                                      backref=backref('notifications', order_by=id, lazy='dynamic'))
    author = db.relationship(User, foreign_keys=[author_id])
...