Неверный запрос POST с отношениями с использованием flask-restless

Я использую flask-restless и получаю ошибку Bad Request (400) на своем первом POST (от Postman). Если я продолжаю делать тот же запрос, он продолжает ошибаться. Но если я удалю поле, на которое жалуется flask-restless, снова запущу POST, получу положительный ответ, добавлю то же самое поле обратно и снова запущу его, с этого момента он будет работать нормально.

URL-адрес: /api/appraisals

Запрос JSON:

{
    "suggested_price": 88,
    "listing": {"id": 1}
}

Ответ об ошибке:

{
    "message": "Model does not have field 'listing'"
}

app.py:

from models.db import init_app
from controllers import api


app = Flask(__name__)
app.config.from_object('config')
init_app(app)

api.init_api(app)

из models.db.py:

 from flask.ext.sqlalchemy import SQLAlchemy

 def init_app(app):
      with app.app_context():
           db.init_app(app)
           db.create_all()

 db = SQLAlchemy()

из контроллеров.api.py:

 from flask.ext.restless import APIManager

 class ResourceManager(APIManager): ...

 def init_api(app):
      with app.app_context():
           manager = ResourceManager(app, flask_sqlalchemy_db=db)
           manager.add_resource(ListingResource())
           manager.add_resource(AppraisalResource())

из моделей.оценка.py:

 from .db import db
 from .base import BaseModel


 class Appraisal(BaseModel):

      __tablename__ = "appraisal"

      # required fields
      suggested_price = db.Column(db.Integer, nullable=False)

      # optional fields
      currency = db.Column(db.Unicode, default=u"USD")

      # relationships
      listing_id = db.Column(db.Integer, db.ForeignKey('listing.id'))

из models.listing.py:

 from sqlalchemy.schema import UniqueConstraint

 from .db import db
 from .base import BaseModel

 class Listing(StatusfulModel, BaseModel):

     __tablename__ = "listing"

     # relationships
     appraisals = db.relationship(
         "Appraisal",
         backref=db.backref("listing", uselist=False),
         uselist=True)

из controllers.resource.appraisal.py:

 class AppraisalResource(Resource):

      model_class = Appraisal
      base_url = "appraisals"
      allowed_methods = ["POST", "GET"]

      def get_fields(self):
           super_fields = super(AppraisalResource, self).get_fields()

           return super_fields + [
                "listing",
                "listing.id"
           ]

person Evan Hammer    schedule 21.06.2014    source источник
comment
Два вопроса: 1. Что вы используете для выполнения запроса POST? 2. Как выглядит ListingResource?   -  person Sean Vieira    schedule 21.06.2014
comment
Вы пытались использовать listing_id вместо списка?   -  person Or Duan    schedule 21.06.2014
comment
@OrDuan listing_id работает. Это правильный путь?   -  person Evan Hammer    schedule 21.06.2014
comment
@EvanHammer я отправил ответ, потому что он слишком долго для комментариев   -  person Or Duan    schedule 21.06.2014


Ответы (1)


Я думаю, что лучший способ объяснить, как решить эту ошибку, — рассказать вам, о чем я думал, когда думал об этом.

Вы будете часто сталкиваться с такими ситуациями с API, и важно знать, как думать о логике.

  1. Вы получили ошибку 400 — это означает, что вы отправили JSON, но не в том формате, который ожидает Flask.
  2. Согласно вашему вопросу, удаление поля списка решило проблему - похоже, мы приближаемся.
  3. Я посмотрел, какую модель вы пытаетесь изменить (/api/appraisals) — Оценки.
  4. Ваша модель:

    class Appraisal(BaseModel):
        __tablename__ = "appraisal"
    
        suggested_price = db.Column(db.Integer, nullable=False)
        currency = db.Column(db.Unicode, default=u"USD")
        listing_id = db.Column(db.Integer, db.ForeignKey('listing.id'))
    
  5. Посмотрев на это, вы можете увидеть, что Flask ожидает «listing_id», а не «listing».

Я надеюсь, что я был ясным, скажите мне, если вам нужна помощь. Удачи!

person Or Duan    schedule 21.06.2014
comment
Отдавая вам должное, поскольку это решило проблему. И спасибо вам за это! Но ошибочный характер ошибки — это проблема с flask-restless. Я отправляю один и тот же запрос дважды: один раз не получается, один раз работает. Кроме того, listing является отношением к объекту "Оценка". Если вы перечислите его RelationshipProperty, вы увидите это. - person Evan Hammer; 21.06.2014