O gerente retorna objetos de modelo uma vez por solicitação (o gerente solta objetos depois de devolvê -los uma vez)

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

  •  03-07-2019
  •  | 
  •  

Pergunta

O comportamento não estava relacionado ao problema, conforme apresentado imediatamente abaixo. Veja o fundo do post para uma explicação. obrigado.


Olá,

Atualmente, estou experimentando o comportamento de que o gerenciador padrão de um modelo específico retorna os objetos para este modelo apenas uma vez por solicitação ou por sessão de shell. Abaixo está uma transcrição do PDB de parar em uma visão (mas o comportamento também ocorre sem 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()
[]

Sempre que recuperar um objeto, esse objeto não aparece mais em consultas posteriores.

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

Esse comportamento é apenas para um dos meus modelos; Os outros modelos parecem consultar corretamente. Eu não acho que isso tenha nada a ver com a definição do meu modelo, o que é basicamente:

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

Peço desculpas que minha descrição seja um pouco vaga; Estou confuso sobre como esse comportamento poderia surgir e não tenho certeza de onde cutucar a próxima.

O SQL gerado pelo gerente para o Queryset é o mesmo (e aparentemente correto) a cada vez:

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

Estou usando o Django 1.0.2, Python 2.6.1 e o SQLite que veio embalado com o Python 2.6.1 em uma máquina Mac OS 10.5.

Em resposta a um dos comentários, tentei renomear o related_name parâmetros para entries1 e entries2 Para evitar um possível conflito, mas isso não mudou o comportamento.


Resolvido (eu acho)

Desculpe tudo, o problema não estava relacionado ao problema como eu o apresentei. Eu tive um bug descuidado em um dos meus sinais na entrada:

Dentro myapp.__init__:

post_init.connect(entry_initialized, sender=Entry)

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

A versão correta do meu código seria:

        #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()
Foi útil?

Solução

Desculpe tudo, o problema não estava relacionado ao problema como eu o apresentei. Eu tive um bug descuidado em um dos meus sinais na entrada:

Dentro myapp.__init__:

post_init.connect(entry_initialized, sender=Entry)

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

A versão correta do meu código seria:

        #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()
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top