我是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)
现在,我想使用剩下的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"]}]}
我已经被困了一段时间,任何帮助将是感激:)
首先,数据格式不是在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
您应该将.save()
放入循环并编辑您的查询如下:
def create(self, validated_data):
allergies_data =validated_data.pop('allergies', [])
user1=UserProfile.objects.create(**validated_data)
for allergy in allergies_data:
al=IngFamily.objects.get(name=allergy['name'])
user1.allergies.add(al)
#here you should add it
user1.save()
可以尝试以下方法:
- 这可能是你的数据库没有一些过敏与用户数据。这就是为什么你的al是空的。
- 在添加过敏症之前保存用户数据。这很重要。
- 通过使用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
使用如下格式:
class ProjectSerializer(serializers.ModelSerializer):
tag= serializers.StringRelatedField(many=True)
class Meta:
model = Song
fields = '__all__'
这里是一个参考文档- https://www.django-rest-framework.org/api-guide/relations/