werkzeug.routing.BuildError: Не удалось создать URL-адрес для конечной точки «rout.urun» со значениями ['lang_code']. Вы забыли указать значения ['urun_id']? - PullRequest
0 голосов
/ 27 марта 2020

У меня есть приложение Flask с пакетами Babel и SQLAlchemy, как показано ниже.

(в app.py нет ничего особенного, только чертежи)

rout.py

from flask import Blueprint, render_template, request, abort, g
from sqlalchemy.exc import ProgrammingError
from database import db
from config import app

routes = Blueprint('routes', __name__, template_folder='templates', url_prefix='/<lang_code>')


# db.drop_all()
# db.create_all()


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


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


@routes.before_request
def before_request():
    if g.lang_code not in app.config['LANGUAGES']:
        abort(404)
    dfl = request.url_rule.defaults
    if 'lang_code' in dfl:
        if dfl['lang_code'] != request.full_path.split('/')[1]:
            abort(404)


from models.urunler import Urunler
from models.kategori import Kategori
from models.uretici import Uretici


@routes.route('/')
def index():
    return render_template('index.html')


@routes.route('/urunler', defaults={'lang_code': 'tr'})
@routes.route('/products', defaults={'lang_code': 'en'})
def urunler():
    sayfa = request.args.get('sayfa')
    if sayfa is None:
        sayfa = 1
    sayfa = int(sayfa)
    sayfa_arti = sayfa + 1
    sayfa_eksi = sayfa - 1
    limit = 18
    offset = sayfa * limit
    urunler = Urunler.query.offset(offset).limit(limit)
    urun_sayfa_adet = urunler.count()
    return render_template('urunler.html', urunler=urunler, kategoriler=kategoriler, ureticiler=ureticiler, sayfa=sayfa,
                           sayfa_arti=sayfa_arti, sayfa_eksi=sayfa_eksi, urun_sayfa_adet=urun_sayfa_adet, limit=limit)


@routes.route('/urun/<int:urun_id>', methods=['GET', 'POST'], defaults={'lang_code': 'tr'})
@routes.route('/product/<int:urun_id>', methods=['GET', 'POST'], defaults={'lang_code': 'en'})
def urun(urun_id):
    urun = Urunler.query.get(urun_id)
    return render_template('urun.html', urun=urun)


@app.errorhandler(404)
def notfound(e):
    return render_template('404.html')

И мой шаблон jinja2 находится ниже:

<div class="row row-cols-md-1 row-cols-md-3">
    {% for urun in urunler %}
        <div class="col mb-4">
            <div class="card h-100">
                <img src="{{ urun.resim }}" class="card-img-top w-75 align-self-center" alt="{{ urun.urun_isim }}">
                <div class="card-body">
                    <h5 class="card-title">{{ urun.urun_isim }}</h5>
                    <p class="card-text small">{{ urun.aciklama }}</p>
                </div>

                <div class="card-footer">
                    <span class="small"><span class="font-weight-bold">Ürün Kodu:</span> {{ urun.kod }}</span><br>
                    <span class="small"><span class="font-weight-bold">Kategori:</span> {{ urun.kategori.kategori_isim }}</span><br>
                    <span class="small"><span class="font-weight-bold">Marka:</span> {{ urun.uretici.uretici_isim }}</span>
                 </div>

                 <a href="{{ url_for('routes.urun', urun_id=urun.urun_id) }}" class="btn btn-primary btn-sm" style="border-radius: 0 0 3px 3px">Ürün sayfasına git</a>
            </div>
        </div>
    {% endfor %}
</div>

Когда я пытаюсь открыть страницу go /en/products/1, она выдает ошибку ниже.

werkzeug.routing.BuildError: Could not build url for endpoint 'routes.urun' with values ['lang_code']. Did you forget to specify values ['urun_id']?

Я много раз пытался указать urun_id, но у меня ничего не получалось. Может кто-нибудь объяснить, почему возникает эта ошибка, даже если я указываю urun_id в шаблоне jinja2?

EDIT

Я обнаружил, в чем проблема. Я должен указать urun_id в маршруте Blueprint ниже.

@routes.route('/urun/<int:urun_id>', methods=['GET', 'POST'], defaults={'lang_code': 'tr', 'urun_id': some_dynamic_id_from_below_query})
@routes.route('/product/<int:urun_id>', methods=['GET', 'POST'], defaults={'lang_code': 'en', 'urun_id': some_dynamic_id_from_below_query})

def urun(urun_id):
    urun = Urunler.query.get(urun_id)
    return render_template('urun.html', urun=urun)

Но я не могу сделать это urun_id по умолчанию Dynami c. У кого-нибудь есть идея?

...