модели django выбирают одно поле

102

У меня есть таблица / модели, Employeesи я хотел бы получить все строки одного поля в качестве набора запросов.

Я знаю, что могу сделать это вот так (надеюсь, я даже делаю это правильно):

emp_list = Employees.objects.get(all)
emp_names = emp_list.eng_name

Будет ли запрашивать базу данных для всех полей и использовать только одно? Есть ли лучший (более быстрый) способ сделать это?

зентенк
источник
Что вы имеете в виду под «и используя только один»? А SELECT colвместо SELECT *?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Ответы:

184
Employees.objects.values_list('eng_name', flat=True)

Это создает плоский список всех eng_names. Если вам нужно более одного поля в строке, вы не можете создать плоский список: это создаст список кортежей:

Employees.objects.values_list('eng_name', 'rank')
Дэниел Розман
источник
спасибо за ответ, а если я хочу выбрать только одно или несколько полей (не все)?
zentenk
Извините, я не понимаю вопроса.
Дэниел Роузман
3
пожалуйста, поделитесь документом. это поможет другим
Боб
25

В дополнение к тому, values_listчто упоминает Даниэль, вы также можете использовать (или для противоположного эффекта), чтобы получить набор запросов объектов, имеющих только их идентификатор и указанные поля:onlydefer

Employees.objects.only('eng_name')

Это запустит один запрос:

SELECT id, eng_name FROM employees
Оскар Перссон
источник
3
Эта команда возвращает мне все поля для моих Django версии 2.1.3 и python версии 3.6.2.
Ananthi
Он получит только это поле, но если вы попытаетесь получить доступ к другим полям, будет выполнен отдельный запрос к базе данных. Так что это хороший метод оптимизации, но убедитесь, что вы не создаете лишних запросов. В противном случае вы потеряете производительность, а не получите ее.
Eerik Sven Puudist
6

Мы можем выделить обязательные поля над значениями.

Employee.objects.all().values('eng_name','rank')
Алок Чоудхари
источник
После успешного выполнения запроса, как сохранить значение поля в переменной, например. var_name = <query_name>. <field_name> ?
user12379095
@ user12379095 просто так:var_name = Employee.objects.all().values('eng_name','rank')
theQuestionMan
@ user12379095, а затем использовать это имя_переменной - например: распечатать имена и звания всех сотрудников, вы можете сделать это:for person in var_name: print(person['eng_name'] + " " + person['rank'])
theQuestionMan
3

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

После этого вы можете легко получить желаемый реквизит:

for employee in employees:
    print(employee.eng_name)

Или в шаблоне:

{% for employee in employees %}

    <p>{{ employee.eng_name }}</p>

{% endfor %}
ПитМайкель
источник
1

Вы можете использовать values_list вместе с фильтром, например:

active_emps_first_name = Employees.objects.filter(active=True).values_list('first_name',flat=True)

Подробнее здесь

7guyo
источник