我有一個與某些資源對象具有M2M關係的故事模型。某些Resource對象缺少名稱,所以我想將Story的標題複製到指定的Resource對象。Django保存隨機行爲
這裏是我的代碼:
from collector import models
from django.core.paginator import Paginator
paginator = Paginator(models.Story.objects.all(), 1000)
def fix_issues():
for page in range(1, paginator.num_pages + 1):
for story in paginator.page(page).object_list:
name_story = story.title
for r in story.resources.select_subclasses():
if r.name != name_story:
r.name = name_story
r.save()
if len(r.name) == 0:
print("Something went wrong: " + name_story)
print("done processing page %s out of %s" % (page, paginator.num_pages))
fix_issues()
我需要,因爲我處理一百萬對象使用分頁程序。奇怪的是,在調用fix_issues()後,大約一半的資源沒有名字,現在有了正確的名字,而另一半沒有名字。我可以一次又一次地調用fix_issues(),每次有更多的對象接收到一個名字。這對我來說似乎很奇怪,爲什麼一個對象不是第一次更新,而是第二次更新?
其他信息:
- 的 「出事了」 的消息是從未打印。
- 我使用django-model-utils的select_subclasses遍歷所有資源(任何類型)。
- story.title是從來沒有空。
- 當我運行這些命令時,不會打印錯誤消息。
- 我沒有重寫資源模型的保存方法(只有故事模型的保存方法)。
- 我試圖使用@ transaction.atomic,但結果是一樣的。
我的模型:
class Resource(models.Model):
name = models.CharField(max_length=200)
# Important for retrieving the correct subtype.
objects = InheritanceManager()
def __str__(self):
return str(self.name)
class CustomResource(Resource):
homepage = models.CharField(max_length=3000, default="", blank=True, null=True)
class Story(models.Model):
url = models.URLField(max_length=3000)
resources = models.ManyToManyField(Resource)
popularity = models.FloatField()
def _update_popularity(self):
self.popularity = 3
def save(self, *args, **kwargs):
super(Story, self).save(*args, **kwargs)
self._update_popularity()
super(Story, self).save(*args, **kwargs)
文檔爲select_subclasses: http://django-model-utils.readthedocs.io/en/latest/managers.html#inheritancemanager
進一步調查: 我想,也許select_subclasses沒有返回的所有對象。現在每個故事都有一個資源。所以很容易檢查select_subclasses總是返回一個項目。這是我使用的功能:
def find_issues():
for page in range(1, paginator.num_pages + 1):
for story in paginator.page(page).object_list:
assert(len(story.resources.select_subclasses()) == 1)
print("done processing page %s out of %s" % (page, paginator.num_pages))
但是,這一次執行沒有任何問題。所以我不會責備select_subclasses。我還檢查了paginator.num_pages是否正確。如果我除以1000(每頁項目數),我就可以得到我的數據庫中的故事數量。
您需要顯示模型的更多細節。 Story是否定義了任何默認排序? 'select_subclasses'有什麼作用?無論如何,分頁器並不是真正的正確工具。你可能想調查queryset ['iterator()'](https://docs.djangoproject.com/en/1.10/ref/models/querysets/#iterator)方法。除了別的之外,可能有更高效的方式來做這件事,例如通過'update()'。 –
我添加了更多的代碼和一個鏈接到我正在使用的庫。尋找解決方法對我來說並不重要,我寧願明白爲什麼這種方法會失敗。但感謝提示,將更新()。 – user667804
我並不是說這是問題(或問題)的100%,但是從代碼中跳轉出來的一件事是在覆蓋保存方法中調用'super()。save()'兩次。你用同樣的參數和kwargs來做,所以如果第一個'save()'從那些彈出,那麼你再次用新的參數調用save。糟糕的策略無論哪種方式,我建議你只調用一次 - 在更新人氣之前或之後。另外,如果你不熟悉它,那麼M2M關係不會保存在'save()'方法中,但是另外一個單獨的方法可以在Django文檔中找到它。 – makaveli