如何使用 Django Rest Framework 向 ManyToMany 字段添加数据?
Posted
技术标签:
【中文标题】如何使用 Django Rest Framework 向 ManyToMany 字段添加数据?【英文标题】:How to add data to ManyToMany field using Django Rest Framework? 【发布时间】:2015-08-13 18:37:17 【问题描述】:我对 DJango 比较陌生,我希望使用来自 rest 框架的序列化程序将数据添加到多对多字段。
我的模特:
class IngFamily(models.Model):
name=models.CharField(max_length=30, unique=True, verbose_name='ingredient parent')
class UserProfile(models.Model):
user=models.ForeignKey(User)
allergies=models.ManyToManyField(IngFamily, verbose_name='allergies', null=True)
现在,我想使用 rest api 将数据添加到 UserProfile 模型。
我环顾四周,但在任何地方都找不到很多东西。
到目前为止我所取得的成就:
序列化器:
class IngFlySerializer(serializers.ModelSerializer):
class Meta:
model = IngFamily
fields= ('name',)
class UserProfileSerializer(serializers.ModelSerializer):
allergies=IngFlySerializer(many=True,)
class Meta:
model = UserProfile
fields=('allergies',)
def create(self, validated_data):
allergies_data =validated_data.pop('allergies', [])
#import pdb;pdb.set_trace()
user1=UserProfile.objects.create(**validated_data)
for allergy in allergies_data:
al=IngFamily.objects.filter(name=allergy.get('name'))
#al.name=allergy.get('name')
user1.allergies.add(al)
user1.save()
return user1
当我尝试使用它时,“al”为空。
查看:
class user_profile(generics.ListCreateAPIView):
serializer_class = UserProfileSerializer
permission_classes = (permissions.IsAuthenticated,)
def get_queryset(self):
user = self.request.user
return UserProfile.objects.filter(user=user)
def perform_create(self, serializer):
#import pdb; pdb.set_trace()
serializer.save(user=self.request.user)
class UserDetail(generics.RetrieveDestroyAPIView):
serializer_class = UserProfileSerializer
permission_classes = (permissions.IsAuthenticated,)
def get_queryset(self):
user1 = self.request.user
return UserProfile.objects.filter(user=user1)
我的 Post 请求如下所示:
"allergies": ["name": ["Beef"],"name": ["Pork"]]
我已经被困了一段时间,任何帮助将不胜感激:)
【问题讨论】:
尝试以下操作:在 UserProfileSerializer 的 create 方法中,在 for 循环之前,显式保存 user1 -> user1.save() 这能回答你的问题吗? How to add data to nested serializers? 【参考方案1】:可以尝试几件事:
-
您的数据库可能没有一些与用户数据一起出现的过敏。这就是为什么你的人是空的。
在添加过敏之前保存用户数据。这个很重要。
通过使用 ipdb 或 pdb,尝试了解 'allergy' 和 'allergies_data' 以什么数据形式出现。如果确实是您编写的内容,则以下代码没有理由不起作用。
def create(self, validated_data):
allergies_data =validated_data.pop('allergies')
user1=UserProfile.objects.create(**validated_data)
user1.save()
for allergy in allergies_data:
al=IngFamily.objects.get_or_create(name=allergy['name'])
user1.allergies.add(al)
return user1
【讨论】:
【参考方案2】:首先,post请求中的数据格式不对:
应该是这样的:
"allergies": ["name": "Beef","name": "Pork"]
现在让我们在你的序列化器中修改你的def create()
def create(self, validated_data):
allergies_data =validated_data.pop('allergies', [])
names = [allergy.get('name') for allergy in allergies_data if allergy]
al = IngFamily.objects.filter(name__in=names) # using names(list) for filtering by __in
user1 = UserProfile.objects.create(**validated_data)
user1.allergies.add(*al) # notice there have * before "al" (as we are putting list inside add()
# user1.save() # we don't need to call `save()` as we are updating ManyToMany field.
return user1
【讨论】:
以上是关于如何使用 Django Rest Framework 向 ManyToMany 字段添加数据?的主要内容,如果未能解决你的问题,请参考以下文章
django.test.client 上的 Django rest 框架导入错误
无法使用 Django Rest 框架发送压缩的 gzip 数据
Django REST to React - 无需密码即可获取社交身份验证令牌
尽管有 AllowAny 权限,django-rest-framework 在 POST、PUT、DELETE 上返回 403 响应