Django REST Framework序列化程序 - 访问现有的外键

时间:2017-12-26 05:11:50

标签: python django django-rest-framework foreign-keys

我在我的应用中使用Django Rest Framework,我需要创建包含外键的新模型实例。这些引用另一个表中的现有对象,因此我不希望创建这些外来对象的新实例。此外,我无法通过主键访问这些对象,因为该信息未提交(我需要过滤POST请求中包含 的某些字段。)

我该怎么做? This问题似乎解决了同样的问题,但我不清楚接受的答案是否真正解决了问题。假设我有两个模型,CategoryItem,后者的ForeignKey字段指定了类别:

class Category(models.Model):
    name = models.TextField()
    format = models.TextField()
    page = models.IntegerField(default=1)
    order = models.IntegerField(default=1)

class Item(models.Model):
    username = models.TextField()
    title = models.TextField()
    category = models.ForeignKey('Category', null=True)
    data = JSONField(null=True, blank=True)

POST请求的正文由JSON有效负载组成,类别定义为指定格式,页面和顺序字段的对象:

POST /api/items
{
  "username" : "test",
  "title" : "foo",
  "category" : {
    "format" : "A",
    "page" : 2,
    "order" : 1
  },
  "data" : [1,2,3,4,5]
}

然后我想我可以按如下方式定义我的Item序列化程序,覆盖create,以便通过过滤相应的字段并将其设置为返回来检索正确的Category实例Item实例:

class ItemSerializer(serializers.ModelSerializer):
    category = CategorySerializer()
    data = serializers.ListField()

    class Meta:
        model = Item
        fields = ('username', 'title', 'category', 'data')

    def create(self, validated_data):
        category_dict = validated_data.pop('category')
        item = Item.objects.create(**validated_data)
        format = category_dict.format
        page = category_dict.page
        order = category_dict.order
        item.category = Category.objects.get(format=format, page=page, order=order)
        return item

这是正确的方法吗?

2 个答案:

答案 0 :(得分:2)

就像

{{1}}

答案 1 :(得分:1)

至少有一个错误,您应该使用get来获取项目类别中的一个类别,而不是使用filter来获取queryset

class ItemSerializer(serializers.ModelSerializer):
    category = CategorySerializer()
    data = serializers.ListField()

    class Meta:
        model = Item
        fields = ('username', 'title', 'category', 'data')

    def create(self, validated_data):
        category_dict = validated_data.pop('category')
        item = Item.objects.create(**validated_data)
        format = category_dict.format
        page = category_dict.page
        order = category_dict.order
        try:
            item.category = Category.objects.get(format=format, page=page, order=order)
        except  Category.DoesNotExist:
            pass
        except  Category.MultipleObjectsReturned:
            pass
        return item