Manager renvoie les objets du modèle une fois par demande (le gestionnaire supprime les objets après les avoir renvoyés une fois).

StackOverflow https://stackoverflow.com/questions/613706

  •  03-07-2019
  •  | 
  •  

Question

Le comportement n’était pas lié au problème présenté immédiatement ci-dessous. Voir le bas de l'article pour une explication. merci.

Bonjour,

Je rencontre actuellement le problème suivant: le gestionnaire par défaut d'un modèle particulier ne renvoie les objets de ce modèle qu'une seule fois par demande ou par session shell. Ci-dessous, une transcription de PDB à partir d'un arrêt dans une vue (mais le problème se produit également sans 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()
[]

Chaque fois que je récupère un objet, cet objet n'apparaît plus dans les QuerySets ultérieurs.

#(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()
[]

Ce comportement n’est valable que pour l’un de mes modèles; les autres modèles semblent interroger correctement. Je ne pense pas que cela ait à voir avec la définition de mon modèle, qui est fondamentalement:

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

Je suis désolé, ma description est un peu vague; Je ne comprends pas comment ce comportement pourrait survenir et je ne sais pas où chercher.

Le code SQL généré par le gestionnaire pour le QuerySet est identique (et apparemment correct) à chaque fois:

(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()
[]

J'utilise Django 1.0.2, Python 2.6.1 et SQLite fourni avec Python 2.6.1 sur un ordinateur Mac OS 10.5.

En réponse à l'un des commentaires, j'ai essayé de renommer les paramètres related_name en entrées1 et entrées2 pour éviter un conflit éventuel, ce qui n'a pas été le cas. changer le comportement.

RESOLU (je pense)

Désolé, le problème n’était en réalité pas lié au problème tel que je l’ai présenté. J'ai eu un bogue d'inattention dans l'un de mes signaux sur Entry:

Dans monapplication .__ init __ :

post_init.connect(entry_initialized, sender=Entry)

Dans 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)

La version correcte de mon code serait:

        #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()
Était-ce utile?

La solution

Désolé, le problème n’était en réalité pas lié au problème tel que je l’ai présenté. J'ai eu un bogue d'inattention dans l'un de mes signaux sur Entry:

Dans monapplication .__ init __ :

post_init.connect(entry_initialized, sender=Entry)

Dans 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)

La version correcte de mon code serait:

        #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()
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top