Джанго найти элемент в наборе запросов и получить следующий - PullRequest
1 голос
/ 28 сентября 2019

Я пытаюсь взять объект, найти набор запросов, найти элемент в этом наборе запросов и найти следующий.

@property
def next_object_url(self):
    contacts = Model.objects.filter(owner=self.owner).order_by('-date')
    place_in_query = list(contacts.values_list('id', flat=True)).index(self.id)
    next_contact = contacts[place_in_query + 1]

Когда я добавляю это в модель и запускаю его,вот что я получаю для каждой переменной для одного экземпляра.

CURRENT = Current Object
NEXT = Next Object

contacts.count = 1114
self.id = 3533 #This is CURRENT.id
place_in_query = 36
contacts[place_in_query] = NEXT
next_contact = CURRENT

Что я пропускаю / какую глупую ошибку я совершаю?

Ответы [ 2 ]

0 голосов
/ 28 сентября 2019

Я не уверен, почему ваш код не работает, но я думаю, что есть лучший подход, используйте необработанный запрос:

@property
def next_object_url(self):
    contacts = Model.objects.raw(f'''
      SELECT 
      t1.id, 
      DATEDIFF((SELECT t2.date FROM table t2 WHERE t2.id = {self.id}), t1.date) as d
      from table t1
      ORDER BY d asc
      LIMIT 2
    ''')

Это полностью не проверено, и, возможно, придется адаптироватьдля вашей конкретной базы данных.Надеюсь, ваша база данных поддерживает DATEDIFF!

0 голосов
/ 28 сентября 2019

В вашей функции контакты - это QuerySet .Фактические объекты не извлекаются в строке:

contacts = Model.objects.filter(owner=self.owner).order_by('-date')

, потому что вы не используете функцию, подобную list(), вы еще не выполняете итерацию QuerySet ... Она оценивается позже.Вероятно, это является причиной вашей проблемы.

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

@property
def next_object_url(self):
    contacts = list(Model.objects.filter(owner=self.owner).order_by('-date').all())
    for curr_contact, next_contact in zip(contacts[:-1], contacts[1:]):
        if curr_contact.id == self.id:
            return next_contact
    else:
        # not found
        raise ContactNotFoundError(self.id)

Другое решение - изменить модель базы данных, чтобы добавить понятие предыдущего / следующего контакта на уровне базы данных ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...