Вопрос

I'm following the Flask Mega Tutorial by Miguel Grinberg. He does a great job of focusing on logging users in / out, and dealing with adding content (blog posts), but it's challenging to extrapolate simple CRUD operations from the tutorial. The focus seems to be on adding data (user logins, new blog posts), rather than editing existing data.

I've currently got a Company model in models.py, with a method that I think returns a Company object based on the id provided:

class Company(db.Model):
  id = db.Column(db.Integer, primary_key = True)
  name = db.Column(db.String(120), index = True)

  def load_company_by_id(id):
    return Company.query.get(int(id))

  def __repr__(self):
    return '<Company %r>' % (self.name)

In my view, I have:

from flask import render_template, flash, redirect, request
from app import app
from forms import CompanyForm
from models import Company
...
...
@app.route('/company/edit/<id>', methods=['GET','POST'])
def company_edit(id):
  company = Company.load_company_by_id(id)
  form = CompanyForm(obj=company)
  return render_template('company_form.html', form = form)

I'm getting an error: TypeError: unbound method load_company_by_id() must be called with Company instance as first argument (got unicode instance instead). It's not clear to me why a method defined by me would be expecting more arguments than I designed it to expect.

Это было полезно?

Решение

Your method load_company_by_id() is defined as an instance method currently, while you're trying to use it as a class method. To make it a class method, you need to use classmethod decorator:

@classmethod
def load_company_by_id(cls, id):
    # Class itself is passed as the first argument.
    return cls.query.get(int(id))

But why not remove this method altogether and simply call Company.query.get()?

# Note the route (<int:id> part), not only it makes sure that id is an integer,
# it also returns an int.
@app.route('/company/edit/<int:id>', methods=['GET','POST'])
def company_edit(id):
    company = Company.query.get(id)
    form = CompanyForm(obj=company)
    return render_template('company_form.html', form=form)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top