0

すぐ下に示すように、動作は問題とは無関係でした。説明については、投稿の下部を参照してください。ありがとう。


こんにちは、

現在、特定のモデルのデフォルトのマネージャーがこのモデルのオブジェクトをリクエストごとまたはシェルセッションごとに1回だけ返すという動作を経験しています。以下は、ビューで停止しない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()
[]

この動作は、私のモデルの1つのみを対象としています。他のモデルは正しくクエリを実行しているようです。基本的には、モデルの定義とは何の関係もないと思います。

class Entry(models.Model):
    user = models.ForeignKey(User, related_name='entries')
    blog = models.ForeignKey(Blog, related_name='entries')
    positive = models.BooleanField()

私の説明が少し曖昧であることをお詫びします。私はこの振る舞いがどのように発生するかについて混乱していて、次にどこを突くべきかわからない。

クエリセット用にマネージャによって生成される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 OS10.5マシンでPython2.6.1にパッケージ化されているDjango1.0.2、Python 2.6.1、およびSQLiteを使用しています。

コメントの1つに応じて、競合の可能性を回避するためにrelated_nameパラメーターの名前を変更しようentries1entries2しましたが、動作は変わりませんでした。


解決済み(私は思う)

申し訳ありませんが、私が提示した問題は、実際には問題とは無関係でした。エントリーのシグナルの1つに不注意なバグがありました:

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()
4

1 に答える 1

0

申し訳ありませんが、問題は実際には私が提示した問題とは無関係でした。Entry の信号の 1 つに不注意なバグがありました。

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()
于 2013-02-14T20:55:22.890 に答える