Il gestore restituisce gli oggetti modello una volta per richiesta (il gestore rilascia gli oggetti dopo averli restituiti una volta)

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

  •  03-07-2019
  •  | 
  •  

Domanda

Il comportamento non era correlato al problema, come illustrato immediatamente di seguito. Vedi in fondo al post per una spiegazione. grazie.


Ciao,

Attualmente sto riscontrando il comportamento che il Manager predefinito per un particolare Modello restituisce gli oggetti per questo Modello solo una volta per richiesta o per sessione di shell. Di seguito una trascrizione di PDB che si interrompe in una vista (ma il comportamento si verifica anche senza 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()
[]

Ogni volta che recupero un oggetto, quell'oggetto non appare più nei QuerySet successivi.

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

Questo comportamento è solo per uno dei miei modelli; gli altri modelli sembrano interrogare correttamente. Non penso che abbia nulla a che fare con la definizione del mio Modello, che è fondamentalmente:

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

Mi scuso che la mia descrizione sia un po 'vaga; Sono confuso su come questo comportamento possa insorgere e non sono sicuro di dove curiosare in futuro.

L'SQL generato dal Manager per il QuerySet è lo stesso (e apparentemente corretto) ogni volta:

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

Sto usando Django 1.0.2, Python 2.6.1 e SQLite fornito con Python 2.6.1 su un computer Mac OS 10.5.

In risposta a uno dei commenti ho provato a rinominare i parametri related_name in entry1 e entry2 per evitare un possibile conflitto, ma ciò non ha funzionato cambiare il comportamento.


RISOLTO (credo)

Scusatemi tutto, il problema in realtà non era correlato al problema quando l'ho presentato. Ho avuto un bug disattento in uno dei miei segnali su Entry:

In myapp .__ init__ :

post_init.connect(entry_initialized, sender=Entry)

In 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 versione corretta del mio codice sarebbe:

        #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()
È stato utile?

Soluzione

Scusatemi tutto, il problema in realtà non era correlato al problema quando l'ho presentato. Ho avuto un bug disattento in uno dei miei segnali su Entry:

In myapp .__ init__ :

post_init.connect(entry_initialized, sender=Entry)

In 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 versione corretta del mio codice sarebbe:

        #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()
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top