Можно ли ссылаться на свойство, используя Django QuerySet.values_list?

У меня есть пользовательское свойство в моей модели Django, которое возвращает полное имя человека:

class Person(models.Model):
  first_name = models.CharField(max_length=30)
  last_name = models.CharField(max_length=30)

def _get_full_name(self):
  return "%s %s" % (self.first_name, self.last_name)
full_name = property(_get_full_name)

Когда я создаю запрос, я хотел бы сослаться на это свойство. Например:

people = Person.objects.all().values_list('full_name')

К сожалению, Django выдает следующую ошибку FieldError:

FieldError: невозможно преобразовать ключевое слово "full_name" в поле

Короче говоря, можно ли получить доступ к пользовательскому свойству через метод values_list()? Если нет, есть ли у кого-нибудь какие-либо предложения о том, как лучше всего решить эту проблему?


person Huuuze    schedule 26.01.2010    source источник


Ответы (3)


полное имя не является полем в модели django, это невозможно. вы можете использовать понимание списка

[person.fullname for person in Person.objects.all() ] 
person zaca    schedule 26.01.2010
comment
Я использовал это решение для фильтрации вариантов для поля формы в stackoverflow.com/questions/11417673/. - person Furbeenator; 10.07.2012

values_list может работать только с полями, полученными непосредственно из базы данных. Как отмечает Зака, вам понадобится понимание списка в фактическом наборе запросов:

[person.fullname for person in Person.objects.all()]

Не злоупотребляйте values_list. Это просто средство ограничения запросов к базе данных, поскольку, когда вы знаете, вам понадобятся только эти конкретные поля. Почти во всех случаях получение стандартного набора запросов достаточно эффективно.

person Daniel Roseman    schedule 27.01.2010
comment
Отлично. Я использую is_reporting @property, и да, я понял, что не могу использовать поле в наборе запросов. очень жаль, что ему приходится перебирать все объекты, а не те, у которых установлено значение True или False. Даже если вы добавите его в используемый диспетчер наборов запросов, ему все равно придется перебирать каждый из них, чтобы вычислить значение. Иногда я думаю, что стоит сохранить конечный результат, чтобы вы могли запросить его. - person radtek; 02.05.2014

Полное имя не является полем в модели Django, поэтому вы можете использовать аннотацию, например:

people = Person.objects.annotate(
    full_name=Concat(
        'first_name', 
        Value(' '), 
        'last_name'
    ).values_list(
        'full_name'
    )
)
person Sergey Pugach    schedule 28.11.2019