如何处理外键字段
问题:CreateView 中包含 ForeignKey,想要传递一个外键例如 author_id,结果报错
代码模拟
models.py
from django.contrib.auth.models import User
from django.db import models
class Article(models.Model):
title = models.CharField(verbose_name="标题", max_length=100)
author = models.ForeignKey(User, verbose_name="作者", on_delete=models.CASCADE)
class Meta:
verbose_name = '文章'
verbose_name_plural = verbose_name
from ninja import ModelSchema
class ArticleIn(ModelSchema):
class Meta:
model = Article
fields = ['title', 'author_id']
class ArticleOut(ModelSchema):
class Meta:
model = Article
fields = '__all__'
from ninja_crud import views, viewsets
from ninja import Router
from .schema import ArticleIn, ArticleOut
route = Router()
class ArticleViewSet(viewsets.APIViewSet):
router = route
model = Article
default_request_body = ArticleIn
default_response_body = ArticleOut
create_view = views.CreateView()
read_view = views.ReadView()
update_view = views.UpdateView()
delete_view = views.DeleteView()
发出网络请求
Request body
{
"title": "string",
"author_id": 12
}
Responses
Traceback (most recent call last):
File "/Users/yiqun/Venv/repgpt_be/lib/python3.10/site-packages/ninja/operation.py", line 107, in run
result = self.view_func(request, **values)
File "/Users/yiqun/Venv/repgpt_be/lib/python3.10/site-packages/ninja_crud/views/api_view.py", line 284, in wrapped_view_function
return self.view_function(
File "/Users/yiqun/Venv/repgpt_be/lib/python3.10/site-packages/ninja_crud/views/create_view.py", line 198, in default_view_function
setattr(instance, field, value)
File "/Users/yiqun/Venv/repgpt_be/lib/python3.10/site-packages/django/db/models/fields/related_descriptors.py", line 215, in __set__
raise ValueError(
ValueError: Cannot assign "12": "Article.author" must be a "User" instance.
问题分析
通过 Model 分析,"Article.author" 必须为一个 "User" 实例,而前端只传了一个 int 的数值。
并且前端是不太可能直接给你传递这个值的,因此, 我们需要自定义 CreateView
的 request_body, 使它允许整数的传入。
schema.py
class NewArticleIn(Schema):
author_id: int
title: str
from ninja_crud import views, viewsets
from ninja import Router
from .schema import ArticleIn, ArticleOut
route = Router()
class ArticleViewSet(viewsets.APIViewSet):
router = route
model = Article
default_request_body = ArticleIn
default_response_body = ArticleOut
create_view = views.CreateView(request_body=NewArticleIn)
read_view = views.ReadView()
update_view = views.UpdateView()
delete_view = views.DeleteView()
问题完。
如有疑问,请留言,或者页面右上角加群讨论。
评论
本文总阅读量次