ฉันมีเว็บแอพพลิเคชั่นบน Flask ที่ซับซ้อน มีไฟล์แยกต่างหากมากมายพร้อมฟังก์ชั่นการดู URL ของพวกเขาถูกกำหนดด้วย@app.route('/...')
มัณฑนากร มีวิธีรับรายการเส้นทางทั้งหมดที่ประกาศไว้ในแอพของฉันหรือไม่ อาจมีวิธีการบางอย่างที่ฉันสามารถโทรหาapp
วัตถุได้?
ฉันมีเว็บแอพพลิเคชั่นบน Flask ที่ซับซ้อน มีไฟล์แยกต่างหากมากมายพร้อมฟังก์ชั่นการดู URL ของพวกเขาถูกกำหนดด้วย@app.route('/...')
มัณฑนากร มีวิธีรับรายการเส้นทางทั้งหมดที่ประกาศไว้ในแอพของฉันหรือไม่ อาจมีวิธีการบางอย่างที่ฉันสามารถโทรหาapp
วัตถุได้?
คำตอบ:
ทุกเส้นทางสำหรับโปรแกรมที่ถูกเก็บไว้บนซึ่งเป็นตัวอย่างของapp.url_map
werkzeug.routing.Map
คุณสามารถวนซ้ำRule
อินสแตนซ์โดยใช้iter_rules
วิธีการ:
from flask import Flask, url_for
app = Flask(__name__)
def has_no_empty_params(rule):
defaults = rule.defaults if rule.defaults is not None else ()
arguments = rule.arguments if rule.arguments is not None else ()
return len(defaults) >= len(arguments)
@app.route("/site-map")
def site_map():
links = []
for rule in app.url_map.iter_rules():
# Filter out rules we can't navigate to in a browser
# and rules that require parameters
if "GET" in rule.methods and has_no_empty_params(rule):
url = url_for(rule.endpoint, **(rule.defaults or {}))
links.append((url, rule.endpoint))
# links is now a list of url, endpoint tuples
ดูลิงก์ที่แสดงไปยังเว็บเพจใหม่ที่สร้างขึ้นสำหรับข้อมูลเพิ่มเติมอีกเล็กน้อย
DeleteEvent
มีพารามิเตอร์ที่จำเป็น - คุณสามารถเป็นกรณีพิเศษที่หนึ่งหรือกรองออกกฎใด ๆ ที่len(rule.arguments) > len(rule.defaults)
url_for
ไม่สามารถสร้าง URL สำหรับ methid นั้นโดยไม่มีพารามิเตอร์ใช่ไหม ตกลง แต่ดูเหมือนว่าวิธีการของฉันจะใช้งานได้ แต่มันจะเก็บส่วนนั้นไว้ถ้า URL เป็นพารามิเตอร์ ขอบคุณ!
url_for(rule.endpoint)
งานrule.rule
นั้นดีกว่าเพราะจะแก้ปัญหาที่คุณมีมากกว่าหนึ่งเส้นทางสำหรับวิธีการเดียวกัน
ฉันเพิ่งพบคำถามเดียวกัน วิธีแก้ปัญหาข้างต้นนั้นซับซ้อนเกินไป เพียงเปิดเปลือกใหม่ภายใต้โครงการของคุณ:
python
>>> from app import app
>>> app.url_map
' app ' ตัวแรกคือสคริปต์โครงการของฉัน: app.pyอีกอันคือชื่อเว็บของฉัน
(วิธีนี้เหมาะสำหรับเว็บเล็ก ๆ ที่มีเส้นทางเล็กน้อย)
Map
อินสแตนซ์หรือเข้าถึงคุณสมบัติใด ๆ ของRule
มันที่มีอยู่โดยที่คุณไม่สามารถทำอะไรได้เลย
ฉันทำวิธีผู้ช่วยในของฉันmanage.py
:
@manager.command
def list_routes():
import urllib
output = []
for rule in app.url_map.iter_rules():
options = {}
for arg in rule.arguments:
options[arg] = "[{0}]".format(arg)
methods = ','.join(rule.methods)
url = url_for(rule.endpoint, **options)
line = urllib.unquote("{:50s} {:20s} {}".format(rule.endpoint, methods, url))
output.append(line)
for line in sorted(output):
print line
มันแก้ข้อโต้แย้งที่ขาดหายไปโดยการสร้างตัวเลือกชุดจำลอง ผลลัพธ์ดูเหมือนว่า:
CampaignView:edit HEAD,OPTIONS,GET /account/[account_id]/campaigns/[campaign_id]/edit
CampaignView:get HEAD,OPTIONS,GET /account/[account_id]/campaign/[campaign_id]
CampaignView:new HEAD,OPTIONS,GET /account/[account_id]/new
จากนั้นเรียกใช้:
python manage.py list_routes
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการชำระเงิน Manage.py: http://flask-script.readthedocs.org/en/latest/
urllib.unquote
ไปurllib.parse.unquote
และprint line
ไปprint(line)
และทำงานในหลาม 3.x เช่นกัน
คล้ายกับคำตอบของโจนาธานฉันเลือกที่จะทำสิ่งนี้แทน ฉันไม่เห็นจุดที่ใช้ url_for เพราะมันจะแตกถ้าข้อโต้แย้งของคุณไม่ใช่สตริงเช่นลอย
@manager.command
def list_routes():
import urllib
output = []
for rule in app.url_map.iter_rules():
methods = ','.join(rule.methods)
line = urllib.unquote("{:50s} {:20s} {}".format(rule.endpoint, methods, rule))
output.append(line)
for line in sorted(output):
print(line)
เห็นได้ชัดว่าตั้งแต่เวอร์ชั่น 0.11 Flask มี CLI ในตัว คำสั่งในตัวหนึ่งรายการเส้นทาง:
FLASK_APP='my_project.app' flask routes
flask urls
สำหรับฉัน (0.12.1) เห็นว่าในflask --help
แต่ฉันไม่เห็นเส้นทางหรือ URL ในหน้า CLI
เนื่องจากคุณไม่ได้ระบุว่าจำเป็นต้องเรียกใช้บรรทัดคำสั่งจึงสามารถส่งคืนข้อมูลต่อไปนี้ใน json ได้อย่างง่ายดายสำหรับแดชบอร์ดหรืออินเทอร์เฟซที่ไม่ใช่บรรทัดคำสั่งอื่น ๆ ผลลัพธ์และผลลัพธ์ที่ได้ไม่ควรนำมาจากมุมมองของการออกแบบเลย มันเป็นการออกแบบโปรแกรมที่ไม่ดีแม้ว่ามันจะเป็นโปรแกรมเล็ก ๆ ผลลัพธ์ด้านล่างนั้นสามารถใช้ในเว็บแอปพลิเคชัน, บรรทัดคำสั่งหรือสิ่งอื่นใดที่นำเข้า json
คุณไม่ได้ระบุว่าคุณจำเป็นต้องรู้ฟังก์ชั่นของหลามที่เชื่อมโยงกับแต่ละเส้นทางดังนั้นสิ่งนี้จะตอบคำถามของคุณได้แม่นยำยิ่งขึ้น
ฉันใช้ด้านล่างเพื่อเพิ่มเอาต์พุตไปยังแดชบอร์ดการตรวจสอบด้วยตนเอง หากคุณต้องการวิธีการหาเส้นทางที่พร้อมใช้งาน (GET, POST, PUT, ฯลฯ ) คุณจะต้องรวมกับคำตอบอื่น ๆ ด้านบน
Rule's repr () ดูแลการแปลงอาร์กิวเมนต์ที่จำเป็นในเส้นทาง
def list_routes():
routes = []
for rule in app.url_map.iter_rules():
routes.append('%s' % rule)
return routes
สิ่งเดียวกันโดยใช้รายการความเข้าใจ:
def list_routes():
return ['%s' % rule for rule in app.url_map.iter_rules()]
ตัวอย่างผลลัพธ์:
{
"routes": [
"/endpoint1",
"/nested/service/endpoint2",
"/favicon.ico",
"/static/<path:filename>"
]
}
หากคุณจำเป็นต้องเข้าถึงฟังก์ชั่นมุมมองของตัวเองแล้วแทนการใช้app.url_map
app.view_functions
สคริปต์ตัวอย่าง:
from flask import Flask
app = Flask(__name__)
@app.route('/foo/bar')
def route1():
pass
@app.route('/qux/baz')
def route2():
pass
for name, func in app.view_functions.items():
print(name)
print(func)
print()
เอาต์พุตจากการรันสคริปต์ด้านบน:
static
<bound method _PackageBoundObject.send_static_file of <Flask '__main__'>>
route1
<function route1 at 0x128f1b9d8>
route2
<function route2 at 0x128f1ba60>
(สังเกตการรวมเส้นทาง "คงที่" ซึ่งสร้างโดยอัตโนมัติโดย Flask)
คุณสามารถดูเส้นทางทั้งหมดผ่านเปลือกขวดโดยการเรียกใช้คำสั่งต่อไปนี้หลังจากการส่งออกหรือการตั้งค่าตัวแปรสภาพแวดล้อม FLASK_APP
flask shell
app.url_map
ภายในแอพขวดของคุณทำ:
flask shell
>>> app.url_map
Map([<Rule '/' (OPTIONS, HEAD, GET) -> helloworld>,
<Rule '/static/<filename>' (OPTIONS, HEAD, GET) -> static>])
url = url_for(rule.endpoint)
ยกเว้นผมมีปัญหากับสาย ฉันเพิ่งได้รับข้อผิดพลาดBuildError: ('DeleteEvent', {}, None)
นี้ เพื่อรับ URL ที่ฉันทำurl = rule.rule
ไปแทน ความคิดใดที่ว่าทำไมวิธีการของคุณใช้ไม่ได้