استفاده از پردازشگرهای URL

Changelog

جدید در نسخه 0.7.

فلاسک ۰.۷ مفهوم پردازنده های URL را ارائه داد. ایده این است که شما ممکن است تعداد زیادی منابع با بخش های مشترک در URL داشته باشید که همیشه نمی خواهید به طور صریح ارائه دهید. به عنوان مثال، ممکن است تعدادی URL داشته باشید که کد زبان را در خود دارند، اما نمی‌خواهید خودتان آن را در هر تابعی مدیریت کنید.

پردازشگرهای URL به ویژه هنگامی که با طرح های اولیه ترکیب می شوند مفید هستند. ما در اینجا هر دو پردازشگر URL ویژه برنامه و همچنین جزئیات طرح را بررسی خواهیم کرد.

URL های برنامه بین المللی شده

برنامه ای مانند این را در نظر بگیرید:

from flask import Flask, g

app = Flask(__name__)

@app.route('/<lang_code>/')
def index(lang_code):
    g.lang_code = lang_code
    ...

@app.route('/<lang_code>/about')
def about(lang_code):
    g.lang_code = lang_code
    ...

این یک تکرار بسیار ناخوش‌آیند است زیرا باید تنظیمات کد زبان را در شیء g در هر تابع تکی مدیریت کنید. مطمئناً، می‌توان از دکوراتور برای ساده‌سازی این کار استفاده کرد، اما اگر می‌خواهید URL از یک تابع به تابع دیگر تولید کنید، باید همچنان کد زبان را به صراحت ارائه دهید که می‌تواند آزاردهنده باشد.

برای دومی، این جایی است که تابع url_defaults() وارد می شود. آن می تواند به طور خودکار مقادیر را به فراخوانی و به url_for() تزریق کند. کد زیر بررسی می‌کند که آیا کد زبان هنوز در فرهنگ لغت مقادیر URL موجود نیست یا نه و آیا نقطه پایانی مقداری به نام 'lang_code' را می‌خواهد:

@app.url_defaults
def add_language_code(endpoint, values):
    if 'lang_code' in values or not g.lang_code:
        return
    if app.url_map.is_endpoint_expecting(endpoint, 'lang_code'):
        values['lang_code'] = g.lang_code

روش is_endpoint_expecting() نقشه URL را می توان برای فهمیدن اینکه آیا ارائه یک کد زبان برای نقطه پایانی داده شده منطقی است یا خیر استفاده می شود.

عکس آن تابع عبارتند از url_value_preprocessor()s . آنها بلافاصله پس از مطابقت درخواست اجرا می شوند و می توانند کد را بر اساس مقادیر URL اجرا کنند. ایده این است که آنها اطلاعات را از فرهنگ لغت مقادیر بیرون می آورند و در جای دیگری قرار می دهند:

@app.url_value_preprocessor
def pull_lang_code(endpoint, values):
    g.lang_code = values.pop('lang_code', None)

به این ترتیب دیگر لازم نیست در هر تابعی، lang_code را به g اختصاص دهید. شما می توانید با نوشتن دکوراتور خود که URL ها را با کد زبان پیشوند می کند، آن را بیشتر بهبود بخشید، اما راه حل زیباتر استفاده از طرح اولیه است. هنگامی که 'lang_code' از فرهنگ لغت مقادیر ظاهر شد و دیگر به تابع view ارسال نمی شود و کد را به این کاهش می دهد:

from flask import Flask, g

app = Flask(__name__)

@app.url_defaults
def add_language_code(endpoint, values):
    if 'lang_code' in values or not g.lang_code:
        return
    if app.url_map.is_endpoint_expecting(endpoint, 'lang_code'):
        values['lang_code'] = g.lang_code

@app.url_value_preprocessor
def pull_lang_code(endpoint, values):
    g.lang_code = values.pop('lang_code', None)

@app.route('/<lang_code>/')
def index():
    ...

@app.route('/<lang_code>/about')
def about():
    ...

طرح URL های بین‌المللی شده

از آنجایی که طرح‌های اولیه می‌توانند به‌طور خودکار همه URL‌ها را با یک رشته مشترک پیشوند کنند، انجام آن به‌طور خودکار برای هر تابع آسان است. علاوه بر این، نقشه‌ها می‌توانند پردازشگرهای URL هر طرح را داشته باشند که منطق زیادی را از تابع url_defaults حذف می‌کند، زیرا دیگر لازم نیست بررسی کند که آیا URL واقعاً به یک پارامتر `()"lang_code"`` علاقه دارد یا خیر:

from flask import Blueprint, g

bp = Blueprint('frontend', __name__, url_prefix='/<lang_code>')

@bp.url_defaults
def add_language_code(endpoint, values):
    values.setdefault('lang_code', g.lang_code)

@bp.url_value_preprocessor
def pull_lang_code(endpoint, values):
    g.lang_code = values.pop('lang_code')

@bp.route('/')
def index():
    ...

@bp.route('/about')
def about():
    ...