【问题标题】:Trouble posting to many-to-many field发布到多对多字段时遇到问题
【发布时间】:2022-02-09 01:48:07
【问题描述】:

我正在尝试发布一个组合对象,它指的是已经存在的标签对象。基本上我希望组合的 tag_id 字段包含 2 个引用 Tag 对象的 id。

这是我的代码:

models.py

class Combination(models.Model):
    user = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True)
    gameround = models.ForeignKey(Gameround, on_delete=models.CASCADE, null=True)
    resource = models.ForeignKey(Resource, on_delete=models.CASCADE, null=True)
    tag_id = models.ManyToManyField(Tag, null=True)
    created = models.DateTimeField(editable=False)
    score = models.PositiveIntegerField(default=0)

    objects = models.Manager()

    def __str__(self):
        return str(self.tag_id) or ''

serializers.py

class CombinationSerializer(serializers.ModelSerializer):
  tag_id = TagWithIdSerializer(many=True, required=False)
  resource_id = serializers.PrimaryKeyRelatedField(queryset=Resource.objects.all(),
                                                   required=True,
                                                   source='resource',
                                                   write_only=False)
  gameround_id = serializers.PrimaryKeyRelatedField(queryset=Gameround.objects.all(),
                                                    required=False,
                                                    source='gameround',
                                                    write_only=False)
  user_id = serializers.PrimaryKeyRelatedField(queryset=CustomUser.objects.all(),
                                               required=False,
                                               source='user',
                                               write_only=False)

  class Meta:
    model = Combination
    depth = 1
    fields = ('id', 'user_id', 'gameround_id', 'resource_id', 'tag_id', 'created', 'score')

  def create(self, validated_data):
    user = None
    request = self.context.get("request")
    if request and hasattr(request, "user"):
      user = request.user

    score = 0

    tag_data = validated_data.pop('tag_id')

    combination = Combination(
      user=user,
      gameround=validated_data.get("gameround"),
      resource=validated_data.get("resource"),
      created=datetime.now(),
      score=score
    )
    for tag_object in tag_data:
      combination.set(tag_id=tag_object)
    if len(combination.tag_id) == 2:
      return combination

  def to_representation(self, instance):
    rep = super().to_representation(instance)
    rep['tag_id'] = TagWithIdSerializer(instance.tag_id.all(), many=True).data
    return rep

有了这个我目前得到一个 AttributeError :'Combination'对象没有属性'set'

如果我更新这个:

for tag_object in tag_data:
      combination.set(tag_id=tag_object)

像这样:

    combination.save()
    for tag_object in tag_data:
      combination.tag_id.add(tag_object)

我现在收到错误字段 'id' expected a number but got OrderedDict([('name', 'word'), ('language', 'en')])。

如果我添加:

    combination.save()
    for tag_object in tag_data[0]:
      combination.tag_id.add(tag_object)

我得到 ValueError 字段 'id' 需要一个数字,但得到了 'name'。

我怎样才能摆脱这个?

【问题讨论】:

    标签: django django-models django-rest-framework


    【解决方案1】:

    为了在 Django 的 ManyToMany 字段中设置对象,您必须先保存该对象。像这样

    combination.save()
    
    for tag_object in tag_data:
        combination.tag_id.add(tab_object)    
    

    【讨论】:

    • 这解决了之前的问题。谢谢你!但是,现在我收到错误消息:字段“id”期望一个数字但得到了 OrderedDict
    • 好吧,我相信它是因为 tag_data = valid_data.pop('tag_id') 如果我没记错的话 .pop 返回一个字典。尝试使用类似 tag_data[0] 的东西。就像 tag_data[0] 中的 tag_object 一样:
    • 我现在已经尝试过了,我收到错误字段 'id' expected a number but got 'name'。
    • 什么是 tag_data[0] 返回?可能与标签序列化器有关。对于创建,您不需要传递此标签对象的序列化程序。尝试在您的字段中直接调用“tag_id”。
    • 我认为它在我传递的 json 中看不到 id,它只是出于某种原因传递了标记对象的名称和语言。直接在字段中调用是什么意思?
    猜你喜欢
    • 1970-01-01
    • 2018-02-26
    • 2014-05-16
    • 2021-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-04
    相关资源
    最近更新 更多