django restframework _ OneToOne字段save()

时间:2017-12-30 10:17:49

标签: django django-rest-framework

我的项目中有两个模型。模型A和模型B.模型B有一个' OneToOne'与模型A的关系。我在" .create()"中为模型B编写了一个序列化器类。函数我在保存模型B时遇到问题,因为我需要覆盖B模型中的save()函数以插入Slug值。错误是:

  

save()得到了一个意外的关键字参数' force_insert'

class A(models.Model):
    address = models.Charfield(max_length=160)

class b(models.Model):
    a = models.OneToOneField(AdIfo, related_name='ad_info', primary_key=True,
                             on_delete=models.CASCADE)
    slug = models.SlugField(unique=True, db_index=True, blank=True)

    def save(self):
        self.slug ="%d%s" %(self.pk, slugify(self.title))
        super(B, self).save()

serializers.py

class ASerializer(serializers.ModelSerializer):

    class Meta:
        model = A
        fields = "__all__"


class BSerilizer(serializers.ModelSerializer):
    a = ASerializer(many=False, required=False, allow_null=True)
    slug = serializers.SlugField(read_only=True)

     class Meta:
        model = B
        fields = '__all__'

    def create(self, validated_data):
        info_data = validated_data.pop('ad_info')
        A.objects.create(**info_data)
        ad = B.objects.update_or_create(**validated_data)
        A.objects.update_or_create(ad_info=adgame, **info_data)
        ad.save()
        return ad

3 个答案:

答案 0 :(得分:2)

问题是你没有接受B的save方法中的默认参数。通常,在重写方法时,您需要确保接受可以传递的所有参数,并确保将它们传递给超类方法。一种方法是使用*args, **kwargs

def save(self, *args, **kwargs):
    self.slug ="%d%s" % (self.pk, slugify(self.title))
    super(B, self).save(*args, **kwargs)

答案 1 :(得分:1)

完成@Daniel Roseman的修复后,您认为应该使用validated_data实例的新实例更新A

def create(self, validated_data):
    info_data = validated_data.pop('ad_info')
    # Next two rows
    a = A.objects.create(**info_data)
    validated_data.update({'a': a})
    ad = B.objects.update_or_create(**validated_data)
    A.objects.update_or_create(ad_info=adgame, **info_data)
    ad.save()
    return ad

答案 2 :(得分:1)

那么你的问题是你正在尝试制作模型A和模型B.然后模型B依赖于模型A的主键。你所做的这个结构是制作模型A而且模型B没有关联然后你就是再次创建模型A. 你只需要创建模型A然后模型B,但是你应该将模型B id引用到模型A.我知道它令人困惑但是试试这个:

def create(self, validated_data):
    info_data = validated_data.pop('ad_info')
    info = A.objects.create(**info_data)
    ad = B.objects.create(pk=info.id, **validated_data)
    return ad
  

pk = info.id是此问题的关键。