该行为与下面立即呈现的问题无关。请参阅帖子底部的说明。谢谢。
你好,
我目前遇到的行为是,特定模型的默认管理器在每个请求或每个 shell 会话中只返回一次该模型的对象。下面是在视图中停止的 PDB 记录(但在没有 PDB 的情况下也会发生这种行为):
#Nothing up my sleeves (using the default Manager):
(Pdb) p Entry.objects
<django.db.models.manager.Manager object at 0x18523b0>
#Now you see them...
(Pdb) Entry.objects.all()
[<Entry: Entry 1>, <Entry: Entry 2>, <Entry: Entry 3>, <Entry: Entry 4]
#Now you don't!
(Pdb) Entry.objects.all()
[]
每当我检索一个对象时,该对象就不再出现在以后的 QuerySet 中。
#(New Request from above)
#If I only request one object then it is the one that disappears
(Pdb) Entry.objects.all()[0]
[<Entry: Entry 1>]
#Here Entry 1 is missing
(Pdb) Entry.objects.all()
[<Entry: Entry 2>, <Entry: Entry 3>, <Entry: Entry 4]
#And now they're all gone.
(Pdb) Entry.objects.all()
[]
此行为仅适用于我的一个模型;其他模型似乎查询正确。我认为这与我的模型的定义没有任何关系,基本上是:
class Entry(models.Model):
user = models.ForeignKey(User, related_name='entries')
blog = models.ForeignKey(Blog, related_name='entries')
positive = models.BooleanField()
抱歉,我的描述有点含糊;我对这种行为是如何出现的感到困惑,不知道下一步该在哪里闲逛。
Manager 为 QuerySet 生成的 SQL 每次都是相同的(并且显然是正确的):
(Pdb) p Entry.objects.all().query.as_sql()
('SELECT "myapp_entry"."id", "myapp_entry"."user_id", "myapp_entry"."blog_id", "myapp_entry"."positive" FROM "myapp_entry"', ())
(Pdb) p Entry.objects.all()
[<Entry: Entry 1>, <Entry: Entry 2>, <Entry: Entry 3>, <Entry: Entry 4]
(Pdb) p Entry.objects.all().query.as_sql()
('SELECT "myapp_entry"."id", "myapp_entry"."user_id", "myapp_entry"."blog_id", "myapp_entry"."positive" FROM "myapp_entry"', ())
(Pdb) Entry.objects.all()
[]
我在 Mac OS 10.5 机器上使用 Django 1.0.2、Python 2.6.1 和与 Python 2.6.1 一起打包的 SQLite。
为了回应其中一条评论,我尝试将related_name
参数重命名为entries1
并entries2
避免可能的冲突,但这并没有改变行为。
已解决(我认为)
对不起,这个问题实际上与我提出的问题无关。我在 Entry 的一个信号中有一个粗心的错误:
在myapp.__init__
:
post_init.connect(entry_initialized, sender=Entry)
在myapp.signals
:
def entry_initialized(sender, instance, *args, **kwargs):
try:
#Disconnect signal to avoid infinite recursion
post_init.disconnect(entry_initialized, sender=Entry)
#Intializing a new Entry here would cause the recursion
#Check to see if there is a previous entry by this user in this blog
#In this app entries are unique by (User, Blog)
#And what we want to do is remove the old Entry if the positive fields don't match
prev_instance = Entry.objects.get(user=instance.user, blog=instance.blog)
#This is an error: it is not appropriate to delete without some checking
prev_instance.delete()
post_init.connect(verification_initialized, sender=Verification)
except:
post_init.connect(verification_initialized, sender=Verification)
我的代码的正确版本是:
#Only delete if this is a different Entry with same user/blog and the positive field is different.
if not instance.id == prev_instance and not instance.positive == prev_instance.positive:
prev_instance.delete()