繁体   English   中英

序列化自引用外键

[英]serialize self-referential foreign key

假设我想创建一篇文章,通过 slug 链接到一篇或多篇其他文章(现在是一篇)。 一个帖子请求给了我一些文章信息和相关的 slug。 我想要

  1. 验证数据和相关的 slug
  2. 在数据库中创建一篇文章
  3. 退回文章(带有蛞蝓)

models.py

class Article(models.Model):
        heading = models.CharField(max_length=2550)
        slug = models.SlugField(null=True, default=None, unique=True, max_length=255)
        article_previous = models.ForeignKey('self', to_field='slug', blank=True, null=True, 
        related_name='subcategories', on_delete=models.DO_NOTHING)

serializers.py

class ArticleSerializer(serializers.ModelSerializer):

    class Meta:
        model = Article
        fields = (
            "heading",
            "slug",
            "article_previous",

    def create(self, validated_data):
        try:
            article_previous = Article.objects.get(slug=d['value'])
            article_previous_slug = article_previous.slug
        except Article.DoesNotExist:
            raise serializers.ValidationError(f'No Article with the slug {d["value"]}')
        
        article=Article.objects.create(**validated_data,article_previous_id=article_previous_slug)
        return validated_data

该解决方案提供:

article_previous = serializers.CharField()

ValueError:无法分配“'test_1'”:“Article.article_previous”必须是“Article”实例。

该解决方案提供:

article_previous = serializers.CharField('article.article_previous')

TypeError:Article() 得到了一个意外的关键字参数“文章”

如果我在views.py中使用 serializer.validated_data :

return Response(serializer.validated_data, status=status.HTTP_201_CREATED, headers=headers)
response = serializer.save()
return Response(response, status=status.HTTP_201_CREATED, headers=headers)

TypeError:Article 类型的对象不是 JSON 可序列化的。

您可以通过使用article_previous_id字段来序列化 slug:

class ArticleSerializer(serializers.ModelSerializer):
    article_previous = serializers.CharField(source='article_previous_id')

    class Meta:
        model = Article
        fields = ('heading', 'slug', 'article_previous')

    # …
class ArticleSerializer(serializers.ModelSerializer):

    article_previous=serializers.SlugRelatedField(queryset=Article.objects.all(), slug_field="slug")

    class Meta:
        model = Article
        fields = ('heading', 'slug', 'article_previous')

    def create(self, validated_data):
        article_previous=validated_data.pop("article_previous")
        article=Article.objects.create(**validated_data, article_previous=article_previous)
        validated_data.update( {"article_previous" : article.article_previous.slug} ) 
        return validated_data

我认为这个解决方案的优点是命名保持article_previous并且没有更改为article_previous_id

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM