django - 使用具有外键的模型序列化程序在 Django Rest Framework 中的父表上执行 CRUD
问题描述
在我的 API 中,我有两个模型Question
,Option
如下所示
class Question(models.Model):
body = models.TextField()
class Options(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
option = models.CharField(max_length=100)
is_correct = models.SmallIntegerField()
在创建问题时,可以同时创建选项会更好。并且不应创建已存在的问题,但如果选项与以前的选项不同,则可以更改选项。
我正在使用ModelSerializer
和ModelViewSet
。Question
我对and使用不同的 url 和视图Option
。
序列化程序.py
class QuestionSerializer(serializers.ModelSerializer):
class Meta:
model = Question
fields = '__all__'
class OptionReadSerializer(serializers.ModelSerializer):
question = QuestionSerializer(read_only=True)
class Meta:
model = Option
fields = ('question', 'option', 'is_correct')
class OptionWriteSerializer(serializer.ModelSerializer):
class Meta:
model = Option
fields = ('question', 'option', 'is_correct')
视图.py
class QuestionViewSet(ModelViewSet):
seriaizer_class = QuestionSerializer
queryset = Question.objects.all()
class OptionViewSet(ModelViewSet):
queryset = Option.objects.all()
def get_serializer_class(self):
if self.request.method == 'POST':
return OptionWriteSerializer
return OptionReadSerializer
网址.py
from django.urls import include
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('api/question', QuestionViewset, base_name='question')
router.register('api/option', OptionViewSet, base_name='option')
urlpatterns = [
path('', include(router.urls))
]
这样,我总是必须先创建问题,然后我才能为该问题单独添加选项。我认为这可能不是一个实用的方法。
最好可以同时添加问题和选项,并且类似于所有 CRUD 操作。
JSON格式的预期结果和发布数据如下所示:
{
"body": "Which country won the FIFA world cup 2018",
"options": [
{
"option": "England",
"is_correct": 0
},
{
"option": "Germany",
"is_correct": 0
},
{
"option": "France",
"is_correct": 1
}
]
}
解决方案
我们可以使用PrimaryKeyRelatedField。
tldr;
我相信一个Question
可以有多个Options
附加到它。而不是让Option
一个Question
.
像这样的东西:
class Question(models.Model):
body = models.TextField()
options = models.ManyToManyField(Option)
class Options(models.Model):
text = models.CharField(max_length=100)
is_correct = models.BooleanField()
然后我们可以像这样使用PrimaryKeyRelatedField :
class QuestionSerializer(serializers.ModelSerializer):
options = serializers.PrimaryKeyRelatedField(queryset=Options.objects.all(), many=True, read_only=False)
class Meta:
model = Question
fields = '__all__'
参考:https ://www.django-rest-framework.org/api-guide/relations/#primarykeyrelatedfield
推荐阅读
- laravel - Laravel updateOrCreate 使用复合键
- mysql - Mysql Replication:该表不符合外部插件的要求
- python - 如何将字典插入sqlite数据库?
- excel - 具有“开始于”多个条件的 VBA 自动过滤器
- aframe - Aframe如何在vr模式下调整画布
- javascript - web-bluetooth 从设备 GATT 获取存储的数据
- python - 有没有办法使用工作表菜单自动更新列菜单?
- c# - 在离线模式下使用 Gmap
- java - ANTLR 不匹配的输入 'foo(some_foo)' 期望 {'foo'}
- sql - 如何获得每天花费的总小时数