【问题标题】:django restframework _ OneToOne field save()django rest框架_一对一字段save()
【发布时间】:2017-12-30 10:17:48
【问题描述】:

我的项目中有两个模型。模型 A 和 B。模型 B 与模型 A 具有“OneToOne”关系。我为模型 B 编写了一个序列化程序类。在“.create()”函数中我在保存模型 B 时遇到问题,因为我需要覆盖保存B 模型中的 () 函数用于插入 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()

序列化器.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

【问题讨论】:

  • 您没有正确复制/粘贴 + 修改您的代码(请参阅语法突出显示)。

标签: django django-rest-framework


【解决方案1】:

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

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

【讨论】:

  • tnx 问题已解决,但新问题是:错误绑定参数 0 - 可能是不受支持的类型。 /env/lib/python3.5/site-packages/django/db/backends/sqlite3/operations.py 在 _quote_params_for_last_executed_query,第 125 行。A.objects.update_or_create(ad_info=info_data, **info_data) @danielRoseman
【解决方案2】:

那么您的问题是您正在尝试制作模型 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 是这个问题的关键。

【讨论】:

    【解决方案3】:

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

    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
    

    【讨论】:

    • 我按照你说的修改了代码。现在我从数据库中得到完整性错误:唯一约束失败:store_b.slug
    • 我认为我制作的 slug 字段正在数据库中复制
    • 我进行了硬刷新并发出了另一个请求。我再次收到此错误:错误绑定参数 3 - 可能不受支持的类型。 .为什么我认为我的结构是错误的?我的意思是这是在 django restframework 中创建 OneToOne 关系的正确方法吗?
    • 有什么想法吗?我自己处理不了
    猜你喜欢
    • 2015-10-30
    • 2018-08-09
    • 2017-08-07
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    • 2017-06-25
    • 2018-10-14
    • 1970-01-01
    相关资源
    最近更新 更多