Добавление комментариев в веб-приложение блога фляги - PullRequest
0 голосов
/ 31 августа 2018

Я пытаюсь добавить комментарии к своим сообщениям. Я на шаге 1, где я вручную захожу на URL / post / post_id / comment (в зависимости от маршрута).

Это покажет мне форму, и эта форма после проверки обновит БД.

Вот код для моделей:

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    content = db.Column(db.Text, nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    comments = db.relationship('Comment', backref='article', lazy=True)

    def __repr__(self):
        return f"Post('{self.title}', '{self.date_posted}')"

class Comment(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    body = db.Column(db.String(100), nullable=False)
    timestamp = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    post_id = db.Column(db.Integer, db.ForeignKey('post.id'), nullable=False)

    def __repr__(self):
        return f"Comment('{self.body}', '{self.timestamp}')"

Форма:

class AddCommentForm(FlaskForm):
    body = StringField("Body", validators=[DataRequired()])
    submit = SubmitField("Post")

Это моя функция просмотра:

@app.route("/post/<int:post_id>/comment", methods=["GET", "POST"])
@login_required
def comment_post(post_id):
    post = Post.query.get_or_404(post_id)
    form = AddCommentForm()
    if form.validate_on_submit():
        comment = Comment(body=form.body.data, article=post.id)
        db.session.add(comment)
        db.session.commit()
        flash("Your comment has been added to the post", "success")
        return redirect(url_for("post", post_id=post.id))
    return render_template("comment_post.html", title="Comment Post", form=form)

А это шаблон:

{% extends "layout.html"%}
{% block content %}
<div class="content-section">
        <form method="POST" action="">
            {{ form.hidden_tag() }}
            <fieldset class="form-group">
                <legend class="border-bottom mb-4">Comment</legend>
                <div class="form-group">
                    {{ form.body.label(class="form-control-label") }}
                    {% if form.body.errors %}
                        {{ form.body(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.body.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.body(class="form-control form-control-lg") }}
                    {% endif %}
                </div>
            </fieldset>
            <div class="form-group">
                {{ form.submit(class="btn btn-outline-info") }}
            </div>
        </form>
    </div>
{% endblock content %}

Проблема, с которой я сталкиваюсь, заключается в том, что форма, кажется, не проверяется, т. Е. На маршруте я могу получить флэш-сообщение, если я отправлю его прямо над «form.validate_on_submit».

Но, похоже, что даже когда я "отправляю" форму в html, она не входит в цикл "if".

Что мне здесь не хватает?

1 Ответ

0 голосов
/ 31 августа 2018

Первое, что я вижу, что это неправильно, это то, что ваш атрибут action пуст, и это означает, что когда вы отправляете форму, она никуда не денется.

Исправьте это, добавив в свой HTML атрибут action, который указывает на маршрут, который обрабатывает форму.

{% extends "layout.html"%}
{% block content %}
<div class="content-section">
        <form method="POST" action="{{url_for('comment_post', post_id=str(post_id))}}">
            {{ form.hidden_tag() }}
            <fieldset class="form-group">
                <legend class="border-bottom mb-4">Comment</legend>
                <div class="form-group">
                    {{ form.body.label(class="form-control-label") }}
                    {% if form.body.errors %}
                        {{ form.body(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.body.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.body(class="form-control form-control-lg") }}
                    {% endif %}
                </div>
            </fieldset>
            <div class="form-group">
                {{ form.submit(class="btn btn-outline-info") }}
            </div>
        </form>
    </div>
{% endblock content %}

в вашем коде маршрута вы должны сделать следующее:

from flask import request

@app.route("/post/<int:post_id>/comment", methods=["GET", "POST"])
@login_required
def comment_post(post_id):
    post = Post.query.get_or_404(post_id)
    form = AddCommentForm()
    if request.method == 'POST': # this only gets executed when the form is submitted and not when the page loads
        if form.validate_on_submit():
            comment = Comment(body=form.body.data, article=post.id)
            db.session.add(comment)
            db.session.commit()
            flash("Your comment has been added to the post", "success")
            return redirect(url_for("post", post_id=post.id))
    return render_template("comment_post.html", title="Comment Post", 
form=form, post_id=post_id)

Наконец, попробуйте вместо этого использовать InputRequired() validator.

from wtforms.validators import InputRequired
class AddCommentForm(FlaskForm):
    body = StringField("Body", validators=[InputRequired()])
    submit = SubmitField("Post")
...