Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从内存中的数据初始化属于ManyToManyField的对象_Python_Django - Fatal编程技术网

Python 从内存中的数据初始化属于ManyToManyField的对象

Python 从内存中的数据初始化属于ManyToManyField的对象,python,django,Python,Django,我正在使用数据库模型的实例,在这些实例中,我需要从内存中的数据构造对象(使用Python风格的o=object(),而不是ModelClass.objects.create()。数据是否会保存在数据库中,将在稍后使用调用o.save()时决定 这些模型有一个ManyToManyField并拥有许多子对象。问题是,在子对象实际保存之前,我无法add()到ManyToManyField。我如何以save()的方式构造这些对象可以稍后调用吗?我找到的解决此问题的所有可能的解决方案实际上并不能满足我的要

我正在使用数据库模型的实例,在这些实例中,我需要从内存中的数据构造对象(使用Python风格的
o=object()
,而不是
ModelClass.objects.create()
。数据是否会保存在数据库中,将在稍后使用调用
o.save()
时决定

这些模型有一个
ManyToManyField
并拥有许多子对象。问题是,在子对象实际保存之前,我无法
add()
ManyToManyField
。我如何以
save()的方式构造这些对象
可以稍后调用吗?我找到的解决此问题的所有可能的解决方案实际上并不能满足我的要求

下面是一些示例代码,显示了我正在尝试的操作:

类作者:
# ...
@类方法
def创建(cls、数据):
# ...
通过
教材(models.Model):
title=models.CharField(最大长度=128)
pages=models.PositiveIntegerField()
作者=模型。ManyToManyField(作者)
@类方法
@原子事务
def创建(cls、数据):
尝试:
使用transaction.atomic():
b=cls(标题=数据[“标题”],
页面=数据[“页面”])
#这是可行的,但有一个不必要的副作用:作者被保存到数据库中
#因为它们是在此处创建的,而书本未保存。
b、 authors=Author.objects.bulk_create([Author.create(a)for a in data[“authors”])
返回b
除例外情况外:
# ...
提升
###################后来。。。
#这个数据不是静态的——它是由来自API的JSON形成的。这里只是一个例子。
数据={
"标题":一,,
“页数”:934页,
“作者”:[
{
“姓名”:“约翰·史密斯”,
# ...
}
]
}
#我们现在要用这个,但我们不确定是否真的要保存
#将对象添加到数据库。
b=Book.create(数据)
#如果需要,请将数据保存到数据库中。
b、 保存()

我能想到的唯一解决方案是将操作排队,并在调用
save()
时执行它们

通过这种方式,您可以:

class Book(PostponedOpMixin):
    ...
    authors = models.ManyToManyField(Author)
    ...

instance = Book()
instance.title = "Romeo and Juliet"
instance.postpone('authors.add', shakespeare)
...

# and some time later:
instance.save()

此代码未经测试,仅作为起点。任何错误都留给读者作为练习。

也许您可以将实际书籍作者的添加推迟到您确定要将该书籍保存到数据库中的那一刻。
同时,可以为每个book对象存储已处理(但尚未保存)的author对象列表

class Book(models.Model):
    title = models.CharField(max_length=128)
    pages = models.PositiveIntegerField()
    authors = models.ManyToManyField(Author)

    @classmethod
    @transaction.atomic
    def create(cls, data):
        try:
            b = cls(title=data["title"],
                    pages=data["pages"])
            b.author_list = list()
            for a in data["authors"]:
                b.authors_list.append(Author.create(a))
            return b
        except Exception:
            # ...
            raise

然后,当您确定要保存该对象时,必须保存该列表中的所有作者,然后将其添加到相应图书对象的“作者”字段。

这些作者是否已经在数据库中?或者您是否像在初始运行时那样创建他们?像在初始运行时那样创建他们。我根本不希望他们出现在数据库中在这一点上。谢谢!如果没有其他人,我会认真考虑这个问题,并很快接受答案,谢谢!这一定是一个常见的习语,我不敢相信没有真正的解决办法。所以我有机会详细研究了这个问题,它肯定会起作用。我怀着感激的心情接受你的答案。我仍然觉得这是一种耻辱e不是更好的解决方案。此外,我很抱歉,我只能提供少量的赏金!您可能希望将其保留几天,没有公认答案的问题往往会得到更多的关注,有人可能会想出更好的解决方案。
class Book(models.Model):
    title = models.CharField(max_length=128)
    pages = models.PositiveIntegerField()
    authors = models.ManyToManyField(Author)

    @classmethod
    @transaction.atomic
    def create(cls, data):
        try:
            b = cls(title=data["title"],
                    pages=data["pages"])
            b.author_list = list()
            for a in data["authors"]:
                b.authors_list.append(Author.create(a))
            return b
        except Exception:
            # ...
            raise