Найти самый последний рейтинг для пользователя в наборе запросов Django - PullRequest
1 голос
/ 18 июня 2011

Я ищу способ получить самый последний рейтинг для конкретного человека для всех ресурсов.В настоящее время я использую запрос типа Rating.objects.filter(Person = person).order_by('-timestamp'), затем пропускаю его через unique_everseen с ключом ресурса и пользовательских атрибутов, а затем перехожу на Rating.objects.filter(id__in = uniquelist).Есть ли более элегантный способ сделать это с помощью функций набора запросов django?Это соответствующие модели.

class Person(models.Model):
    pass

class Resource(models.Model):
    pass

class Rating(models.Model):
    rating = models.IntegerField()
    timestamp = models.DateField()
    resource = models.ForeignKey('Resource')
    user = models.ForeignKey('Person')

Мне нужно сохранить все старые рейтинги, так как другие функции должны иметь возможность вести историю того, как все «меняется».

1 Ответ

1 голос
/ 18 июня 2011

Я не на 100% уверен в том, что вы ищете здесь, хотите ли вы найти самый последний рейтинг пользователя для всех ресурсов, которые он оценил? Если вы сможете подробно рассказать о том, что на самом деле делает unique_everseen, это поможет уточнить, что вы ищете.

Вы могли бы скорее взглянуть с точки зрения ресурсов:

resources = Resource.objects.filter(rating__user=person).order_by('-rating__timestamp')
resource_rating = [(resource, resource.rating_set.filter(person=person).get_latest('timestamp')) for resource in resources]

Возможно, вы сможете использовать Агрегатные функции , чтобы получить самую последнюю запись на ресурс, или использовать умный объект Q для ограничения запросов SQL (мой пример может сэкономить некоторые запросы, и быть более элегантным, но это не так просто, как то, что вы могли бы сделать с необработанным запросом SQL). В сыром SQL вы должны использовать внутренний SELECT или хорошо выполненный GROUP BY, чтобы получить самый последний рейтинг, так что имитировать это было бы идеально.

Вы также можете создать в вашей модели рейтинга post_save сигнальный хук и «активное» или «текущее» логическое поле, которое будет перебирать другие рейтинги, соответствующие пользователю / ресурсу, и устанавливать их «активное» поле равным Ложь. то есть ловушка post_save пометит все другие оценки как неактивные для пользователя / ресурса, используя что-то вроде:

if instance.active:
    for rating in Rating.objects.filter(user=instance.user,resource=instance.resource).exclude(id=instance.id):
        rating.active=False
        rating.save()

Вы можете сделать простой запрос для:

Rating.objects.filter(user=person,active=True).order_by('-timestamp')

Это был бы самый экономичный из запросов (даже если вы делаете сложную группу с помощью / inner выбора в сыром SQL, вы делаете более сложный запрос, чем необходимо). Использование логического поля также означает, что вы можете обеспечить поведение «шаг вперед / шаг назад» / «отменить / повторить» для оценок пользователя, если это уместно.

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