Менеджер возвращает объекты модели один раз за запрос (менеджер удаляет объекты после их однократного возврата)

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

  •  03-07-2019
  •  | 
  •  

Вопрос

Поведение не было связано с проблемой, представленной ниже.Объяснение смотрите в нижней части поста.Спасибо.


Привет,

В настоящее время я сталкиваюсь с тем, что менеджер по умолчанию для конкретной модели возвращает объекты для этой модели только один раз за запрос или за сеанс оболочки.Ниже приведена расшифровка 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()
[]

Каждый раз, когда я извлекаю объект, этот объект больше не появляется в последующих наборах запросов.

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

Прошу прощения, что мое описание немного расплывчато;Я не понимаю, как могло возникнуть такое поведение, и не знаю, куда копаться дальше.

SQL-код, сгенерированный диспетчером для QuerySet, каждый раз один и тот же (и, очевидно, правильный):

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

Я использую Django 1.0.2, Python 2.6.1 и SQLite, поставляемый в комплекте с Python 2.6.1 на компьютере Mac OS 10.5.

В ответ на один из комментариев я попытался переименовать related_name параметры для entries1 и entries2 чтобы избежать возможного конфликта, но это не изменило поведения.


РЕШЕНО (думаю)

Извините всех, проблема на самом деле не имела отношения к проблеме, которую я представил.У меня была небрежная ошибка в одном из моих сигналов на вход:

В 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()
Это было полезно?

Решение

Извините всех, проблема на самом деле не имела отношения к проблеме, которую я представил.У меня была небрежная ошибка в одном из моих сигналов на вход:

В 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()
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top