【问题标题】:Calling one function from another function or route using flask, python and sqlite使用flask、python和sqlite从另一个函数或路由调用一个函数
【发布时间】:2020-12-19 00:27:57
【问题描述】:

我正在使用烧瓶、python 和 sqlite 进行 cs50 最终项目。我的问题是了解如何从同一路由调用 2 个函数,或从另一个调用一个。或者坦率地说,只是如何实现 1 - 根据日期和月份分配 astro_sign 以及 2 - 将 astro_sign 更新为 3 的 sqlite db (signs.db) 的目标 - 显示在 index.html 上。我正在尝试使用此示例代码https://www.geeksforgeeks.org/program-display-astrological-sign-zodiac-sign-given-date-birth/,但无法使 zodiac 功能正常工作。我已经尝试在没有注册路由中的 if/elif 语句的功能的情况下执行此操作,但我得到“NameError:名称'astro_sign'未定义”或“UnboundLocalError:分配前引用的局部变量'astro_sign'”取决于尝试.我在这里找到了一个讨论局部变量与全局变量的示例,并建议添加“astro ='',但随后我的signs.db 被更新为一个空字符串,就好像函数永远不会运行一样。我还尝试使用@/zodiac 路由重定向,但无法正确处理。我找到了这个:How can we call one route from another route with parameters using python flask.? 但不明白。下面的当前尝试,我尝试将函数放入 helper.py,但这完全杀死了应用程序。我不能弄清楚如何返回函数,全局命名变量,我非常沮丧。我从 html 文档中提取月份和日期作为整数:

register.html:

    <form action="/register" method="post">
        <div class="form-group">
            <input autocomplete="off" autofocus class="form-control" name="username" placeholder="Username" type="text">
        </div>
        <div class="form-group">
        <select class="form-control" name="month">
                <option value= 1>January</option>
                <option value= 2>February</option>
                <option value= 3>March</option>
                <option value= 4>April</option>
                <option value= 5>May</option>
                <option value= 6>June</option>
                <option value= 7>July</option>
                <option value= 8>August</option>
                <option value= 9>September</option>
                <option value= 10>October</option>
                <option value= 11>November</option>
                <option value= 12>December</option>
        </select>
        </div>
        <div class="form-group">
            <input class="form-control" name="day" placeholder="Day of Birth" type="number">
        </div>
        <div class="form-group">
            <input class="form-control" name="password" placeholder="Password" type="password">
        </div>
        <div class="form-group">
            <input class="form-control" name="confirmation" placeholder="Confirm Password" type="password">
        </div>
        <button class="btn btn-primary" type="submit">Register</button>
    </form>

然后在 application.py 中,一切正常,直到我尝试确定星座并发送到 db。

@app.route("/register", methods=["GET", "POST"])
def register():
    """Register user"""
        # if user reached route via POST
    if request.method == "POST":
        username = request.form.get("username")
        month = request.form.get("month")
        day = request.form.get("day")
        password = request.form.get("password")
        confirmation = request.form.get("confirmation")
        astro_sign = ''

        #there are other checks in here that I removed to make this shorter
        #insert new users
        result = db.execute("INSERT INTO users (username, hash, month, day) VALUES (:username, :password, :month, :day)", username=username, password=hash, month=month, day=day)

        # ensure username is unique
        if not result:
            return apology("username is already registered")

        # remember which user has logged in
        session["user_id"] = result

        #try to call the function from helper.py and update astro_sign 
        if astro_sign is '':
            zodiac_sign(day, month)
            return astro_sign

        #insert into signs.db that accepts astro_sign as text
        db.execute("INSERT INTO signs (user_id, astro_sign) VALUES (:user_id, :astro_sign)",
        user_id=session["user_id"], astro_sign=astro_sign)

        #redirect to login
        return render_template("login.html")


    # User reached route via GET (as by clicking a link or via redirect)
    else:
        return render_template("register.html")

在 helper.py 中,我最近的尝试现在导致应用在注册后完全崩溃。

def zodiac_sign(day, month):
astro_sign = ''
# checks month and date within the valid range
# of a specified zodiac
if month is 12:
    astro_sign = 'Sagittarius' if (day < 22) else 'capricorn'

elif month is 1:
    astro_sign = 'Capricorn' if (day < 20) else 'aquarius'

elif month is 2:
    astro_sign = 'Aquarius' if (day < 19) else 'pisces'

elif month is 3:
    astro_sign = 'Pisces' if (day < 21) else 'aries'

#you get the point

elif month is 11:
    astro_sign = 'scorpio' if (day < 22) else 'sagittarius'

return astro_sign

Any help would be so appreciated!

