【问题标题】:Django: Modify model object and save as newDjango:修改模型对象并另存为新
【发布时间】:2015-09-08 16:31:36
【问题描述】:

我的问题和这个问题很相似:How to modify a queryset and save it as new objects?

假设我的模型有以下字段:

class myModel(models.Model):
    articleId = models.ForeignKey(otherModel)
    myCounter = models.IntegerField

现在,假设 articleId 保持不变,我想通过改变 myCounter 来保存多行。这就是我想要做的:

for x in range(1, 5):
    m = myModel()
    m.articleId = otherModel.objects.get(pid="some constant")
    m.myCounter = x
    m.save()
    m.id = None

根据上述帖子(以及其他类似帖子)的建议,我尝试将“id”和“pk”都设置为无。但没有任何帮助。

此代码仅在数据库中写入一行,并正在更新 myCounter 的值。如何提交 4 个不同的行?

【问题讨论】:

  • karthikr 回答下面的作品!!但我想知道是否有更符合上述 for 循环并为每次迭代重新创建一个新对象的解决方案?

标签: django


【解决方案1】:

你可以使用bulk_create for this:

an_article_object = otherModel.objects.create(name="Some Constant")
myModel.objects.bulk_create([
    myModel(articleId=an_article_object, myCounter=x) for x in range(1, 5)
])

编辑:

循环解决您的问题:

article = otherModel.objects.create(name="SomeConst")
#or fetch the article object

m = myModel(articleId = article)

for x in range(1, 5):
    m.myCounter = x
    m.pk = None
    m.save()

【讨论】:

  • 我试过了,但不幸的是,即使这样也行不通。我仍然只有一排。您认为 articleId 作为外键会导致问题吗?
  • 不,不应该是这样。在bulk_create 之前和之后执行print myModel.objects.count(),看看创建了多少对象。
  • 但我想知道是否有更符合上述 for 循环并为每次迭代重新创建一个新对象的解决方案?
  • 当然,检查编辑。但是,bulk_create 将执行 1 次数据库写入,而不是 for 循环中的 n
  • 这就是我最初的问题。做 m.pk=None 没有用。我认为这正是他们在链接的 SO 问题中讨论的内容。
【解决方案2】:

型号 -

    myCounter = models.AutoField(primary_key=True)
    #myCounter = models.AutoField(primary_key=False)

    #you use primary_key = True if you do not want to use default field "id" given by django to your model

代码 -

  for x in range(1, 5):
    m = myModel()
    m.articleId = "some constant"
    m.save()

【讨论】:

  • myCounter 在我的设计中不是(也不能是)主键。
  • 那就让它为假吧。
  • 视情况而定,如果系统是新的,你可以这样做。更好的数据库。
【解决方案3】:

如果您想更改相同的object,您可以试试这个:

m = myModel()
for x in range(1, 5):
    m.articleId = otherModel.objects.get(pid="some constant")
    m.myCounter = x
    m.save()

【讨论】:

  • 它与我所做的有什么不同?您没有制作 id = None?即使这样也无济于事。
  • 为什么要设置id=None是不可能的。这是不同的,因为您将在for 中使用sabe 对象m,不管m.id 的值,您将拥有相同的object 来使用它。
  • 是的,因为我有相同的对象,所以只有一行被(覆盖)写入。我想要 4 个不同的行。
  • 如果你想改变同一个对象,你可以试试这个:这就是我说的。对不起,如果它没有帮助。但是请告诉我,您为什么需要(或者您认为)将 id 值设置为 None?
  • 好吧,我尝试了不同的解决方案。有人建议做 id=None 和 force_insert = True 会创建多个对象。我想我现在会接受karthikr的回答。非常感谢您的帮助。
【解决方案4】:

您可以使用force_insert 参数来强制使用INSERT 语句。如果插入失败,这将引发错误,但不会静默更新现有对象。

m.save(force_insert=True)

【讨论】:

  • 只有一行被(覆盖)写入。
  • @TheWanderer 如果您使用force_insert=True,则不可能使用UPDATE 语句。但是,根据您提供的代码,我无法告诉您出了什么问题。
  • 感谢 knbk 的帮助和时间。从现在开始,我将使用 karthikr 解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-24
  • 2013-04-15
  • 2014-04-18
  • 2022-10-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多