gpt4 book ai didi

python - 使用 Django rest 更新 ManyToMany 字段

转载 作者:太空狗 更新时间:2023-10-30 02:17:31 32 4
gpt4 key购买 nike

我正在尝试设置此 API,以便我可以使用“PUT”来更新模型“MOVIE”中的项目的一个/多个“TAG”。 Tags 是 MOVIE 上的 M2M。我发的是电影中元素的PK。

我的 httpie 工作(返回 200OK)但没有创建任何东西。当我发布整个 JSON(使用 fetch)时,它只会创建 TAG,但不会在 MOVIE ( link) 上创建 M2M 关系。

httpie

http -f PUT http://localhost:8000/api/Edit/3/ tag:='{"name": "TEST"}'

模型.py

class Tag(models.Model):
name = models.CharField("Name", max_length=5000, blank=True)
taglevel = models.IntegerField("Tag level", null=True, blank=True)

class Movie(models.Model):
title = models.CharField("Whats happening?", max_length=10000, blank=True)
tag = models.ManyToManyField('Tag', blank=True)

序列化器.py

class Tag1Serializer(serializers.ModelSerializer):
class Meta:
model = Tag
fields = ('name',)

class EditSerializer(serializers.ModelSerializer):
tag = Tag1Serializer(many=True, read_only=True)
class Meta:
model = Movie
fields = ('title', 'tag', 'info', 'created', 'status')

def update(self, instance, validated_data):
import pdb; pdb.set_trace()
tags_data = validated_data.pop('tag')
for tag_data in tags_data:
tag_qs = Tag.objects.filter(name__iexact=tag_data['name'])
if tag_qs.exists():
tag = tag_qs.first()
else:
tag = Tag.objects.get(**tag_data)
instance.tag.add(tag)
return movie

View .py

class MovieViewSet(viewsets.ModelViewSet):
queryset = Movie.objects.all()
serializer_class = MovieSerializer

错误:

Traceback
tags_data = validated_data.pop('tag')
KeyError: 'tag'

最佳答案

在 drf 模型序列化器类上没有 put 方法,所以没有调用 put(self, validated_data)。使用:update(self, instance, validated_data) 代替。关于保存实例的文档:http://www.django-rest-framework.org/api-guide/serializers/#saving-instances

django 模型查询集也没有:Movie.objects.putTag.objects.put。您已经有了电影的 instance 参数,如果您正在查询标签,您可能需要 Tag.objects.getTag.objects.filter ?查询集 API 引用:https://docs.djangoproject.com/en/1.10/ref/models/querysets/#queryset-api

在验证序列化器方法被调用后,也许您应该使用 drf test api 客户端为其编写测试以便能够轻松发现错误:http://www.django-rest-framework.org/api-guide/testing/#apiclient

序列化器.py

class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tag
fields = ('name', 'taglevel', 'id')


class MovieSerializer(serializers.ModelSerializer):
tag = TagSerializer(many=True, read_only=False)

class Meta:
model = Movie
ordering = ('-created',)
fields = ('title', 'pk', 'tag')

def update(self, instance, validated_data):
tags_data = validated_data.pop('tag')
instance = super(MovieSerializer, self).update(instance, validated_data)

for tag_data in tags_data:
tag_qs = Tag.objects.filter(name__iexact=tag_data['name'])

if tag_qs.exists():
tag = tag_qs.first()
else:
tag = Tag.objects.create(**tag_data)

instance.tag.add(tag)

return instance

测试.py

class TestMovies(TestCase):
def test_movies(self):
movie = Movie.objects.create(title='original title')

client = APIClient()
response = client.put('/movies/{}/'.format(movie.id), {
'title': 'TEST title',
'tag': [
{'name': 'Test item', 'taglevel': 1}
]
}, format='json')

self.assertEqual(response.status_code, 200, response.content)
# ...add more specific asserts

关于python - 使用 Django rest 更新 ManyToMany 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40143267/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com