【问题讨论】:

  • 我认为这个问题需要澄清一下:当您说您当前的代码“完全杀死应用程序”时,您看到的实际错误是什么?这真的可以帮助我们了解出了什么问题。此外,缩进看起来有点不对劲:我假设 zodiac_sign 函数的内容是缩进的,但如果不是,那肯定会导致问题。您是从application.py 中的helper 模块导入zodiac_sign 函数吗?
  • 对不起。我很沮丧。在尝试注册新用户后,我当前使用 helper.py 中的函数的代码会导致屏幕完全变白(无法恢复)。在任何情况下,我都无法让 astro_sign 在signs.db 中更新。我确实忘了说我正在将 zodiac 函数导入到 application.py 中。我是。谢谢你至少回复。我是新来的堆栈和尝试。
  • 我正在使用 cs50 IDE。我没有收到错误,但我想我试图从 helpers.py 中的 zodiac 函数重定向到路由索引。我尝试了很多东西,我可能复制了错误的版本。对不起。
  • 如果是这样的话,在我的 helpers.py zodiac 函数的底部有返回重定向(“/”)。不管怎样,我需要帮助。我可以提供您需要的任何代码来查看正在导入的内容。我希望我不是虚拟学生,因为我想真正理解这一点。无论哪种方式,在 application.py 的顶部:“从助手导入道歉,login_required,zodiac_sign”。当我运行“烧瓶运行”时,注册后出现白屏。我一直认为这应该在注册路线中轻松完成,但我不知道如何。我对任何链接或更好的学习策略感兴趣。

标签: python flask


【解决方案1】:

很难给出完整的答案,因为代码目前有些不完整,但我认为您在注册时看到空白屏幕的原因是由于您的 register 函数中的 if 语句:

if astro_sign is '':
    zodiac_sign(day, month)
    return astro_sign

让我们考虑一下代码中此时发生了什么:在register 函数的顶部,我们有astro_sign = '' 行,在我们到达这一点之前我们不会改变这个astro_sign 变量,所以这个 if 条件 (astro_sign is '') 将始终评估为 true,因此将始终调用其中的代码。

接下来,我们运行zodiac_sign 函数,这很有意义,因为我们需要找到占星符号以将其包含在输出中。该函数returns 是一个字符串。但是,您不会将字符串的结果存储在您的register 函数中的astro_sign 变量中。我知道zodiac_sign函数调用了它构造的字符串变量astro_sign,但是由于这是两个不同的函数,这不会影响register函数中的astro_sign,它会保留为'' (一个空字符串)。

那么,我们return astro_sign。但这意味着register 函数的其余部分将无法运行!我们返回空字符串 astro 符号,因此 Flask 会向浏览器发送一个空页面作为结果。我们真正想要做的是更改register 函数中的astro_sign 变量,以便我们稍后可以将其插入数据库。所以,也许你应该把 if 语句改成这样:

if astro_sign is '':
    astro_sign = zodiac_sign(day, month)

现在,函数应该在 if 语句运行后继续运行,我们最终将返回 login.html 模板。

编辑:另外,您可能需要更新 zodiac_sign 函数,使其正确缩进,如下所示:

def zodiac_sign(day, month):
    astro_sign = ''
    # checks month and date within the valid range
    # of a specified zodiac
    if month is 12:
        astro_sign = 'Sagittarius' if (day < 22) else 'capricorn'

    elif month is 1:
        astro_sign = 'Capricorn' if (day < 20) else 'aquarius'

    elif month is 2:
        astro_sign = 'Aquarius' if (day < 19) else 'pisces'

    elif month is 3:
        astro_sign = 'Pisces' if (day < 21) else 'aries'

    #you get the point

    elif month is 11:
        astro_sign = 'scorpio' if (day < 22) else 'sagittarius'

    return astro_sign

【讨论】:

  • 我试过如果 astro_sign 是 ' ': astro_sign = zodiac_sign(day, month)。首先它在IDE中给了我一个错误“分配函数调用的结果,该函数没有返回”。我查了一下,发现 stackoverflow.com/questions/54548783/…> 说这只是一个 pylint 错误。所以我还是跑了。屏幕上出现 500 错误,这在控制台中。文件“/home/ubuntu/finalproject/application.py”,第 186 行返回 render_template("login.html") ^ SyntaxError: invalid syntax
  • 我的问题中应该包含哪些其他代码可以帮助您查看我的错误?有没有更简单的方法来完成这项工作?
  • 我有一个拼写错误,解决了语法错误。但是,现在我得到“分配函数调用的结果,其中函数没有返回”,ValueError:NOT NULL 约束失败:终端中的signs.astro_sign 和页面上的500 错误。有什么办法吗?
  • 我对所有的 cmets 感到抱歉,但我忘了补充一点,控制台告诉我 DEBUG: INSERT INTO 标志 (user_id, astro_sign) VALUES (48, NULL)。我尝试添加“return astro_sign and get TypeError: The view function did not return a valid response. 该函数返回 None 或没有返回语句结束。为什么返回 null?
  • @Kelly5978 我认为这只是您第一篇文章中的格式问题,但您可能还需要修复zodiac_sign 函数的缩进?我已经更新了我的答案,向您展示正确的缩进应该是什么样子
【解决方案2】:

万一有人遇到这个问题,它最终会成为一个选角问题。在 index.html 上,我用了几个月的“数字”,但 python 将它们读取为字符串(“12”)。我用&lt;select class="form-control" name="month" type="number"&gt; 解决了这个错误。我也可以在 helpers.py 中的所有月份数字周围加上“”,以使它们成为字符串。 @ouroboring 帮助我弄清楚了实际功能,但我太新了,无法投票。谢谢!

【讨论】:

    猜你喜欢
    • 2017-10-14
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 1970-01-01
    • 2011-09-19
    • 2021-08-24
    • 2020-05-13
    • 1970-01-01
    相关资源
    最近更新 更多