管理器每次请求返回模型对象(管理器在返回一次后丢弃对象)

时间:2009-03-05 05:50:05

标签: django django-models

该行为与下面立即提出的问题无关。有关说明,请参阅帖子底部。感谢。


您好,

我目前遇到的行为是,特定模型的默认管理器仅为每个请求或每个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参数重命名为entries1entries2以避免可能的冲突,但这并未改变行为。


已解决(我认为)

对不起,问题实际上与我提出的问题无关。我在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()

1 个答案:

答案 0 :(得分:0)

对不起,问题实际上与我提出的问题无关。我在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()