0

I am working on a small reading tracking app in Flask. I cannot seem to write data from one of my routes, below:

@app.route('/add_book', methods=['GET', 'POST'])
@login_required
def add_book():
    form=BookForm()
    if request.method=='POST':
        if form.validate_on_submit():
            book=Book(
                title=form.title.data,
                author=form.author.data,
                # category=form.category.data,
                # added_on=form.added_on.data,
                # done=form.done.data,
                user_id=current_user
                )

            db.session.add(book)
            db.session.commit()
            flash('Book added')
            return redirect(url_for('books'))
        else:
            flash('ERROR. The book not added.')

    return render_template('add_book.html', form=form)

This is the corresponding HTML:

{% extends "layout.html" %}

{% block content %}

{% if form %}

    <form action="{{ url_for('add_book') }}" method="post">
      {{ form.hidden_tag() }}

        {{ form.title.label }}<br>
        {{ form.title() }}<br>

        {{ form.author.label }}<br>
        {{ form.author(cols=32, rows=4) }}<br>

       <!-- {{ form.category.label }}<br>
        {{ form.category() }}<br> -->

        {{ form.submit() }}

    </form>

    {% endif %}

{% endblock %}

When the page renders, the label and forms for the book and author appear, however on clicking Submit, the data does not get saved.

The code section is similar to that for registering a user and I am stuck on what to do because I cannot see any errors. I am using SQLite as a database.

Here is the book model:

class Book(db.Model):

    __tablename__='books'

    id=db.Column(db.Integer, primary_key=True)
    title=db.Column(db.String(100))
    author=db.Column(db.String(50))
    # category=db.Column(db.String(50))
    added_on=db.Column(db.DateTime, index=True, default=datetime.utcnow)
    done=db.Column(db.Boolean, default=False)
    user_id=db.Column(db.Integer, db.ForeignKey('users.id'))

    def __init__(self, title, author, added_on, done, user_id):
        self.title=title
        self.author=author
        self.added_on=added_on
        self.done=done
        self.user_id=user_id

    def __repr__(self):
        # return '<Book: Title - {0}, Author - {1}, Category - {2}>'.format(self.title, self.author, self.category)
        return '<Book: Title - {0}, Author - {1}>'.format(self.title, self.author)
2
  • 2
    What is the Book model, please show that code? Commented Feb 19, 2019 at 15:44
  • Edit: I added the book model. Commented Feb 20, 2019 at 5:48

1 Answer 1

1

The current_user is a user proxy giving access to all user attributes or use something like this How to track the current user in flask-login?

a quick solution would be to change this line

user_id = current_user

into this

user_id = current_user.id

Update: ok, I got it working. You need the following fixes, each of them leads to trouble with form validation and or committing to database: - use current_user.id in your book object as I said earlier. - removed the init method in books model. I'm not sure what the added value is at the moment, I'm getting error messages about fields added on and done which are not on the form. I haven't taken the time to look into it further. - just go for if request.method=='POST' as you don't need both. The form will be checked for validation anyways.

tip: don't forget to create a requirements file (pip freeze --> requirements.txt), that makes it a lot easier to reinstall in a new virtual environment.

Sign up to request clarification or add additional context in comments.

4 Comments

let me test myself with your code, I'll come back on it
thanks, i'll try and test this evening. in the meantime, try add a print before and between this, to see if the form validation is going as expected. db.session.add(book) db.session.commit()
IT'S WORKING! THANK YOU!
No worries mate. Just run in a venv in debug mode and keep a close look at its output. It also helps if you add some prints here and there to check input and output during troubleshooting.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.