[英]Post request Manytomany field DRF with postman
目标:使用“POST”从 Postman 在数据库中创建一个新条目。
我正在尝试从 Postman 发送数据,并且我正在使用嵌套序列化。 我已经更改了创建方法,我在下面共享了代码段。 另外,我尝试了这个解决方案,但没有奏效。 有人可以指出我犯的错误吗?
当我尝试作为表单数据发布时,错误是{"magazine":["This field is required."]}
。 当我尝试将其作为原始数据发布时,错误Direct assignment to the forward side of a many-to-many set is prohibited. Use magazine.set() instead.
Direct assignment to the forward side of a many-to-many set is prohibited. Use magazine.set() instead.
这是我的模型:
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
author = models.ForeignKey('authors.Author', on_delete=models.CASCADE)
magazine = models.ManyToManyField('articles.Magazine')
def __str__(self):
return self.title
class Magazine(models.Model):
name = models.CharField(max_length=30)
title = models.CharField(max_length=100)
def __str__(self):
return self.name
这是我的序列化程序:
class MagazineSerializer(serializers.ModelSerializer):
class Meta:
model = Magazine
fields = '__all__'
class ArticleSerializer(serializers.ModelSerializer):
author = AuthorSerializer(read_only=True, many=False)
magazine = MagazineSerializer(many=True)
class Meta:
model = Article
fields = [
'title',
'content',
'author',
'magazine',
]
def create(self, validated_data):
allmags = []
magazine = validated_data.pop('magazine')
for i in magazine:
if Magazine.objects.get(id=magazine["id"]).exists():
mags = Magazine.objects.get(id=magazine["id"])
allmags.append(mags)
else:
return Response({"Error": "No such magazine exists"}, status=status.HTTP_400_BAD_REQUEST)
validated_data['author'] = self.context['request'].user
validated_data['magazine'] = allmags
return Article.objects.create(**validated_data)
这是我的看法:
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
class MagazineViewSet(viewsets.ModelViewSet):
queryset = Magazine.objects.all()
serializer_class = MagazineSerializer
serializer_action_class = {
'get_articles': MagazineSerializer,
}
@action(detail=True, url_path='articles', url_name='articles')
def get_articles(self, request, pk=None):
articles = Article.objects.filter(magazine=self.kwargs.get('pk'))
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data, status=200)
这就是我尝试将数据作为原始数据发送的方式:
{
"title": "New Post form Postman",
"content": "Postman content new",
"magazine": [
{
"id": 1,
"name": "The Times",
"title": "All News"
}
]
}
首先,您能否澄清一下您是否还希望从嵌套序列化程序创建新的Magazine
对象,或者您是否希望用户只能为现有杂志创建Article
(这似乎是第二个,因为您正在调用.exists()
) ?
如果您要进行第一种情况,您还希望在同一个POST
请求中创建新杂志,我建议使用drf-writeable-nested package。
为此,您也应该使用drf-writeable-nested package。 或者,您可以改用此hack :
from rest_framework.exceptions import ValidationError
from rest_framework import serializers
from .models import Article, Magazine
class ArticleSerializer(serializers.ModelSerializer):
author = AuthorSerializer(read_only=True, many=False)
magazines = MagazineSerializer(many=True, read_only=True)
# accept list of PKs
magazines_ids = serializers.PrimaryKeyRelatedField(
many=True, write_only=True, queryset=Magazine.objects.all()
)
class Meta:
model = Article
fields = [
'title',
'content',
'author',
'magazines',
'magazines_ids',
]
def create(self, validated_data):
magazines = validated_data.pop("magazines_ids", None)
validated_data["author"] = self.context["request"].user
article = Article.objects.create(**validated_data)
if magazines:
article.magazine.set(magazines)
return article
现在您的POST
请求JSON
正文应如下所示:
{
"title": "New Post form Postman",
"content": "Postman content new",
"magazines_ids": [1]
}
magazines
参数获取主键列表的位置。
另外,出于我的好奇,您确定要使用ManytoManyField
吗? 我会假设一篇Article
只能属于您应该使用ForeignKey
的单个Magazine
,例如:
magazine = models.ForeignKey("articles.Magazine", related_name="articles")
然后在您的“动作”中,您可以进行以下更改:
@action(detail=True, url_path='articles', url_name='articles')
def get_articles(self, request, pk=None):
articles = self.get_object().articles
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data, status=200)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.