如何更新Django 的ManyToMany 字段

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何更新Django 的ManyToMany 字段相关的知识,希望对你有一定的参考价值。

更新Django 的ManyToMany 字段:
1、在创建一个新的的时候:
p1=Post.objects.create(title=title,content=content,pub_date=pub_date,author=author)
p1.label.add(p)
其中label是ManyToMany 字段。
2、更新的时候:
p1=Post.objects.filter(id=num).save(title=title,content=content,pub_date=pub_date,author=author)
3、如果此时误用update,则成了批量更新,会发生错误。
参考技术A 更新Django 的ManyToMany 字段:
1、在创建一个新的的时候:
p1=Post.objects.create(title=title,content=content,pub_date=pub_date,author=author)
p1.label.add(p)
其中label是ManyToMany 字段。
2、更新的时候:
p1=Post.objects.filter(id=num).save(title=title,content=content,pub_date=pub_date,author=author)
3、如果此时误用update,则成了批量更新,会发生错误。
参考技术B 在创建一个新的的时候p1=Post.objects.create(title=title,content=content,pub_date=pub_date,author=author)p1.label.add(p)这里是没问题的其中label是ManyToMany 字段然后更新的时候p1=Post.objects.filter(id=num).update(title=title,content=content,pub_date=pub_date,author=author)就不好使了 求教~本回答被提问者采纳

如何使用 Django Rest Framework 向 ManyToMany 字段添加数据?

【中文标题】如何使用 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 的ManyToMany 字段的主要内容,如果未能解决你的问题,请参考以下文章

如何在django中查询具有manytomany字段指向它们的对象

如何在模板上显示 Django ManyToMany?需要简单的代码

如何使 ManyToMany 字段的值显示在 Django 通用 DeleteView 中

django manytomany 字段使用 through 和 formwizard

Django ORM - 模型引用另一个模型ManyToMany字段

Django 中的 OneToOne、ManyToMany 和 ForeignKey 字段有啥区别?