【问题标题】:Flask: How to use an value taken from a database as an input for a functionFlask:如何使用从数据库中获取的值作为函数的输入
【发布时间】:2020-03-30 10:22:52
【问题描述】:

我希望能够生成一个 for 循环,该循环显示用户当前可用的所有处方,如果当前用户是药剂师,则在该行旁边有一个类似提交的按钮,当它减少该处方的当前计数时被点击。目前正在尝试减少 current_count 当我知道处方ID = current_user.prescription_id 时不正确,特别是对于有多个处方的情况。现在可以正常显示所有内容,但会抛出错误,提示“用户”对象没有属性“处方 ID”。可以帮忙做。代码如下。

main.py
@app.route('/patient_advice/<username>',methods=['GET', 'POST'])
@login_required
def advice(username):
    form = FillForm(request.form)
    user = User.query.filter_by(username=username).first_or_404()
    prescription = Prescriptions.query.filter_by(username=username)
    if request.method == 'POST' and form.validate():
        prescriptions = Prescriptions.query.filter_by(prescription_id=current_user.prescription_id).first()
        prescriptions.prescription_current_count = prescriptions.prescription_current_count - 1
        prescriptions.fill_date = datetime.utcnow()
        db.session.commit()
        flash('Prescription removed')
        flash(prescriptions.prescription_current_count)
    return render_template('patient_advice.html', title='Patient Advice', user=user, prescription=prescription, form=form)

.html section
<table id="patient-advice">
{% for medicine in prescription %}
    {% if medicine.prescription_name and medicine.prescription_current_count > 0 %}
     <tr>
        <td id='prescriptionRow'>
            {{ medicine.prescription_current_count }}
            {% if (medicine.prescription_current_count < 2) %}
                round
            {% else %}
                rounds
            {% endif %}
        of {{ medicine.prescription_name }} <b>issued on:</b> {{ medicine.issue_date }}<br>
        {% if medicine.fill_date %}
            Last filled on: {{ medicine.fill_date }}
        {% endif %}

        {% if (current_user.user_type=="pharmacist") %}
            <form method=post>
                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
                <p>
                    {{ form.prescriptionId(cols=50, rows=4) }}<br>
                </p>
                <p>{{ form.submit() }}</p>
            </form>
        {% endif %}
    </td>
    <td>
        {% if medicine.prescription_name and medicine.prescription_current_count > 0 %} {{ medicine.issued_doctor }}{% endif %}
    </td>
</tr>
{% endif %}
{% endfor %}
</table>

forms.py:
class FillForm(Form):
    submit = SubmitField('Fill Prescription')

models.py:
class Prescriptions(UserMixin, db.Model):

    __tablename__ = "prescriptions"

    prescription_id = db.Column(db.Integer, primary_key=True)
    prescription_name = db.Column(db.String(200))
    prescription_count = db.Column(db.Integer)
    prescription_current_count = db.Column(db.Integer)
    issued_doctor = db.Column(db.String(200))
    issue_date = db.Column(db.DateTime, default=datetime.utcnow)
    fill_date = db.Column(db.DateTime, default=datetime.utcnow)
    username = db.Column(db.String(128))

    users = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
    UserDetails = db.relationship('User', foreign_keys=users)

class User(UserMixin, db.Model):
    __tablename__ = "users"
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(128), unique=True)
    password_hash = db.Column(db.String(128))
    email = db.Column(db.String(120), unique=True, index=True)
    user_type = db.Column(db.String(128))
    advice = db.Column(db.String(1000))
    last_seen = db.Column(db.DateTime, default=datetime.utcnow)

通过将来自数据库的输入作为表单中隐藏字段的值来解决,更改了以下部分: main.py:

if request.method == 'POST' and form.validate():
    prescriptions = Prescriptions.query.filter_by(prescription_id=request.form.get("prescid"))
    for medicine in prescriptions:
        medicine.prescription_current_count = medicine.prescription_current_count - 1
        medicine.fill_date = datetime.utcnow()
        db.session.commit()
        flash("Prescription Filled")

表单相关html变化:

<form method=post>
    <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
    <input class="form-control" name="prescid" type="hidden" value={{ medicine.prescription_id }}>
    <p>{{ form.submit() }}</p>
</form>

【问题讨论】:

    标签: html flask sqlalchemy jinja2


    【解决方案1】:

    根据我的经验,您所描述的错误通常是由于您的数据库配置问题而引发的,所以也许可以提供一些有关您的数据库结构的信息?并且可能会显示更多代码以提供更多上下文。

    我不禁注意到您 HTML 中的这一行

    {% if (current_user.user_type=="pharmacist") %}
    

    并看到这个“current_user”没有在任何地方定义,至少没有在你显示的代码中。在您的 render_template 中,您传递了一个用户,但该变量的名称只是“user”而不是“current_user”。

    【讨论】:

    • 嘿,干杯,我添加了上面的数据库。 current_user 是从 flask_login 导入的,下面是解释它的指南链接。 blog.miguelgrinberg.com/post/…
    • @Marone289 它可能看起来 current_user 正在从 User 数据库中提取数据,如果是这种情况,那么这可能就是您收到错误的原因,因为该数据库不包含prescription_id 的列。一个可能的解决方法是按照prescription_id=Prescriptions.prescription_id where Prescriptions.username == current_user.username 的方式进行比较我没有使用 SQLalchemy 的经​​验(这看起来像)所以这可能是不可能的,但这是我最好的猜测。
    • 感谢您的输入,在使用上面底部添加的代码之前,我尝试了类似的方法。使用这种方式,“填写处方”按钮只会减少它在数据库中找到的第一个处方 ID 的计数,并减少当前的计数,因此不适用于多个处方。
    • @Marone289 如果prescriptions.prescription_current_count 包含多个值,您可能想要创建一个 for 循环,例如:if request.method == 'POST' and form.validate(): prescriptions = Prescriptions.query.filter_by(username=username).first() for i in prescriptions i.prescription_current_count = i.prescription_current_count - 1 i.fill_date = datetime.utcnow() db.session.commit() flash('Prescription removed') 但我对 SQLAlchemy 不了解,所以我不确定这是否适用于此案例。
    • 这个循环似乎减少了与用户名相关的每个处方的当前计数,而不仅仅是提交按钮旁边的处方
    猜你喜欢
    • 2016-05-29
    • 1970-01-01
    • 2021-09-16
    • 2019-09-03
    • 2015-10-19
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多