簡體   English   中英

如何使用 Django Rest 框架向多對多字段添加數據?

[英]How to add data to ManyToMany field using Django Rest Framework?

我對 DJango 比較陌生,我希望使用 rest 框架中的序列化程序將數據添加到多對多字段。

我的 Model:

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 model。

我環顧四周,但找不到很多地方。

到目前為止,我所取得的成就:

序列化器:

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"]}]}

我已經堅持了一段時間,任何幫助將不勝感激:)

可以嘗試幾件事:

  1. 您的數據庫可能可能沒有用戶數據中的某些過敏症。 這就是為什么你的al會變空。
  2. 在添加過敏症之前保存用戶數據。 這個很重要。
  3. 通過使用ipdb或pdb,嘗試了解'過敏'和'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

首先,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

使用類似的東西:

class ProjectSerializer(serializers.ModelSerializer):

    tag= serializers.StringRelatedField(many=True)

    class Meta:
       model = Song
       fields = '__all__'

這是一個參考文檔 - https://www.django-rest-framework.org/api-guide/relations/

您應該在循環中使用 but.save() 並將您的查詢編輯為:

定義創建(自我,驗證數據):

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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM