質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Jinja2

Jinja2は、Python用のテンプレートエンジンです。テンプレートファイルの読込や文字列の埋込、分岐/ループの制御文のサポートなどの機能を持ちます。HTMLやXML生成によく使用されますが、どのような文書でも生成することが可能です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1491閲覧

Flask expected token ',', got 'main'エラー

退会済みユーザー

退会済みユーザー

総合スコア0

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Jinja2

Jinja2は、Python用のテンプレートエンジンです。テンプレートファイルの読込や文字列の埋込、分岐/ループの制御文のサポートなどの機能を持ちます。HTMLやXML生成によく使用されますが、どのような文書でも生成することが可能です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2023/04/25 12:48

編集2023/04/25 21:59

Flaskのアプリを実行すると、どうしてもcategory_maintenance.html内の
<li {% if blog_categories.has_next %}class="page-item"{% else %} class="page-item disabled"{% endif %}><a class="page-link" href="{% if blog_categories.has_next %}{{ url_for('main.category_maintenance', page=blog_categories.next_num) }}{% else %}#{% endif %}">次へ</a></li> </ul>でエラーとなってしまいます。

エラー内容

jinja2.exceptions.TemplateSyntaxError: expected token ',', got 'main'

エラー内容を調べると、()や{}の閉じ忘れの様なことですが、何度見直しても、閉じ忘れは無いように思えます。
どなたかアドバイス、ご教示いただければと思います。

category_maintenance.html

html

1{% extends "base.html" %} 2{% block content %} 3 <header id="page-header"> 4 <div class="container my-3 py-3 bg-light"> 5 <div class="row"> 6 <div class="col-md-6 m-auto text-center"> 7 <h1>カテゴリ管理</h1> 8 </div> 9 </div> 10 </div> 11 </header> 12 <section id="menu"> 13 <div class="container my-3 py-3 bg-light"> 14 <div class="row"> 15 <div class="col-md-3"> 16 <button type="button" class="btn btn-warning w-100" data-bs-toggle="modal" data-bs-target="#addCategoryModal"> 17 カテゴリ追加 18 </button> 19 </div> 20 </div> 21 </div> 22 </section> 23 24 <section id="list"> 25 <div class="container my-3"> 26 <div class="row"> 27 <div class="col-md-9"> 28 <div class="card"> 29 <div class="card-header"> 30 <h4>最新のカテゴリ</h4> 31 </div> 32 <table class="table table-striped"> 33 <thead class="table-dark"> 34 <tr> 35 <th>ID</th> 36 <th>カテゴリ名</th> 37 <th>ブログ投稿数</th> 38 <th>変更</th> 39 </tr> 40 </thead> 41 <tbody> 42 {% for blog_category in blog_categories.items %} 43 <tr> 44 <td>{{ blog_category.id }}</td> 45 <td>{{blog_category.category}}</td> 46 <td><a href="#">ブログ投稿数</a></td> 47 <td><a href="#" class="btn btn-secondary"> 48 変更 49 </a></td> 50 </tr> 51 {% endfor %} 52 </tbody> 53 </table> 54 </div> 55 </div> 56 </div> 57 </div> 58 </section> 59 60 <nav class="my-2" aria-label="Page navigation"> 61 <ul class="pagination justify-content-center"> 62 <li {% if blog_categories.has_prev %}class="page-item"{% else %} class="page-item disabled"{% endif %}><a class="page-link" href="{% if blog_categories.has_prev %}{{ url_for('main.category_maintenance', page=blog_categories.prev_num) }}{% else %}#{% endif %}">前へ</a></li> 63 64 65 {% for page_num in blog_categories.iter_pages(left_edge=1, right_edge=1, left_current=1, right_current=2) %} 66 {% if page_num %} 67 {% if blog_categories.page == page_num %} 68 <li class="page-item disabled"><a class="page-link" href="#">{{ page_num }}</a></li> 69 {% else %} 70 <li class="page-item"><a class="page-link" href="{{ url_for('main.category_maintenance, page=page_num) }}">{{ page_num }}</a></li> 71 {% endif %} 72 {% else %} 73 <li class="page-item disabled"><a class="page-link" href="#">&hellip;</a></li> 74 {% endif %} 75 {% endfor %} 76 77 <li {% if blog_categories.has_next %}class="page-item"{% else %} class="page-item disabled"{% endif %}><a class="page-link" href="{% if blog_categories.has_next %}{{ url_for('main.category_maintenance', page=blog_categories.next_num) }}{% else %}#{% endif %}">次へ</a></li> 78 </ul> 79 </nav> 80<!-- Modal --> 81<div class="modal fade" id="addCategoryModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"> 82 <div class="modal-dialog modal-lg"> 83 <div class="modal-content"> 84 <div class="modal-header bg-warning"> 85 <h5 class="modal-title" id="exampleModalLabel">カテゴリ追加</h5> 86 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 87 </div> 88 <form method="POST"> 89 {{ form.hidden_tag() }} 90 <div class="modal-body"> 91 <div class="form-group"> 92 {{ form.category.label(class="form-control-label") }} 93 {{ form.category(class="form-control") }} 94 </div> 95 </div> 96 <div class="modal-footer"> 97 {{ form.submit(class="btn btn-warning") }} 98 </div> 99 </form> 100 </div> 101 </div> 102 </div> 103{% endblock %}

