Django模型的空PK反序列化

Django模型的空PK反序列化,django,serialization,Django,Serialization,我已经序列化了我的django模型: serializers.serialize(MyModel.objects.filter(color="Red")) 得到了这个输出: <object model="example.example" pk="133"> <field name="name" type="CharField">John Smith</field> <field name="color" type="CharField"

我已经序列化了我的django模型:

serializers.serialize(MyModel.objects.filter(color="Red"))
得到了这个输出:

<object model="example.example" pk="133">
    <field name="name" type="CharField">John Smith</field>
    <field name="color" type="CharField">Red</field>
    ... #more fields
</object>
(实际上是0.96,但我认为它应该适用于1。*同样)

因此,在JSON中,pk可以为null,但在XML中会出现问题。如何将XML的pk设置为null


谢谢

看起来像Django中的bug。无法为XML序列化对象提供空(或null/None)“pk”

来自django/core/serializers/xml_serializer.py:

class Deserializer(base.Deserializer):
    ...
    def _handle_object(self, node):
    ...
        pk = node.getAttribute("pk")
        if not pk:
            raise base.DeserializationError("<object> node is missing the 'pk' attribute")

        data = {Model._meta.pk.attname : Model._meta.pk.to_python(pk)}
    ...
如果pk不是整数,则也是异常

看起来没有办法提供空pk

解决办法可以是:

  • 从MyModel获取最大id
  • id+=1
  • 使用新id在我的xml中设置“pk”
  • 反序列化为模型
  • 保存()
  • 这有点棘手,因为在步骤1-5中,表应该被锁定。。以某种方式只是为了避免身份冲突

    编辑:

    解决办法是:

  • Set pk=“999999”(某些临时整数值)
  • 在迭代过程中,将id和pk设置为None,然后保存()

    mymodels\u迭代器=序列化器。反序列化(“xml”,已修复\u pk\u序列化的\u xml\u模型)

    对于mymodels\u迭代器中的mymodel:

    mymodel.object.id = None
    mymodel.object.pk = None
    mymodel.save()
    
  • 而且它有效


    多亏了Evgeny对clone()方法的评论。

    这只是一个想法——如果解析器正在验证,那么它就不会让您设置无效值,比如空值。还有-主键是否自动递增?如果是,那么您可能不想手动设置它们,我会创建一个类似clone()的方法,或者寻找这样的方法……是的,这是django中的一个bug,请参阅
    class AutoField(Field):
        ...
        def to_python(self, value):
            if value is None:
                return value
            try:
                return int(value)
            except (TypeError, ValueError):
                raise exceptions.ValidationError(
                    _("This value must be an integer."))
        ...
    
    mymodel.object.id = None
    mymodel.object.pk = None
    mymodel.save()