Django Rest Framework - 在 POST 上创建外键对象

Sam*_*Sam 7 python django foreign-keys django-rest-framework

我有一个简单的 DRF REST API,我想用它来创建博客文章。我希望能够为这些博客文章添加标签,以便用户可以搜索标签并查看相关文章。但是,标签可能还不存在。我已经创建了一个Article带有 ForeignKey 字段的Tag模型到这样的模型:

class Tag(models.Model):

    name = models.CharField(max_length=32)

    def _str__(self):
        return self.name

    class Meta:
        ordering = ('name',)

class Article(models.Model):

    title = models.CharField(max_length=256)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    content = models.TextField()
    date = models.DateTimeField(auto_now_add=True)
    tags = models.ForeignKey(Tag, on_delete=models.CASCADE, blank=True, default=None)

    def __str__(self):
        return self.title

    class Meta:
        ordering = ('date', 'id')
Run Code Online (Sandbox Code Playgroud)

理想情况下,我想要的是能够发布Article带有一组标签的新标签,如果任何标签不存在,请在数据库中创建它们。但是,就目前而言,标签需要已经存在才能添加到Article. 从视觉上看,DRF 将其显示为填充有预先存在的标签的下拉列表:

DRF接口

如何Tag从我的ArticleAPI 端点添加或创建多个s ?

编辑:根据要求,我添加了我的 views.py

视图.py:

from api.blog.serializers import ArticleSerializer, TagSerializer
from rest_framework import viewsets

# /api/blog/articles
class ArticleView(viewsets.ModelViewSet):

    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

# /api/blog/tags
class TagView(viewsets.ModelViewSet):

    queryset = Tag.objects.all()
    serializer_class = TagSerializer
Run Code Online (Sandbox Code Playgroud)

为了完整起见,这里是我的 REST API 的 serializers.py 中的序列化程序。

序列化程序.py:

class ArticleSerializer(serializers.ModelSerializer):

    class Meta:
        model = Article
        fields = '__all__'


class TagSerializer(serializers.ModelSerializer):

    class Meta:
        model = Tag
        fields = '__all__'
Run Code Online (Sandbox Code Playgroud)

网址.py:

from rest_framework import routers

router = routers.DefaultRouter()
router.register('articles', views.ArticleView)
router.register('tags', views.TagView)

urlpatterns = [
    path('', include(router.urls)),
]
Run Code Online (Sandbox Code Playgroud)

JPG*_*JPG 16

create()将序列化程序的方法覆盖为

class ArticleSerializer(serializers.ModelSerializer):
    tags = serializers.CharField()

    class Meta:
        model = Article
        fields = '__all__'

    def create(self, validated_data):
        tag = validated_data.pop('tags')
        tag_instance, created = Tag.objects.get_or_create(name=tag)
        article_instance = Article.objects.create(**validated_data, tags=tag_instance)
        return article_instance
Run Code Online (Sandbox Code Playgroud)