base.html

html

1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <!-- CSS only --> 8 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> 9 <!-- JavaScript Bundle with Popper --> 10 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script> 11 <title>Yossy Inc.</title> 12</head> 13<body> 14 <nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top"> 15 <div class="container"> 16 <a class="navbar-brand" href="#">Sample Inc.</a> 17 <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> 18 <span class="navbar-toggler-icon"></span> 19 </button> 20 <div class="collapse navbar-collapse" id="navbarNav"> 21 <ul class="navbar-nav"> 22 <li class="nav-item"> 23 <a class="nav-link" href="#">ホーム</a> 24 </li> 25 <li class="nav-item"> 26 <a class="nav-link" href="#">会社情報</a> 27 </li> 28 <li class="nav-item"> 29 <a class="nav-link" href="#">お問い合わせ</a> 30 </li> 31 </ul> 32 33 <ul class="navbar-nav ms-auto"> 34 <li class="nav-item"> 35 <a class="nav-link" href="#">ブログ</a> 36 </li> 37 <li class="nav-item"> 38 <a class="nav-link" href="{{ url_for('main.category_maintenance') }}">カテゴリ</a> 39 </li> 40 <li class="nav-item"> 41 <a class="nav-link" href="#">お問い合わせ</a> 42 </li> 43 <li class="nav-item"> 44 <a class="nav-link" href="{{url_for('users.user_maintenance')}}">ユーザー</a> 45 </li> 46 {% if current_user.is_authenticated %} 47 <li class="nav-item"> 48 <a class="nav-link" href="{{ url_for('users.logout') }}">ログアウト</a> 49 </li> 50 <span class="navbar-text ms-3"> 51 {{ current_user.username }} 52 </span> 53 {% endif %} 54 </ul> 55 </div> 56 </div> 57 </nav> 58 {% from "_formhelpers.html" import render_field %} 59 60 <div class="container" style="padding-top: 4rem; padding-bottom: 4rem;"> 61 {% for message in get_flashed_messages() %} 62 <div class="alert alert-warning alert-dismissible fade show" role="alert"> 63 {{ message }} 64 <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button> 65 </div> 66 {% endfor %} 67 68 {% block content %} 69 70 {% endblock %} 71 </div> 72 73 <footer id="footer" class="footer text-center pt-2 bg-dark fixed-bottom"> 74 <div class="container"> 75 <div class="row"> 76 <div class="col text-white"> 77 <p>Copyright @ 2022 Sample Inc.</p> 78 </div> 79 </div> 80 </div> 81 </footer> 82</body> 83</html>

vies.py

python

1from flask import Blueprint, render_template, request, url_for, redirect, flash 2from flask_login import login_required 3from company_blog.models import BlogCategory 4from company_blog.main.forms import BlogCategoryForm 5from company_blog import db 6 7# Blueprintの実装 8main = Blueprint('main', __name__) 9 10@main.route('/category_maintenance', methods=['GET', 'POST']) 11@login_required 12def category_maintenance(): 13 page = request.args.get('page', 1, type=int) 14 blog_categories = BlogCategory.query.order_by(BlogCategory.id.asc()).paginate(page=page, per_page=10) 15 form = BlogCategoryForm() 16 # フォームの入力チェック 17 if form.validate_on_submit(): 18 # 問題が無い場合、blog_categoryにフォームデータを渡す。 19 blog_category = BlogCategory(category=form.category.data) 20 db.session.add(blog_category) 21 db.session.commit() 22 flash('ブログカテゴリが追加されました') 23 return redirect(url_for('main.category_maintenance')) 24 elif form.errors: 25 # フォームの内容をクリア 26 form.category.data = "" 27 # フィールドカテゴリに設定されたエラーメッセージを表示 28 flash(form.errors['category'][0]) 29 return render_template('category_maintenance.html', blog_categories=blog_categories, form=form)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

間違いは必ずあるに決まっているので、1文字ずつ、間違いが見つかるまでチェックを繰り返せば良いだけです。

70行目の、'main.category_maintenanceの閉じるシングルクォートが無いです。

慣れれば、

got 'main'

というエラーメッセージから、mainの直前にあるシングルクォートの、それ以前の箇所での閉じ忘れではないかという見当がすぐ付きますが、文法エラーの場合、慣れていなくても、上記のように見つかるまで探せば絶対に見つかります。

投稿2023/04/25 12:59

編集2023/04/25 12:59
otn

総合スコア84423

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問