Django Ninja API framework ValueError: Невозможно присвоить "*": "*.*" должен быть экземпляром "*".
В моем проекте используется Django 4.1 и Ninja 0.19.1. Я пытаюсь сделать пост запрос через Swagger или Postman и получаю ошибку ValueError: Cannot assign "115": "Offer.currency_to_sell" must be a "Currency" instance.
Почтовые данные:
{
"currency_to_sell_id": 115,
"currency_to_buy_id": 116,
"user_id": 1,
"amount": 100,
"exchange_rate": 10
}
Endpoint в api.py
@api.post("/add_offer/")
async def add_offer(request, payload: OfferIn):
offer = await Offer.objects.acreate(**payload.dict())
return {"id": offer.pk}
schemas.py
class OfferIn(ModelSchema):
class Config:
model = Offer
model_fields = [
"currency_to_sell",
"currency_to_buy",
"user",
"amount",
"exchange_rate",
]
Модель предложения:
class Offer(models.Model):
"""Sell currency offer model."""
currency_to_sell = models.ForeignKey(
to="Currency",
on_delete=models.CASCADE,
related_name="currencies_to_sell",
verbose_name="Currency to sell",
)
currency_to_buy = models.ForeignKey(
to="Currency",
on_delete=models.CASCADE,
related_name="currencies_to_buy",
verbose_name="Currency to buy",
)
amount = models.DecimalField(
decimal_places=2, max_digits=11, blank=False, null=False, verbose_name="Amount"
)
exchange_rate = models.DecimalField(
decimal_places=2,
max_digits=11,
blank=False,
null=False,
verbose_name="Exchange rate",
)
user = models.ForeignKey(
to=User, on_delete=models.CASCADE, related_name="offers", verbose_name="User"
)
Что я делаю неправильно? Я попробовал другой подход с Schema
вместо ModelSchema
и это сработало.
class OfferIn(Schema):
currency_to_sell_id: int = None
currency_to_buy_id: int = None
user_id: int = None
amount: float
exchange_rate: float
Как вы видите, в вашей модели Offer
есть поле currency_to_sell
, оно содержит объект модели Currency
, поэтому, когда вы отправляете id в запросе POST
вы получаете следующую ошибку:
Cannot assign "115": "Offer.currency_to_sell" must be a "Currency" instance.
Поэтому у вас есть два варианта:
- Когда вы создаете форму, добавьте скрытое поле, которое также включает идентификатор типа содержимого, как объясняется в этом ответе https://stackoverflow.com/a/32110462/14535309 .
- Измените вашу модель
Offer
таким образом, чтобыcurrency_to_sell
фактически был просто id отCurrency
и затем используйте это в ваших views для запроса db для требуемогоCurrency
объекта.